Reputation: 183
I am trying to figure out how to properly use Three.js' built in ShaderChunk
s for lighting and fog and such, and I figured a good first step was to just copy one of the ShaderLib
shaders' setup. So to start with I used:
customMaterial = new ShaderMaterial({
lights: true,
uniforms: UniformsUtils.merge( [
UniformsLib.common,
UniformsLib.specularmap,
UniformsLib.envmap,
UniformsLib.aomap,
UniformsLib.lightmap,
UniformsLib.emissivemap,
UniformsLib.fog,
UniformsLib.lights,
{
emissive: { value: new Color( 0x000000 ) },
diffuse: { value: new Color( 1,1,1 ) }
}
]),
vertexShader: document.getElementById("vertexShader").textContent,
fragmentShader: document.getElementById("fragmentShader").textContent
})
Where the shader code is just directly copied from meshlambert_vert.glsl and meshlambert_frag.glsl, and that section there is based on this entry in the ShaderLib
However, I am rendering my test scene from two different cameras/renderers at once, and I immediately noticed an issue. Changing one camera's perspective changes the second camera's lighting angle, for objects with this customMaterial
applied.
I assume this is due to these UniformLib
objects being referenced elsewhere?
I'm not sure what I should be passing here instead, nor why this doesn't work but the standard material does. I guess I'm skipping a step, but I don't understand what it might be.
Here is a codepen where I have isolated the problem as much as I can. Now it is almost a direct copy of the ShaderLib
source. At this point I'm thinking this is a pass-by-reference where it should have been a copy, somewhere inside the WebGLRenderer
. https://codepen.io/cl4ws0n/pen/dVewdZ
For whatever its worth, I also tried adding a second scene, and moving the objects between them. That didn't fix it, nor did separate objects in separate scenes sharing the material.
Upvotes: 0
Views: 311
Reputation: 183
As Matjaz Drolc indicated with his comments, this is a bug in three r87. The needsUpdate
flags are not functioning properly for ShaderMaterials
. You can force an update before each render pass in my codepen link and it will render correctly. See the fork https://codepen.io/cl4ws0n/pen/qPYwzp
I have made an issue on the repo, if anyone would like to track it's progress it can be found here.
Upvotes: 0
Reputation: 386
WebGLRenderer has some hardcoded logic for certain materials. In this case it's looking for a flag called isMeshLambertMaterial: https://github.com/mrdoob/three.js/blob/r87/src/renderers/WebGLRenderer.js#L1780
So try setting isMeshLambertMaterial: true, isMeshBasicMaterial: false
in your material.
Upvotes: 1