最简单的方法可能是将纹理加载到2d画布中以构建您的图集。
假设我们有一个下载512个纹理的功能,我们希望通过16个
var width = 128; // just assuming this is the size of a single texture
var height = 128;
var across = 32;
var down = 16;
asyncLoad512Images(useLoaded512Images);
function useLoaded512Images(arrayOfImages) {
var canvas = document.createElement("canvas");
canvas.width = width * across;
canvas.height = height * down;
var ctx = canvas.getContext("2d");
// draw all the textures into the canvas
arrayOfImagess.forEach(function(image, ndx) {
var x = ndx % across;
var y = Math.floor(ndx/across);
ctx.drawImage(image, x * width, y * height);
}
// now make a texture from canvas.
var atlasTex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, atlasTex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE,
canvas);
}
一些优化,把他们在32个网格:所以你让画布一开始你可能更改代码并在每个图像加载到正确位置的2D画布中。优点是浏览器不需要在内存中保存所有512个图像。它可以在你绘制完成后立即丢弃它们。
var width = 128; // just assuming this is the size of a single texture
var height = 128;
var across = 32;
var down = 16;
var numImages = 32 * 16;
var numImagesDownloaded = 0;
// make a canvas to hold all the slices
var canvas = document.createElement("canvas");
canvas.width = width * across;
canvas.height = height * down;
var ctx = canvas.getContext("2d");
// assume the images are named image-x.png
for (var ii = 0; ii < numImages; ++ii) {
loadImage(ii);
}
function loadImage(num) {
var img = new Image();
img.onload = putImageInCanvas(img, num);
img.src = "image-" + num + ".png";
}
function putImageInCanvas(img, num) {
var x = num % across;
var y = Math.floor(num/across);
ctx.drawImage(img, x * width, y * height);
++numImagesDownloaded;
if (numImagesDownloaded === numImages) {
// now make a texture from canvas.
var atlasTex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, atlasTex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE,
canvas);
....
}
}
或者,也可以将每个图像划分成纹理,并使用附连到帧缓冲器的纹理要呈现的图像的纹理到图谱质地。这是更多的工作。你需要制作一个简单的2d着色器,然后在正确的位置渲染每个图像纹理到atlas纹理。
这样做的唯一理由就是如果纹理有4个通道的数据而不是3个或更少,因为2d画布无法使用所有4个通道,因为2d画布始终使用预乘alpha 。
将纹理绘制到纹理中与绘制周期相同。 See any example that draws into a texture。
在three.js所短的版本是,
进行渲染目标
rtTexture = new THREE.WebGLRenderTarget(
width * across, height * down, {
minFilter: THREE.LinearFilter,
magFilter: THREE.NearestFilter,
format: THREE.RGBFormat,
depthBuffer: false,
stencilBuffer: false,
});
rtTexture.generateMipmaps = false;
建立一个平面和渲染,把它放在一个场景的材料。对于每个图像纹理,将材质设置为使用该图像纹理,并设置任何其他参数以使其绘制四边形,然后将其绘制到图集纹理中。 I'm guessing an orthographic camera would make that easiest。然后用渲染目标调用渲染。
renderer.autoClear = false;
renderer.render(sceneRTT, cameraRTT, rtTexture, false);
这将渲染到rtTexture
。
当你完成rtTexture
是你的图谱纹理。只要使用像任何纹理的纹理。将其分配给材料。
实际上,您不必创建2D地图,但可以模拟3D纹理的存在。 http://stackoverflow.com/questions/19939557/a-3-dimensional-array-represented-by-a-2-dimensional-array和https://www.youtube.com/watch?v=rfQ8rKGTVlg#t= 25m03s – gaitat
谢谢您的回答Peter O.然而,您所描述的是我的过程中的下一步。它假定我已经加载了sampler2D tex中所有图像的数组。考虑到我的项目条件,我要问的是如何做到这一点。 –