I can make a three.js skybox using 6 separate image files. But I want to be able to build a skybox from a single image made up of tiles.
For example if I have a composite tiled image as source (see (http://www.zen226082.zen.co.uk/STACK_EXCHANGE/Giant_A.jpg)... i dont have enough rep to post it here :-(.
I can load the composite image into a canvas and copy each tile into a cache buffer and then send them into a Three.js materials array. The materials are then used to make a skybox.
However there are two problems.
Problem 1 is that the composite image needs to be flipped. I can do this easilly in a graphics app like Paint.net but it would be nice to be able to do it programmatically in javascript/three.js.
Problem 2 is that Three.js requires that the tiles for Y+ and Y- also need to be rotated 180 degrees. This is difficult (for me) to do in a graphics application. For example here is a composite tiled image after modification to suit the Three.js code which I have been using (http://www.zen226082.zen.co.uk/STACK_EXCHANGE/Giant_B.jpg) (Horrible!)
My Question = Is there some way that I can perform a 180 degree rotation on the two tiles after extracting them from the composite image and before passing them into the skybox construction.
EDIT (10th August 2014) The Question should be "How to make a three.js skyBox from a single image file made up of 12 equal-sized tiles".
Here is the code I have been using:-
var skyBoxGeometry = new THREE.CubeGeometry(skybox_sidelength,skybox_sidelength,skybox_sidelength);
var skyBoxMaterialArray = [];
var widthOfOnePiece = 2048/4;//...i.e. 512
var heightOfOnePiece = 1536/3;//...i.e. 512
var numColsToCut = 4;
var numRowsToCut = 3;
var image = new Image();
image.src = "TRI_VP_files/images/SOW_skybox_2048_1536_v7.jpg";
image.onload = SOW_F_cutImageUp;
//... NB canvas origin is Top Left corner, X is left to right, Y is top to bottom
function SOW_F_cutImageUp() {
var imagePieces = [];
for(var xxx = 0; xxx < numColsToCut; ++xxx)
{
for(var yyy = 0; yyy < numRowsToCut; ++yyy)
{
var canvas = document.createElement('canvas');
canvas.width = widthOfOnePiece;
canvas.height = heightOfOnePiece;
var context = canvas.getContext('2d');
context.drawImage(image,
xxx * widthOfOnePiece, yyy * heightOfOnePiece, widthOfOnePiece, heightOfOnePiece, 0, 0, canvas.width, canvas.height);
imagePieces.push(canvas.toDataURL());
}
}
//... expected sequence of face view directions = ["xpos", "xneg", "ypos", "yneg", "zpos", "zneg"];
for (var iii = 0; iii < 6; iii++)
{
if (iii == 0) imagePiece_num = 4 //... xpos
else if (iii == 1) imagePiece_num = 10//... xneg
else if (iii == 2) imagePiece_num = 6 //... ypos
else if (iii == 3) imagePiece_num = 8 //... yneg
else if (iii == 4) imagePiece_num = 1 //... zpos
else if (iii == 5) imagePiece_num = 7 //... zneg
skyBoxMaterialArray.push
( new THREE.MeshBasicMaterial
( {map: THREE.ImageUtils.loadTexture(imagePieces[imagePiece_num]),
side: THREE.BackSide}));
//window.open(imagePieces[imagePiece_num], "Here is the toDataURL() cached image", "width=512, height=512");
//alert ("Continue");
}
}//... end of function.
var skyBoxMaterial = new THREE.MeshFaceMaterial( skyBoxMaterialArray );
var skyBox = new THREE.Mesh( skyBoxGeometry, skyBoxMaterial );
scene222.add( skyBox );
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:-
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).