我可以使用 6 个单独的图像文件制作一个 three.js 的天空盒。但我希望能够从由瓷砖组成的单个图像构建天空盒。
例如,如果我有一个复合平铺图像作为源(请参阅(http://www.zen226082.zen.co.uk/STACK_EXCHANGE/Giant_A.jpg)...我没有足够的代表在这里发布它:-(。
我可以将合成图像加载到画布中,并将每个图块复制到缓存缓冲区中,然后将它们发送到 Three.js 材料数组中。然后使用这些材料制作天空盒。
然而有两个问题。
问题1是合成图像需要翻转。我可以在像 Paint.net 这样的图形应用程序中轻松地做到这一点,但如果能够在 javascript/three.js 中以编程方式做到这一点,那就太好了。
问题 2 是 Three.js 要求 Y+ 和 Y- 的图块也需要旋转 180 度。这在图形应用程序中(对我来说)很难做到。例如,这是一个经过修改以适应我一直在使用的 Three.js 代码的合成平铺图像(http://www.zen226082.zen.co.uk/STACK_EXCHANGE/Giant_B.jpg)(太可怕了!)
我的问题 = 在从合成图像中提取它们并将它们传递到天空盒构造之前,我是否可以通过某种方式对两个图块执行 180 度旋转。
编辑(2014 年 8 月 10 日)问题应该是“如何从由 12 个大小相等的图块组成的单个图像文件中制作一个 three.js skyBox”。
这是我一直在使用的代码:-
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 );