ShaderMaterial created from MeshStandardMaterial's shader has mirrored reflection?


jsfiddle here:

I’m trying to create a ShaderMaterial based on MeshStandardMaterial (without any tweaks for now, will replace standard.fragmentShader in the future):

    let standard = THREE.ShaderLib['standard'];
    let customMaterial = new THREE.ShaderMaterial({
      lights: true,
      fragmentShader: standard.fragmentShader,
      vertexShader: standard.vertexShader,
      uniforms: THREE.UniformsUtils.clone(standard.uniforms),
    customMaterial.uniforms.diffuse.value = new THREE.Color(0x00ffff);
    customMaterial.uniforms.roughness.value = 0;
    customMaterial.uniforms.metalness.value = 1;
    // ...

It seems working except that the reflections are mirrored.


How can I fix this?
Also, am I on the right track to customize MeshStandardMaterial?

Thank you very much!

When using ShaderMaterial, common and material specific uniforms are not updated automatically. You have missed to update the uniform flipEnvMap. I’ve added the fix to your code.

1 Like

Thank you!

I have another question about :
Why both the following lines are necessry to display the env map?

customMaterial.envMap = hdrCubeRenderTarget.texture;
customMaterial.uniforms.envMap.value = hdrCubeRenderTarget.texture;


customMaterial.uniforms.envMap.value = hdrCubeRenderTarget.texture;

alone is not enough?
Thank you!

No. The renderer does perform tests on .envMap so it’s important to set customMaterial.envMap.

What about the why?

@pailhead the question is:

Why is customMaterial.uniforms.envMap.value = hdrCubeRenderTarget.texture alone not enough?

Yes, I’m curious about the why part :slight_smile: The “why” was truncated from mugens reply.

I read this and found it confusing since assigning value to a uniform works on custom shaders.

Maybe this overview can be of some assistance:

My guess is that there is a naming conflict as well as reserved words that perhaps should not be used with ShaderMaterial.