I tried LightProbe but the faces of the cube are still with flat color:
In real world, there should be some subtle brightness / hue changing in each face. What are the cheap approaches to make it more realistic?
I tried LightProbe but the faces of the cube are still with flat color:
In real world, there should be some subtle brightness / hue changing in each face. What are the cheap approaches to make it more realistic?
Do you have an environment map here? (scene.environment
or material.envMap
) That’s going to be the highest-quality lighting you can get, generally.
A “light probe” in three.js does not automatically capture its surroundings; you have to initialize it with some light information. So knowing you have a light probe in the scene doesn’t tell us much – with a solid color a light probe is the same as an ambient light.
Hey I basically implemented threejs’ lightProbe example with r3f.
export function LightProbTest() {
const { gl, scene } = useThree();
const cubeRT = new WebGLCubeRenderTarget(256, {
encoding: sRGBEncoding, // since gamma is applied during rendering, the cubeCamera renderTarget texture encoding must be sRGBEncoding
format: RGBAFormat,
});
const cubeTexture = useCubeTexture(
["px.png", "nx.png", "py.png", "ny.png", "pz.png", "nz.png"],
{ path: "/textures/cube/" }
);
cubeTexture.encoding = sRGBEncoding;
scene.background = cubeTexture;
const cubeCameraRef = useRef<CubeCamera>();
const lightProbeRef = useRef<LightProbe>();
useLayoutEffect(() => {
cubeCameraRef.current?.update(gl, scene);
lightProbeRef.current?.copy(
LightProbeGenerator.fromCubeRenderTarget(gl, cubeRT)
);
}, []);
return (
<>
<cubeCamera args={[1, 1000, cubeRT]} ref={cubeCameraRef} />
<lightProbe ref={lightProbeRef} />
</>
);
}
And in the original example the envMap is created via:
const genCubeUrls = function ( prefix, postfix ) {
return [
prefix + 'px' + postfix, prefix + 'nx' + postfix,
prefix + 'py' + postfix, prefix + 'ny' + postfix,
prefix + 'pz' + postfix, prefix + 'nz' + postfix
];
};
const urls = genCubeUrls( 'textures/cube/pisa/', '.png' );
new THREE.CubeTextureLoader().load( urls, function ( cubeTexture ) {
cubeTexture.encoding = THREE.sRGBEncoding;
scene.background = cubeTexture;
cubeCamera.update( renderer, scene );
lightProbe.copy( LightProbeGenerator.fromCubeRenderTarget( renderer, cubeRenderTarget ) );
scene.add( new LightProbeHelper( lightProbe, 5 ) );
render();
} );
There seems to be no updates on scene.environment
or material.envMap
…?
Not sure what you mean here – the code above does not set scene.environment
or material.envMap
anywhere that I can see. I’d suggest setting scene.environment
in addition to scene.background
.
A light probe collapses all lighting information from a cubemap into directional coefficients (“spherical harmonics”) at the probe’s location. Since the faces of a cube are flat, and all parts of a face have the same normal vector, you aren’t going to see subtle changes across the surface of the cube with a single light probe.