With the recent changes on color management and soon lighting, I strongly recommend to inject your GLSL code into native three shaders using onBeforeCompile instead.
Because shaders chunks have become so convoluted (r151-154 is borderline pure madness), it’s not worth it to use shaderMaterial anymore if you seek shadows an lights. There is litterally hundreds of lines spread in 10+ chunks, to get it working.
For the defense of three maintainers, it’s an unavoidable situation as they try to transition to webGPU and nodes while avoiding potential technical debts from the decade old webGL
You need to use a native shader, you still use ShaderMaterial.
Something like this:
//our new material will use the Phong shader as base
const material = new THREE.MeshPhongMaterial( {
map: texture,
color: 0xffffff
} );
//shader injection
material.onBeforeCompile = function ( shader ) {
//exemple of uniforms definition for fragment
shader.uniforms.myUniform = { value: myValue };
shader.fragmentShader = 'uniform float myUniform;\n' + shader.fragmentShader;
//exemple of replacing phong map_fragment chunk with custom code
shader.fragmentShader = shader.fragmentShader.replace(
'#include <map_fragment>',
[
//write custom code here
].join( '\n' )
);
};
To understand exactly which chunks you need to change. Look at the native shaders code here:
in my exemple I would open meshphong.glsl.js
Next look at the detailed code used by chunks here
In my exemple I need to open map_fragment.glsl.js to either edit this code, or replace it.
Since native shaders are very fragmented right now, it’s not a simple task either.
But your shader will work with every features available.
I made a plugin to make it much easier and cleaner to extend native shader. Also those with custom vertex transformations (see templates). If you only do minor changes you can also use ’ onBeforeCompile’ the patchShader of this lib however will also give you the cleaner patching functionality.
If you want to properly access uniforms you might want your materials to be based on ShaderMaterial then.
You need to replace a proper line, you only replaced gl_FragColor, since you don’t use a built-in map you also need to define USE_UV in defines, not declaring vUv yourself as it would conflict.