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
-
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