I create my material by replace shader on MeshStandardMaterial.
The shader is modified from standard shader. The original uniforms and my int/vector2 uniforms works fine. DirectionalLight and AmbientLight works fine too.
Two problems:
-
directLight.color turns black after compute PointLight;(detected by return gl_fragcolor in
lights_fragment_begin
) -
My custom map uniforms won’t show.(confirmed by
spector.js
)
The shader had no problems on my old project, but I am rewriting the project by TypeScript and Object-oriented way.
My material:
class DecalMaterial extends THREE.MeshStandardMaterial {
uniforms = THREE.UniformsUtils.merge([
THREE.UniformsLib.common,
THREE.UniformsLib.envmap,
THREE.UniformsLib.aomap,
THREE.UniformsLib.lightmap,
THREE.UniformsLib.emissivemap,
THREE.UniformsLib.normalmap,
THREE.UniformsLib.roughnessmap,
THREE.UniformsLib.metalnessmap,
//THREE.UniformsLib.fog,
THREE.UniformsLib.lights,
{
emissive: { value: new THREE.Color(0x000000) },
roughness: { value: 0.6 },
metalness: { value: 0 },
envMapIntensity: { value: 1 },
normalIntensity: { value: 1.0 },
fabricEmission: { value: 0 },
decalTecRepeat: { value: new THREE.Vector2(1, 1) },
decalThicknessNormalMap: { value: new THREE.Texture() },
uvMatrix: { value: new THREE.Matrix3() },
decalRepeatMode: { value: 0 }
},
{
borderIntensity: { value: 0 },
borderRange: { value: 0 }
},
{
backFaceMap: { value: null }
},
{
backFaceNormalMap: { value: null },
backFaceNormalIntensity: { value: 1.0 }
},
{
originNormalMap: { value: null },
originNormalScale: { value: new THREE.Vector2(1, 1) }
},
{
decalFabricOriginUv: { value: new THREE.Vector2(0.5, 0.5) },
decalFabricUvRange: { value: new THREE.Vector2(0.5, 0.5) },
decalFabricRotation: { value: 0.0 },
decalFabricMapRepeat: { value: new THREE.Vector2(1, 1) }
},
{
pureLightColor: { value: -1.0 },
pureLightIntensity: { value: 0.7 }
},
{
backPureLightColor: { value: 0.6 },
backLightIntensity: { value: 0.7 }
},
{
depthMap: { value: new THREE.Texture() },
opaqueDepthMap: { value: new THREE.Texture() },
depthrender: { value: 0.0 },
tmap: { value: 0.0 },
peeling: { value: 0.0 }
}
]);
constructor() {
super({
roughness: 0.9,
metalness: 0.1,
transparent: true,
depthWrite: false
});
this.onBeforeCompile = shader => {
shader.uniforms = this.uniforms;
shader.vertexShader = ShaderOur.vertexShader;
shader.fragmentShader = ShaderOur.fragmentShader;
};
this.defines["DECAL"] = "";
}
}
How I set my map uniform:
get ThicknessMap() {
return this.uniforms.decalThicknessNormalMap ? this.uniforms.decalThicknessNormalMap.value : null;
}
set ThicknessMap(texture: THREE.Texture) {
if (texture) {
this.defines["DECAL_THICKNESS"] = "";
this.uniforms.decalThicknessNormalMap = {
value: texture
};
} else {
delete this.defines["DECAL_THICKNESS"];
this.uniforms.decalThicknessNormalMap = {
value: null
};
}
this.uniforms.decalThicknessNormalMap.value.needsUpdate = true;
this.needsUpdate = true;
}
The shader is composited by many chunks(just modification of standard material. I didn’t modify the lighting part. And the part about decalThicknessNormalMap
is
#if defined (USE_NORMALMAP) || defined (DECAL_THICKNESS)
uniform sampler2D normalMap;
uniform vec2 normalScale;
uniform float normalIntensity;#ifdef DECAL_THICKNESS uniform sampler2D decalThicknessNormalMap; #endif
Sorry that I don’ t know how to format the text properly. The full vertex shader and fragment shader can be seen here(get from spector.js
):
fragment
vertex
I feel the problems are complicated to explain, so it may be not very clear. If you kind guys need more information, please tell me. I would like to make a fiddle but I don’t know how to paste the long shader with line feeds on it.
Edit: The maps work fine, it disapeared because I forget to open some key words.