英文:
Three.js React Fiber - Transparent background
问题
我使用React Fiber,但无法弄清楚如何使子场景的背景透明。
这是我的根组件,带有主要的Canvas:
export const Splash = () => {
const { intensity, distance, color, ambientIntensity } = useControls('Main lights', {
intensity: { value: 9, min: 0, max: 200, step: 0.5 },
distance: { value: 100, min: -100, max: 100, step: 0.5 },
color: "#7c0505",
ambientIntensity: { value: 0.5, min: -3, max: 3, step: 0.1 },
});
return (
<>
<Canvas
dpr={window.devicePixelRatio}
onCreated={({ gl }) => {
gl.setClearColor(0xFF0000, 0);
gl.autoClear = false;
gl.clearDepth()
}}
gl={{ antialias: true, alpha: true }}
camera={{ fov: 65, position: [0, 0, 30] }}>
<Main>
<ambientLight intensity={ambientIntensity} color={color} />
<RadialGradientPlane />
</Main>
<ApplyEffects>
<RadialGradientPlane />
</ApplyEffects>
</Canvas>
</>
)
}
Main
组件只是简单地渲染一个子场景:
function Main({ children }) {
const scene = useRef()
const { gl, camera } = useThree()
useFrame(() => {
gl.autoClear = false
gl.clearDepth()
gl.render(scene.current, camera)
}, 1)
return <scene ref={scene}>{children}</scene>
}
这是透明的,如果我删除ApplyEffects
组件,我会看到RadialGradientPlane
和我的普通文档背景颜色。
问题似乎与ApplyEffects
组件有关,如下所示:
import { Effects } from '@react-three/drei';
import { UnrealBloomPass, RenderPass, WaterPass } from 'three-stdlib';
export default function ApplyEffects({ children }: { children: React.ReactNode }}) {
const waterPass = useRef<WaterPass>(null!);
const composer = useRef<EffectComposerGeneric<WebGLRenderTarget>>(null!)
const { size, camera } = useThree();
const aspect = useMemo(() => new Vector2(2046, 2046), [])
const [scene, setScene] = useState<Scene>();
const {strength, threshold, radius} = useControls('Bloom', {
threshold: { value: 0.1, min: 0, max: 1, step: 0.01 },
strength: { value: 1.5, min: 0, max: 10, step: 0.01 },
radius: { value: 0.05, min: 0, max: 1, step: 0.01 },
})
useEffect(() => {
if (composer.current) {
composer.current.setSize(size.width, size.height)
}
}, [size])
useFrame(() => {
composer.current?.render();
if (waterPass.current) {
waterPass.current.time += 0.05;
}
composer.current.renderer.autoClear = false
composer.current.renderer.clearDepth()
}, 2);
return <>
<scene ref={setScene}>{children}</scene>
<Effects ref={composer} disableGamma={true} disableRenderPass={true}>
<renderPass scene={scene} camera={camera} />
<waterPass ref={waterPass} attach="passes" factor={0.6} />
<unrealBloomPass
threshold={threshold}
strength={strength}
radius={radius}
resolution={aspect} />
</Effects>
</>;
}
我觉得我已经尝试了一切,但无法弄清楚!
非常感谢任何帮助!
这是相同问题的示例:小示例
如果删除“Effects”,背景将变为透明并显示白色背景颜色。
Shannon
英文:
I'm using react fiber, and cannot figure out how to get the background of my child scene to be transparent
This is my root component with the main Canvas
export const Splash = () => {
const { intensity, distance, color, ambientIntensity } = useControls('Main lights', {
intensity: { value: 9, min: 0, max: 200, step: 0.5 },
distance: { value: 100, min: -100, max: 100, step: 0.5 },
color: "#7c0505",
ambientIntensity: { value: 0.5, min: -3, max: 3, step: 0.1 },
});
return (<>
<Canvas
dpr={window.devicePixelRatio}
onCreated={({ gl }) => {
gl.setClearColor(0xFF0000, 0);
gl.autoClear = false;
gl.clearDepth()
}}
gl={{ antialias: true, alpha: true }}
camera={{ fov: 65, position: [0, 0, 30] }}>
<Main>
<ambientLight intensity={ambientIntensity} color={color} />
<RadialGradientPlane />
</Main>
<ApplyEffects>
<RadialGradientPlane />
</ApplyEffects>
</Canvas>
</>
)
}
The Main
Component simply just renders a child scene
function Main({ children }) {
const scene = useRef()
const { gl, camera } = useThree()
useFrame(() => {
gl.autoClear = false
gl.clearDepth()
gl.render(scene.current, camera)
}, 1)
return <scene ref={scene}>{children}</scene>
}
This IS transparent, if i remove the ApplyEffects component i see the RadialGradientPlane and my normal document background colour.
It's something to do with the ApplyEffects component, which is:
import { Effects } from '@react-three/drei';
import { UnrealBloomPass, RenderPass, WaterPass } from 'three-stdlib';
export default function ApplyEffects({ children }: { children: React.ReactNode }}) {
const waterPass = useRef<WaterPass>(null!);
const composer = useRef<EffectComposerGeneric<WebGLRenderTarget>>(null!)
const { size, camera } = useThree();
const aspect = useMemo(() => new Vector2(2046, 2046), [])
const [scene, setScene] = useState<Scene>();
const {strength, threshold, radius} = useControls('Bloom', {
threshold: { value: 0.1, min: 0, max: 1, step: 0.01 },
strength: { value: 1.5, min: 0, max: 10, step: 0.01 },
radius: { value: 0.05, min: 0, max: 1, step: 0.01 },
})
useEffect(() => {
if (composer.current) {
composer.current.setSize(size.width, size.height)
}
}, [size])
useFrame(() => {
composer.current?.render();
if (waterPass.current) {
waterPass.current.time += 0.05;
}
composer.current.renderer.autoClear = false
composer.current.renderer.clearDepth()
}, 2);
return <>
<scene ref={setScene}>{children}</scene>
<Effects ref={composer} disableGamma={true} disableRenderPass={true}>
<renderPass scene={scene} camera={camera} />
<waterPass ref={waterPass} attach="passes" factor={0.6} />
<unrealBloomPass
threshold={threshold}
strength={strength}
radius={radius}
resolution={aspect} />
</Effects>
</>;
}
I feel like I've tried everything here, i cannot figure it out!
Any help would be greatly appreciated!
Here's an example of the same issue: small example
If you remove the "Effects" the background is transparent and shows the white body colour.
Shannon
答案1
得分: 0
这是一个众所周知的问题,已在这里进行了广泛讨论。
其中一种解决方案在这里实现 ,并似乎根据这个演示解决了该问题。
请告诉我这是否有帮助。
英文:
This is a well-known issue reported and heavily discussed here.
One of the solutions is implemented here and seem to solve the problem based on this demo.
Please let me know if this helps.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论