-
Problem description:I have three different environment maps which a toggled using a button. When choosing a map for the first time, the screen flashes white. After picking a map once, switching works as expected. The envMaps are Relevant code:I import the maps import day from '../../webgl/envMaps/day.hdr'
import dawn from '../../webgl/envMaps/dawn.hdr'
import night from '../../webgl/envMaps/night.hdr' choose the selected environment const envMap = useMemo(() => {
switch (activeEnvMap) {
case 'NIGHT':
return night
case 'DAWN':
return dawn
default:
return day
}
}, [activeEnvMap]) and then use in the <RenderCanvas
shadows
frameloop="demand"
camera={{ position: [-1.2, 1.2, 2], fov: 50 }}
style={{ zIndex: 0 }}
>
<group>
[..]
<spotLight position={[-1, 0.5, 1]} intensity={0.1} penumbra={0.4} />
<spotLight position={[-1, 2, -1.5]} intensity={0.6} penumbra={0.2} />
<spotLight position={[-2, 0, -2]} intensity={0.2} penumbra={0} />
<spotLight
position={[1, 2, 0]}
intensity={0.8}
penumbra={0.4}
angle={Math.PI / 2.5}
/>
<directionalLight position={[1, 0.2, 1]} intensity={0.2} />
</group>
<Effects />
<Environment files={envMap} />
<fog attach="fog" args={['#28282B', 1, 8]} />
</RenderCanvas> Suggested solution:I tried to provide all the environments and only render the currently active one {activeEnv === 'DAY' && <Environment files={day} />} also I tried to wrap it inside a group and toggle the visibility <group visible={activeEnv === 'DAY'}>
<Environment files={day} />
</group> Both approaches did not work. Since this is my first project using drei it might very well be a mistake on my end. Thank you in advance |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
every async component is based on suspense. when a component inside a suspense bound suspends then everything in that bound will be unmounted and remounted once the async thing has completed. in other words, it's up to you to wrap stuff in additional suspense bounds to prevent things from getting affected. <Canvas>
<Something />
<SomethingElse />
<Suspense fallback={null}>
<Environment files={envMap}>
</Suspense> now the env won't affect the rest of the scene. you can hang on to the current thing without going into a fallback with the useTransition hook. https://beta.reactjs.org/reference/react/useTransition you can also preload stuff in the background so that it becomes immediately available: import { RGBELoader } from 'three-stdlib'
useLoader.preload(RGBELoader, day)
useLoader.preload(RGBELoader, dawn)
... |
Beta Was this translation helpful? Give feedback.
every async component is based on suspense. when a component inside a suspense bound suspends then everything in that bound will be unmounted and remounted once the async thing has completed.
in other words, it's up to you to wrap stuff in additional suspense bounds to prevent things from getting affected.
now the env won't affect the rest of the scene.
you can hang on to the current thing without going into a fallback with the useTransition hook. https://beta.reactjs.org/reference/react/useTransition
you can also preload stuff in the background so that it becomes immed…