Drawing order for objects with transparent shader materials #3291
Unanswered
lordcraymen
asked this question in
Q&A
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Hi everyone,
I'm new to r3f, so please be patient with me!
I'm working on a viewer to display multiple 3D models (GLTF) and want to add a fade-in and fade-out effect for presentation purposes.
To keep things flexible and achieve a 2.5D compositing experience, I decided to render the objects I want to animate the transparency on as a separate pass. Then, I apply the render target's texture in a shader material with screen space coordinates to control the alpha value for each fragment. I also implemented custom depth checking to reduce transparency artifacts, especially for concave objects.
After some effort, I got it working (normalizing the screen coordinates was tricky on my Mac with Retina display; I had to adjust the render target resolution using gl.getPixelRatio). However, I'm facing an issue with multiple instances of the RenderGroup component: only the object in the last instance shows the transparency effect.
Any advice or suggestions would be greatly appreciated!
This is my code so far:
`
import { useEffect, useRef, useMemo } from 'react';
import { useFrame } from '@react-three/fiber';
import { Vector2, WebGLRenderTarget, ShaderMaterial, DepthTexture } from 'three';
//SkipRenderMaterial is a material that will cause the renderbufferDirect function to return early
//I use this material to skip rendering the objects that are not in the current render group
import { SkipRenderMaterial } from '../../shaders/SkipRenderMaterial';
const RenderGroup = ({children, opacity=1}) => {
const groupRef = useRef();
};
export {
RenderGroup
}
`
and this is how i use it
`<Canvas onCreated={({ gl }) => {
const originalRenderBufferDirect = gl.renderBufferDirect
gl.renderBufferDirect = function (camera, fog, geometry, material, object, group) {
const currentMaterial = object.overrideMaterial || material
if( currentMaterial === SkipRenderMaterial) return;
originalRenderBufferDirect.call(this, camera, fog, geometry, currentMaterial, object, group);
};
What are your thoughts? only the model in the last renderGroup instance shows the expected 50% opacity, the other two show completely opaque. What am I missing misunaderstanding here?
Thank you for your help!
Beta Was this translation helpful? Give feedback.
All reactions