【发布时间】:2014-08-11 00:40:09
【问题描述】:
我可以使用 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 );
【问题讨论】:
-
这里有很多活动部件。你在使用 WebGLRenderer 吗?在这个 three.js 示例中查看如何提取十字架:threejs.org/examples/webgl_shaders_ocean.html。在示例中,使用
MeshShaderMaterial代替MeshFaceMaterial。 -
@WestLangley。非常感谢。 cubeMap 的东西可以满足我的需要……在 PC/Win7/Firefox 中……但是在 PC/Win7/Chrome 中,webgl_shaders_ocean.html 演示使我的 PC 崩溃了……我拿出了水镜的东西,现在它在三点失败了。 js 第 508 行,带有“未捕获的 SecurityError:无法在 'WebGLRenderingContext' 上执行 'texImage2D':可能无法加载受污染的画布。”也无法在 PC/Win7/Opera 中运行。我在 Chrome/Opera 中使用three.js/webgl 12 个月没有问题。
-
1.崩溃需要不同的帖子... 2. 看看这种替代方法是否适合您:使用您的
MeshFaceMaterial方法,并设置skyBoxGeometry.scale.set( -1, 1, 1 );您可能需要将xpos与xneg交换。 -
@WestLangley。假设您的意思是“skyBox.scale.set ...”(即网格,而不是引发错误的几何图形)。无论如何,使用 skyBox.scale.set(-1,1,1) 天空盒根本不显示。
-
skyBox.scale.set( -1, 1, 1 ),对于材料数组中的每种材料,material.side = THREE.FrontSide;
标签: javascript three.js skybox