Three.js:Three.Geometry + LambertMaterial 网格上的光线不正确
Three.js: incorrect light on Three.Geometry + LambertMaterial meshes
我用一个 jsfiddle 改进了我之前对这个问题的表述 (previous question version),该 jsfiddle 使用 Three.JS 的最新版本并演示了我的 Three.Geometry 光照问题。我无法让依赖项在 Stack Snippets 中工作,但 JSFiddle 工作:
JSFIDDLE SHOWING INCORRECT LIGHTING
注意左侧光照不正确的面(Three.Geometry 个对象)与右侧光照正确的相邻面(Three.CubeGeometry)。
我的灯码:
hemiLight = new THREE.HemisphereLight( 0xffffff, 0xffffff, 0.6 );
hemiLight.color.setHSL( 0.6, 1, 0.6 );
hemiLight.groundColor.setHSL( 0.095, 1, 0.75 );
hemiLight.position.set( 0, 50, 0 );
app.scene.add( hemiLight );
dirLight = new THREE.DirectionalLight( 0xffffff, 1 );
dirLight.color.setHSL( 0.1, 1, 0.95 );
dirLight.position.set( -1, 1.75, 1 );
dirLight.position.multiplyScalar( 50 );
app.scene.add( dirLight );
您可以查看 THREE.CubeGeometry(网格 1、2、3)和 THREE.Geometry(网格 4、5、6)对象的 JSFiddle 源代码。网格 5 和 6 具有单独实例化并由数组分配的兰伯特面,而地理 4 具有单个兰伯特 material 传递给网格构造函数。
material 阵列存储 class THREE.MeshFaceMaterial 中的 material 是否需要按特定顺序排列才能使立方体正确点亮?我按顺序分配了它们:2 个底面、8 个侧面、2 个顶面。
如果 Three.Geometry 对象似乎已正确添加到场景中,为什么灯光会平铺在绿色立方体上?谢谢。
从物体外面看,三角绕法需逆时针旋转
要确认,请将 THREE.DoubleSide 的所有实例更改为 THREE.FrontSide 和 运行。 THREE.FrontSide 应该看起来很完美,因为它是 three.js 默认值 - 但在您的示例中它不是。希望这有帮助! :)
只是为了跟进以防其他人偶然发现:
虽然我确实重新安排了顶点顺序以确保 90 度垂直法线,但我发现这并没有对相邻物体照明产生 material 差异。
答案是 three.js 并没有本质上计算场景图中相邻对象之间的光照,虽然阴影贴图功能试图解决这个问题,但我的调查表明阴影贴图解决方案并没有真正起作用对于我的用例。
相反,我只应用了两种几何计算中的一种来获得模拟光效
我拥有的:
geo.computeFaceNormals();
geo.computeVertexNormals();
我最终使用的是:
geo.computeFaceNormals();
//geo.computeVertexNormals();
使用 computeVertexNormals()...
没有
虽然不是完美的光效(光是平的),但现在是可行的。感谢楼主的帮助。
我用一个 jsfiddle 改进了我之前对这个问题的表述 (previous question version),该 jsfiddle 使用 Three.JS 的最新版本并演示了我的 Three.Geometry 光照问题。我无法让依赖项在 Stack Snippets 中工作,但 JSFiddle 工作:
JSFIDDLE SHOWING INCORRECT LIGHTING
注意左侧光照不正确的面(Three.Geometry 个对象)与右侧光照正确的相邻面(Three.CubeGeometry)。
我的灯码:
hemiLight = new THREE.HemisphereLight( 0xffffff, 0xffffff, 0.6 );
hemiLight.color.setHSL( 0.6, 1, 0.6 );
hemiLight.groundColor.setHSL( 0.095, 1, 0.75 );
hemiLight.position.set( 0, 50, 0 );
app.scene.add( hemiLight );
dirLight = new THREE.DirectionalLight( 0xffffff, 1 );
dirLight.color.setHSL( 0.1, 1, 0.95 );
dirLight.position.set( -1, 1.75, 1 );
dirLight.position.multiplyScalar( 50 );
app.scene.add( dirLight );
您可以查看 THREE.CubeGeometry(网格 1、2、3)和 THREE.Geometry(网格 4、5、6)对象的 JSFiddle 源代码。网格 5 和 6 具有单独实例化并由数组分配的兰伯特面,而地理 4 具有单个兰伯特 material 传递给网格构造函数。
material 阵列存储 class THREE.MeshFaceMaterial 中的 material 是否需要按特定顺序排列才能使立方体正确点亮?我按顺序分配了它们:2 个底面、8 个侧面、2 个顶面。
如果 Three.Geometry 对象似乎已正确添加到场景中,为什么灯光会平铺在绿色立方体上?谢谢。
从物体外面看,三角绕法需逆时针旋转
要确认,请将 THREE.DoubleSide 的所有实例更改为 THREE.FrontSide 和 运行。 THREE.FrontSide 应该看起来很完美,因为它是 three.js 默认值 - 但在您的示例中它不是。希望这有帮助! :)
只是为了跟进以防其他人偶然发现:
虽然我确实重新安排了顶点顺序以确保 90 度垂直法线,但我发现这并没有对相邻物体照明产生 material 差异。
答案是 three.js 并没有本质上计算场景图中相邻对象之间的光照,虽然阴影贴图功能试图解决这个问题,但我的调查表明阴影贴图解决方案并没有真正起作用对于我的用例。
相反,我只应用了两种几何计算中的一种来获得模拟光效
我拥有的:
geo.computeFaceNormals();
geo.computeVertexNormals();
我最终使用的是:
geo.computeFaceNormals();
//geo.computeVertexNormals();
使用 computeVertexNormals()...
没有
虽然不是完美的光效(光是平的),但现在是可行的。感谢楼主的帮助。