ShaderMaterial rendering weird black streaks/artifacts when using MeshPhongMaterial fragment, vertex and uniforms

I noticed I get weird black artifacts from ShaderMaterial under this specific lighting condition. I initially used ShaderMaterial to extend MeshPhongMaterial and gamma correct the images according to custom gamma factor. I noticed that I was getting these weird black artifacts. I investigated and it’s apparently not caused by NAN and I was getting black streaks even before it reached my modifications.

This is the case even when using the built in fragment, vertex and uniforms for MeshPhongMaterial with ShaderMaterial. The first image is rendered using MeshPhongMaterial. The second is rendered using ShaderMaterial but built from MeshPhongMaterial’s fragment shader, vertex shader and uniforms. In the code below, it is the matteMaterial. I am using the same uniform values for both renderings.


function CustomShaderMaterial() {
  const matteMaterial = new THREE.ShaderMaterial({
    uniforms: THREE.ShaderLib.phong.uniforms,
    vertexShader: THREE.ShaderLib.phong.vertexShader,
    fragmentShader: THREE.ShaderLib.phong.fragmentShader,
    lights: true,
    name: 'matte-material',
  });
  matteMaterial.uniforms.side = { value: THREE.FrontSide };
  matteMaterial.uniforms.color = { value: WHITE };
  matteMaterial.uniforms.specular = { value: BLACK };
  matteMaterial.uniforms.shininess = { value: 0 };

  return matteMaterial;
}

Interestingly, this weird artifact does not happen when I remove the red light component coming from the (1,0,1) direction.

So my question is, does anyone know what mistake I could be making when using ShaderMaterial to extend MeshPhongMaterial? I wonder if there is some uniform I did not set or something I did not know about ShaderMaterial vs something built in like MeshPhongMaterial.

Cheers

The way you have created your shader material is not recommended. The code does not properly work since phong specific GLSL defines and uniforms are not properly set by the renderer.

I suggest you use Material.onBeforeCompile() if you want to enhance built-in materials with custom code.

1 Like