Make Three.js Skybox From Tilemap
Solution 1:
The Question should be "How to make a three.js skyBox from a single image file made up of 12 equal-sized tiles".
(This answer achieved with greatly appreciated assistance from WestLangley).
Some key points:-
Assume the tiles in the source image are arranged and referenced thus:-
//... Personal Source image Desired in-scene Required //... tile numbering [column, row] xyz positions of 6 sequence numbers in //... scheme tile coordinates tiles to be used. Three.js material array //... [ 0][ 3][ 6][ 9][0,0][1,0][2,0][3,0][ ][py][ ][ ][ ][2][ ][ ] //... [ 1][ 4][ 7][10][0,1][1,1][2,1][3,1][nx][pz][px][nz][1][4][0][5] //... [ 2][ 5][ 8][11][0,2][1,2][2,2][3,2][ ][ny][ ][ ][ ][3][ ][ ]
The tile at the centre of the "cross" corresponds to the view looking from the skyBox origin in the Z_positive direction.
(That makes spinning by 180 degrees unneccessary).
In definition of material use... side: THREE.FrontSide
To prevent mirror images of the source tiles, "flip" them using... skyBox.scale.set( -1, 1, 1 )
To ensure that images are fully processed the function F_cutImageUp extends to include creation of the skyBox mesh
This works for the current latest Three.js release (R.68).
This code does not use MeshShaderMaterial, more powerful (but demanding) WebGL code example is available at http://threejs.org/examples/webgl_shaders_ocean.html
The webgl_shaders_ocean.html code example also includes a more efficient tile-cutting and sequencing algorithm.
SkyBox Generation Code (to be inserted in the THREE.js Initialisation function).
varskybox_sidelength=10000;
varskyBoxGeometry=newTHREE.BoxGeometry( skybox_sidelength, skybox_sidelength, skybox_sidelength);
varskyBoxMaterialArray= [];
varnumCols=4, numRows = 3; //... assume any source image is tiled 4 columns(x) by 3 rows(y)//... NB canvas origin is Top Left corner, X is left to right, Y is top to bottom//... We use the following mapping scheme to reference the tiles in the source image:-//...//... Personal [x,y] tile coordinates xyz positions Required tile //... tile numbering of tiles in scene sequence in Three.js //... array //... [ 0] [ 3] [ 6] [ 9] [0,0] [1,0] [2,0] [3,0] [ ] [py] [ ] [ ] [ ] [2] [ ] [ ] //... [ 1] [ 4] [ 7] [10] [0,1] [1,1] [2,1] [3,1] [nx] [pz] [px] [nz] [1] [4] [0] [5] //... [ 2] [ 5] [ 8] [11] [0,2] [1,2] [2,2] [3,2] [ ] [ny] [ ] [ ] [ ] [3] [ ] [ ] varimage_file="3D_Skybox_files/Giant_A.jpg", tile_width = 512, tile_height = 512;
varIP_image=newImage();
IP_image.onload = F_cutImageUp;
IP_image.src = image_file; //... horizontal cross of 6 WYSIWYG tiles in a 4x3 = 12 tile layout.
function F_cutImageUp()
{ //... cut up source image into 12 separate image tiles, numbered 0..11varimagePieces= [];
varitem_num= -1;
for(varxxx=0; xxx < numCols; ++xxx)
{
for(varyyy=0; yyy < numRows; ++yyy)
{
vartileCanvas= document.createElement('canvas');
tileCanvas.width = tileWidth;
tileCanvas.height = tileHeight;
vartileContext= tileCanvas.getContext('2d');
tileContext.drawImage(
IP_image,
xxx * tileWidth, yyy * tileHeight,
tileWidth, tileHeight,
0, 0, tileCanvas.width, tileCanvas.height);
imagePieces.push(tileCanvas.toDataURL());
}
}
//... Required sequence of tile view directions = ["xpos", "xneg", "ypos", "yneg", "zpos", "zneg"];for (variii=0; iii < 6; iii++) //... select the right tiles for the 6 different faces of the sky box
{
//... we associate the centre tile (4) of the cross with the zpos directionif (iii == 0) imagePiece_num = 7;//... xposelseif (iii == 1) imagePiece_num = 1;//... xnegelseif (iii == 2) imagePiece_num = 3;//... yposelseif (iii == 3) imagePiece_num = 5;//... yneg elseif (iii == 4) imagePiece_num = 4;//... zposelseif (iii == 5) imagePiece_num = 10;//... zneg
skyBoxMaterialArray.push
( newTHREE.MeshBasicMaterial
({ map: THREE.ImageUtils.loadTexture(imagePieces[imagePiece_num]),
side: THREE.FrontSide // <== not intuitive
})
);
//... Just for checking image pieces are created OK//window.open(imagePieces[imagePiece_num], "Here is the toDataURL() cached image " + //imagePiece_num, "width=512, height=512");//alert ("Displayed imagePiece_num: " + imagePiece_num);
} //... end of tile selectionvarskyBoxMaterial=newTHREE.MeshFaceMaterial( skyBoxMaterialArray );
varskyBox=newTHREE.Mesh( skyBoxGeometry, skyBoxMaterial );
skyBox.scale.set( -1, 1, 1 ); // <== not intuitive
scene.add( skyBox );
}//... end of F_cutImageUp function <== note function includes skyBox mesh creation.
Post a Comment for "Make Three.js Skybox From Tilemap"