I want to give each face of a THREE.js sphere it's own texture. So I let a SphereGeometry calculate the vertices and convert each face to a PlaneGeometry using the vertices of the faces.
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 );
};
to be sure all of this runs later with the returned geometry:
geometry.computeCentroids();
geometry.computeFaceNormals();
geometry.verticesNeedUpdate = true;
geometry.uvsNeedUpdate = true;
geometry.normalsNeedUpdate = true;
geometry.tangentsNeedUpdate = true;
geometry.elementsNeedUpdate = true;
geometry.dynamic = true;
By applying this texture:
I got this result:
What can be done to remove the distortion between the red and green points? For the poles one vertice is used twice, but it could be better, any idea?
This is a tricky problem. Our texture mapping is still affine.
At some point we'll need to experiment with perspective correct texture mapping. I have read somewhere something about interpolating a w
... but I'm not really sure that this would solve your problem.
To simplify the problem... look at the affine mapped quad in texture mapping image. Imagine that you move the top left vertex into the top right. By doing that you're basically turning the left triangle into a simple line that goes from bottom left to top right. This basically mean that you it won't be visible. Because the vertices of the right triangle have not been moved, the triangle is still there, visible, with the UVs asigned to each vertex.
So the only solutions I can think would be:
There are several issues here.
First, you do not need to convert each face of your geometry to plane geometry -- unless for some reason you want to. You can see how this can be handled in the Fiddles below.
Second, your problem is your UV settings.
Here is a Fiddle ( http://jsfiddle.net/PBjEE/ ) showing a problem similar to yours. I have used a simpler geometry, but like yours, the quad faces are trapezoids. In the Fiddle, I followed your approach of setting the UVs for each face to be the corners of the texture, (0,1), (0,0), (1,0), and (1,1). The result is a distorted circle.
Here is another Fiddle ( http://jsfiddle.net/PBjEE/1/ ) where the distortion is removed by changing the UV coordinates.
The UV coordinates must define a trapezoid having the same proportions as the face.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With