从Blender导入的网格上有灯光的Three.js ShaderMaterial



我正在尝试获得一个在three.js r77中工作的灯光的ShaderMaterial。当应用于具有简单BoxGeometry的网格时,它可以正常工作,但当应用于从Blender导入的网格时它的行为不正确。

这里有一个简单的jsfiddle来说明这个问题。左侧的网格是通过Blender导出创建的。右侧的网格是从一个简单的BoxGeometry创建的。两者都使用相同的ShaderMaterial。灯光的位置由DirectionalLightHelper指示。

右侧的网格被正确地照亮,而左侧的网格则没有。很明显,问题出在我的着色器代码中。我最初认为问题出现在导入网格的UV贴图中,但事实并非如此。在jsfiddle示例中,UV贴图会从导入的几何体直接复制到BoxGeometry网格中——由于Blender和three.js之间的坐标差异,它们会相对旋转,但导入UV的右侧网格上的照明仍然正常工作。

着色器代码为:

THREE.TestShader = {
uniforms: {
"uDirLightPos": {
type: "v3",
value: new THREE.Vector3(20, 20, 20)
},
"uDirLightColor": {
type: "c",
value: new THREE.Color(0xffffff)
},
"uTexture": {
type: "t",
value: null
},
},
vertexShader: [
"varying vec3 vNormal;",
"varying vec3 vViewPosition;",
"varying vec2 vUv;",
"void main() {",
"vUv = uv;",
"vNormal = normalize(normalMatrix * normal);",
"vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);",
"vViewPosition = -mvPosition.xyz;",
"gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);",
"}"
].join("n"),
fragmentShader: [
"uniform vec3 uDirLightPos;",
"uniform vec3 uDirLightColor;",
"varying vec2 vUv;",
"varying vec3 vNormal;",
"varying vec3 vViewPosition;",
"varying vec4 mvPosition;",
"uniform sampler2D uTexture;",
"void main() {",
"vec4 lDirection = viewMatrix * vec4(uDirLightPos, 0.0);",
"vec3 lVector = normalize(lDirection.xyz);",
"vec3 normal = normalize(vNormal);",
"float diffuse = dot(normal, lVector);",
"vec4 texel = texture2D( uTexture, vUv );",
"gl_FragColor = vec4(uDirLightColor * diffuse, 1.0) * texel;",
"}"
].join("n")
};

除了这个特殊问题的解决方案外,如果能找到关于three.js着色器的更好文档,我们将不胜感激。ShaderChunk、ShaderLib和UniformsLib的官方文档并非详尽无遗。

您的Blender导出模型的法线不正确。

vnh1 = new THREE.VertexNormalsHelper( mesh1, 1, 0xff0000, 1 );
scene.add( vnh1 );

小提琴:https://jsfiddle.net/5j0axcgz/1/

three.js r.77

最新更新