8

我想为 THREE.js 球体的每个面赋予它自己的纹理。所以我让 SphereGeometry 计算顶点并使用面的顶点将每个面转换为 PlaneGeometry。

THREE.SpherePlaneGeometry = function ( v1, v2, v3, v4 ) {

  THREE.Geometry.call( this );

  var normal = new THREE.Vector3( 0, 1, 0 );

  this.vertices.push( v1.clone() );
  this.vertices.push( v2.clone() );
  this.vertices.push( v3.clone() );
  this.vertices.push( v4.clone() );

  var face = new THREE.Face4( 0, 1, 2, 3 );

  face.normal.copy( normal );
  face.vertexNormals.push( normal.clone(), normal.clone(), normal.clone(), normal.clone() );

  this.faces.push( face );

  var uvs = [
    new THREE.UV( 1.0, 0.0 ),
    new THREE.UV( 0.0, 0.0 ),
    new THREE.UV( 0.0, 1.0 ),
    new THREE.UV( 1.0, 1.0 ),
  ];
  this.faceVertexUvs[ 0 ].push( uvs );

};

确保所有这些都在稍后使用返回的几何图形运行:

geometry.computeCentroids();
geometry.computeFaceNormals();
geometry.verticesNeedUpdate = true;
geometry.uvsNeedUpdate = true;
geometry.normalsNeedUpdate = true;
geometry.tangentsNeedUpdate = true;
geometry.elementsNeedUpdate = true;
geometry.dynamic = true;

通过应用此纹理:

质地

我得到了这个结果:

领域

可以做些什么来消除红点和绿点之间的失真?对于极点,一个顶点使用两次,但它可能会更好,知道吗?

4

2 回答 2

3

这是一个棘手的问题。我们的纹理映射仍然是仿射的。

废话

在某些时候,我们需要尝试使用透视正确的纹理映射。我在某处读过一些关于插值的东西w……但我不确定这是否能解决你的问题。

为了简化问题...查看纹理映射图像中的仿射映射四边形。想象一下,您将左上角的顶点移动到右上角。通过这样做,您基本上将左三角形变成了一条从左下角到右上角的简单线。这基本上意味着你不会看到它。因为直角三角形的顶点尚未移动,所以三角形仍然存在,可见,UV 已分配给每个顶点。

所以我能想到的唯一解决方案是:

  1. 为这些多边形添加一层细分。
  2. 对于这些可能的情况,具有特殊的预校正纹理(使用画布或 Photoshop)。
于 2012-08-23T14:34:13.870 回答
2

这里有几个问题。

首先,您不需要将几何体的每个面都转换为平面几何体——除非出于某种原因您想要这样做。您可以在下面的 Fiddles 中看到如何处理这个问题。

其次,您的问题是您的紫外线设置。

这是一个 Fiddle ( http://jsfiddle.net/PBjEE/ ),显示了与您类似的问题。我使用了更简单的几何形状,但和你的一样,四边形面是梯形。在小提琴中,我按照你的方法将每个面的 UV 设置为纹理的角,(0,1)、(0,0)、(1,0) 和 (1,1)。结果是一个扭曲的圆圈。

这是另一个 Fiddle ( http://jsfiddle.net/PBjEE/1/ ),通过更改 UV 坐标来消除失真。

UV 坐标必须定义一个与面部具有相同比例的梯形。

于 2012-08-26T20:45:03.823 回答