【发布时间】:2018-04-04 05:31:24
【问题描述】:
将BoxBufferGeometry 转换为球体后,并明确正确设置法线如下:
let geometry = new THREE.BoxBufferGeometry(1, 1, 1, 64, 64, 64);
const vertices = geometry.attributes.position;
const normals = geometry.attributes.normal;
for (let i = 0; i < vertices.count; i++) {
const v = new THREE.Vector3().fromArray(vertices.array, i * 3);
v.normalize();
normals.setXYZ(i, v.x, v.y, v.z);
v.setLength(radius);
vertices.setXYZ(i, v.x, v.y, v.z);
}
vertices.needsUpdate = true;
normals.needsUpdate = true;
为了测试,我在每个面上使用完全平坦的法线贴图(即所有像素都是rgb(128, 128, 255))来渲染球体。我的假设是,与没有法线贴图的渲染相比,我应该看不到任何区别,但不幸的是,我在每个面的边缘/uv 边界处都有明显的接缝:
这是一个显示问题的小提琴:https://jsfiddle.net/Lcf1wgvo/5/
如何消除这些接缝?我知道任何球体上都会存在切线空间不连续性,但至少,完全平坦的切线空间法线贴图不应该显示没有接缝吗?
【问题讨论】:
-
我猜问题是对应的uv坐标不连续。您可以使用以下小提琴轻松看到这一点:jsfiddle.net/f2Lommf5/4269。这是因为纹理投影在盒子的每一侧。真实球体的 uv 坐标看起来不同。
-
@Mugen87 用球体进行相同的实验确实消除了接缝,但包括两极的变形。我想这很明确地表明这是由于法线贴图的切线空间问题。大概有一种方法可以通过调整接缝/极点附近的法线贴图来纠正这些问题?
-
我认为 three.js 通常无法做你想做的事,因为它使用导数动态创建切线框架。在 three.js 中渲染烘焙的法线贴图是不可能的,我相信已经有很多版本了。您可以在平面上渲染砖块纹理之类的东西,应该可以。
-
是的,我在这里挖掘了一下:github.com/mrdoob/three.js/blob/… 并担心可能是这种情况。我认为可以通过预先计算切线来解决,但我想在这种情况下它将使用自定义着色器。希望在three.js的上下文中有一个解决方案。