如何修改three.js中纹理投射到半球面的方式以解决边缘扭曲问题
问题原因
你遇到的纹理扭曲是THREE.SphereGeometry默认的经纬度UV映射规则导致的:默认UV的U轴对应球面经度,V轴对应球面纬度,这会让半球的两个极点(你所说的顶部、底部点)被映射到纹理的一整条边,所以纹理的边缘会被挤压到单点产生变形。
解决方案
优先选择手动重写几何体UV坐标的方案,无需修改原有材质逻辑,即可实现你要的正方形纹理四角贴合半球圆周的效果:
- 半球创建完成后,将每个顶点的三维坐标投影到半球开口所在的平面,把投影后的坐标归一化到
[0,1]区间作为UV值即可。 - 参考代码如下,在你的
SphereGeometry实例化后添加这段逻辑:
const positionAttr = geometry.attributes.position; const uvArr = new Float32Array(positionAttr.count * 2); // 此处假设你的半球开口朝向Z轴负方向,中心在坐标原点,若朝向不同可自行调整投影轴 for (let i = 0; i < positionAttr.count; i++) { const x = positionAttr.getX(i); const y = positionAttr.getY(i); // 投影到XY平面后归一化到0-1区间 const u = (x / (2 * Component.radius)) + 0.5; const v = (y / (2 * Component.radius)) + 0.5; uvArr[i * 2] = u; uvArr[i * 2 + 1] = v; } geometry.setAttribute('uv', new THREE.BufferAttribute(uvArr, 2)); geometry.attributes.uv.needsUpdate = true;
- 适配说明:如果你的半球开口朝向不是Z轴负方向,比如朝向Y轴负方向,只需要把计算v值的变量从y改成z即可。
如果后续需要更灵活的映射规则,也可以使用自定义MeshStandardMaterial,在片元着色器中动态计算UV值,不需要修改几何体属性。
内容的提问来源于stack exchange,提问作者tengoku
相关产品推荐
相关产品推荐

