0

I'm trying to UV map a cube-map texture onto a sphere. I have tried to Map a cube-map onto a cube and it was pretty easy. I had this image which was mapped onto the cube as follows: Click here to open image

This is the final output (with a different image, of same type)[Click here to open the Output][2]

This is how I carried out the UV mapping for the aforementioned task:

var geometry = new THREE.CubeGeometry( 10, 10, 10); 
 
var material = new THREE.MeshPhongMaterial( { map:THREE.ImageUtils.loadTexture('images/texture-atlas.jpg') } );

There are few things that I found in OpenGL, but almost nothing for Three.js

If you can come up with anything that'll help me in executing this, it'll be a great help. If possible, please show me how to map one image onto corresponding part of the sphere and I'll do it for the rest of them.

Łukasz
  • 2,131
  • 1
  • 13
  • 28
Galileo Verma
  • 149
  • 1
  • 1
  • 15

1 Answers1

4

A SphereGeometry does not have vertices in the correct locations to achieve the mapping you want. However, you can easily create a suitable geometry by morphing BoxGeometry into a sphere.

// geometry
var geometry = new THREE.BoxGeometry( 10, 10, 10, 8, 8, 8 );

// morph box into a sphere
for ( var i = 0; i < geometry.vertices.length; i ++ ) {

    geometry.vertices[ i ].normalize().multiplyScalar( 10 ); // or whatever size you want

}

// texture is a collage; set offset/repeat per material index
var repeat = new THREE.Vector2( 1/3, 1/2 );
var offsets = [ 
    new THREE.Vector2( 0, 0 ),
    new THREE.Vector2( 0, 1/2 ),
    new THREE.Vector2( 1/3, 0 ),
    new THREE.Vector2( 1/3, 1/2 ),
    new THREE.Vector2( 2/3, 0 ),
    new THREE.Vector2( 2/3, 1/2 )
];

// redefine vertex normals consistent with a sphere; reset UVs
for ( var i = 0; i < geometry.faces.length; i ++ ) {

    var face = geometry.faces[ i ];

    face.vertexNormals[ 0 ].copy( geometry.vertices[ face.a ] ).normalize();
    face.vertexNormals[ 1 ].copy( geometry.vertices[ face.b ] ).normalize();
    face.vertexNormals[ 2 ].copy( geometry.vertices[ face.c ] ).normalize();

    var uvs = geometry.faceVertexUvs[ 0 ];

    for ( var j = 0; j < 3; j ++ ) {

        uvs[ i ][ j ].multiply( repeat ).add( offsets[ face.materialIndex ] );

    }

    // face.normal - will not be used; don't worry about it

}

var loader = new THREE.TextureLoader();
var texture = loader.load( 'texture.jpg' );

// mesh
var mesh = new THREE.Mesh( geometry, new THREE.MeshPhongMaterial( { map: texture } ) );
scene.add( mesh );

three.js r.77

WestLangley
  • 102,557
  • 10
  • 276
  • 276
  • Hi, Mr. @WestLangley Thanks! I tried to execute this, and it works fine. The cube gets morphed into a sphere. There's another hurdle that I have come across. This is what the result looks like (after incorporating your code): http://postimg.org/image/ro54xtarr/ I have used the same UV mapping as I used earlier, and I know it's wrong. But I am unable to think of a proper way to alter the UV mapping, because there are too many vertice now. Please help me to figure this out. Thanks in advance! – Galileo Verma Jun 15 '16 at 04:38
  • Is it a requirement that you use http://i.stack.imgur.com/KNtHH.jpg, or is it OK to load 6 separate images? – WestLangley Jun 15 '16 at 05:07
  • I have to use that single image which has all the six sub-images. Is there a way? – Galileo Verma Jun 15 '16 at 08:19
  • Most probably, the reason why you asked me if a collage is a requirement or not, is because if it is not, we can load the six separate images on the six faces of the cube and then morph it into a sphere. It can be certainly done in this manner. But is there a way to do it without having to load the six images separately? I am eagerly waiting for for reply... – Galileo Verma Jun 15 '16 at 12:49
  • Correct. I modified my answer to show how to use `offset/repeat` with a single collage. You just have to load the collage 6 times. I normally do not provide this kind of help, but your question was interesting to me, so you benefit... I hope this wasn't an assignment... – WestLangley Jun 15 '16 at 16:09
  • I don't quite understand this. I am trying. Anyway, thanks a lot for your help. This was not an assignment. :-) – Galileo Verma Jun 15 '16 at 19:30
  • Provide a live link to show what you are doing if you are stuck. It is not hard. – WestLangley Jun 15 '16 at 19:45
  • I am trying to visualize what you tried to do. Of the six lines that you have in the materials array, the first line passes the args 'path', '0/3', '0/3' to the loadTexture function. This function loads the image onto the morphed 3D object with offset as (0, 0) and repeat as (1/3,1/3). Going as per the documentation, repeat (1/3,1/3) would mean that the texture is repeated 1/3 times in each direction U and V. Now, Why would you do that? Shouldn't be it texture.repeat.set( 1/3, 1/2 ); ? – Galileo Verma Jun 17 '16 at 10:50
  • And one more necessary question, that I have to ask. I understand that we are loading the same image six times, which is a bit inefficient way of doing this. If my image is too heavy(or let's say it is a video texture), will it not talk too much time to render 6 textures than rendering 1 texture? Is there a much more efficient method? – Galileo Verma Jun 17 '16 at 11:25
  • (1) yes. typo. (2) update the uv's and use the first method. The box geometry has a materialIndex for each side. Updating the UVs is easy, it turns out. Updated answer. – WestLangley Jun 17 '16 at 14:32
  • Now that the UVs have been updated, I don't have to change anything right? I mean, earlier we had the problem because on using more number of segments to build the cube, we created a lot more vertices and that messed up the UV mapping.. – Galileo Verma Jun 17 '16 at 14:55
  • Why does the entire morphing through normalization thing nullify, when I move my camera to the center of the 3D object? I just added: ` mesh.scale.x = -1; mesh.position.z = 0;` And this is what I got? [Image] ( http://imgur.com/XMTKAzW ) – Galileo Verma Jun 18 '16 at 10:38
  • You need to make a new post at this point. http://stackoverflow.com/questions/16824650/three-js-how-to-flip-normals-after-negative-scale/16840273#16840273 – WestLangley Jun 18 '16 at 14:06
  • I made a new post. Any help from your end will be appreciated. Thank you! http://stackoverflow.com/questions/37956358/flipping-the-normals-of-geometry-in-three-js – Galileo Verma Jun 21 '16 at 23:49
  • Sorry, I have given you all the help I can. This question was an exception. Good luck! – WestLangley Jun 22 '16 at 00:08