Hi! Is is possible to have a godray effect which works with transparent material, e.g. glass so the rays can go through the object?
I was playing around with the effect and it seems that the current implementation works in the same way for opaque and transparent materials.
Thanks for any info!
Hi,
the GodRaysEffect relies on the depth information of the rendered scene to mask the light source. You can remove objects from the mask by preventing them from writing depth:
const transparentCube = new THREE.Mesh(
new THREE.BoxGeometry(4, 4, 2),
new THREE.MeshStandardMaterial({
color: 0xdddddd,
metalness: 0.10000000149011612,
roughness: 0.7990000247955322,
opacity: 0.154313729,
transparent: true,
depthWrite: false // ←
})
);
However, disabling depthWrite may cause undesired results in some situations. Alternatively, you could try to render your transparent objects in another RenderPass after the god rays. It gets tricky when you have objects that are partly transparent, though.
Finding a good solution heavily depends on your actual scene.
Hi,
the
GodRaysEffectrelies on the depth information of the rendered scene to mask the light source. You can remove objects from the mask by preventing them from writing depth:const transparentCube = new THREE.Mesh( new THREE.BoxGeometry(4, 4, 2), new THREE.MeshStandardMaterial({ color: 0xdddddd, metalness: 0.10000000149011612, roughness: 0.7990000247955322, opacity: 0.154313729, transparent: true, depthWrite: false // ← }) );However, disabling
depthWritemay cause undesired results in some situations. Alternatively, you could try to render your transparent objects in anotherRenderPassafter the god rays. It gets tricky when you have objects that are partly transparent, though.Finding a good solution heavily depends on your actual scene.
Thank you very much, setting depthWrite to false did the trick!
I've also tried the solution with two RenderPass (2 scenes needed?) but I guess I am doing something wrong because I can't see the effect output:
const renderPass1 = new PP.RenderPass(scene1, camera)
renderPass1.renderToScreen = false
renderPass1.clear = true
const renderPass2 = new PP.RenderPass(scene2, camera)
renderPass2.renderToScreen = true
renderPass2.clear = false
const godrayPass = new PP.EffectPass(camera, godrayEffect)
composer.addPass(renderPass1)
composer.addPass(godrayEffect)
composer.addPass(renderPass2)
I left out a few details there, sorry. Yes, you'd use two scenes: one main scene and one scene that doesn't influence the god rays light source. It would look like this:
const godRaysEffect = new GodRaysEffect(camera, sun, {
blendFunction: BlendFunction.SKIP
});
const textureEffect = new TextureEffect({
blendFunction: BlendFunction.SCREEN,
texture: godRaysEffect.texture
});
const renderPass1 = new RenderPass(scene1, camera);
const renderPass2 = new RenderPass(scene2, camera);
const godRaysPass = new EffectPass(camera, godRaysEffect);
const texturePass = new EffectPass(camera, textureEffect);
renderPass2.clear = false;
texturePass.renderToScreen = true;
composer.addPass(renderPass1); // Render the main scene.
composer.addPass(godRaysPass); // Generate the god rays, but don't draw them yet.
composer.addPass(renderPass2); // Draw other objects.
composer.addPass(texturePass); // Draw the god rays and other effects.
This works because the EffectPass in between the two render passes doesn't render anything to the main frame buffers. As a result, the EffectComposer doesn't swap the internal buffers which allows the second RenderPass to draw its geometry into the same frame buffer that was used by the first RenderPass, making full use of the depth buffer.
Example: https://jsfiddle.net/7ujw56oe/
I actually encountered a bug while I was working on the example. The EffectPass incorrectly discarded the DEPTH attribute of the GodRaysEffect because its blendFunction was set to SKIP. I fixed that in [email protected] so make sure to update your dependencies!
I left out a few details there, sorry. Yes, you'd use two scenes: one main scene and one scene that doesn't influence the god rays light source. It would look like this:
const godRaysEffect = new GodRaysEffect(camera, sun, { blendFunction: BlendFunction.SKIP }); const textureEffect = new TextureEffect({ blendFunction: BlendFunction.SCREEN, texture: godRaysEffect.texture }); const renderPass1 = new RenderPass(scene1, camera); const renderPass2 = new RenderPass(scene2, camera); const godRaysPass = new EffectPass(camera, godRaysEffect); const texturePass = new EffectPass(camera, textureEffect); renderPass2.clear = false; texturePass.renderToScreen = true; composer.addPass(renderPass1); // Render the main scene. composer.addPass(godRaysPass); // Generate the god rays, but don't draw them yet. composer.addPass(renderPass2); // Draw other objects. composer.addPass(texturePass); // Draw the god rays and other effects.This works because the
EffectPassin between the two render passes doesn't render anything to the main frame buffers. As a result, theEffectComposerdoesn't swap the internal buffers which allows the secondRenderPassto draw its geometry into the same frame buffer that was used by the firstRenderPass, making full use of the depth buffer.Example: https://jsfiddle.net/7ujw56oe/
I actually encountered a bug while I was working on the example. The
EffectPassincorrectly discarded theDEPTHattribute of theGodRaysEffectbecause itsblendFunctionwas set toSKIP. I fixed that in[email protected]so make sure to update your dependencies!
Thank you very much, you rocks!
Most helpful comment
I left out a few details there, sorry. Yes, you'd use two scenes: one main scene and one scene that doesn't influence the god rays light source. It would look like this:
This works because the
EffectPassin between the two render passes doesn't render anything to the main frame buffers. As a result, theEffectComposerdoesn't swap the internal buffers which allows the secondRenderPassto draw its geometry into the same frame buffer that was used by the firstRenderPass, making full use of the depth buffer.Example: https://jsfiddle.net/7ujw56oe/
I actually encountered a bug while I was working on the example. The
EffectPassincorrectly discarded theDEPTHattribute of theGodRaysEffectbecause itsblendFunctionwas set toSKIP. I fixed that in[email protected]so make sure to update your dependencies!