【发布时间】:2017-03-01 10:43:56
【问题描述】:
我是 WebGL(以及一般 3D 图形)的新手,并且正在使用 three.js。我想做的是从 2D 画布创建多个纹理,并使用它们来渲染多个网格,每个网格都有不同的纹理。
如果我只是将画布传递给新的 THREE.Texture() 原型,则纹理将更改为画布当前的样子。所以我所有的物体都有相同的纹理。我的解决方案是使用 getImageData() 存储每个画布数组,并通过将该数据传递给新的 THREE.DataTexture() 原型来创建新纹理。但是,chrome总是报错,当我在firefox上运行时,纹理显示是颠倒的。
userName = $nameInput.val();
ctx2d.fillText( userName, 256, 128);
var canvasData = ctx2d.getImageData(0,0,512,256);
texture = new THREE.DataTexture(canvasData.data, 512, 256, THREE.RGBAFormat);
texture.needsUpdate = true;
material = new THREE.MeshBasicMaterial({ map: texture });
geometry = new THREE.PlaneGeometry(20,10);
textMesh = new THREE.Mesh( geometry, material);
scene.add(textMesh);
Chrome 和 Safari 记录以下错误:WebGL: INVALID_OPERATION: texImage2D: type UNSIGNED_BYTE but ArrayBufferView not Uint8Array。然而Firefox播放它,虽然纹理是颠倒的。
根据 Mozilla 文档,数据是一个 Uint8ClampedArray。所以假设这是问题所在,我可以通过创建一个新的 Uint8Array() 并将数据传递给它来解决上述错误,如下所示:
var data = new Uint8Array(canvasData.data);
texture = new THREE.DataTexture(data, 512, 256, THREE.RGBAFormat);
但它仍然显示颠倒。怎么回事?
【问题讨论】:
-
另外,如果有人有更好的方法将单独的画布图像存储为纹理而不使用 getImageData,那也很棒。
-
在将图像数据添加到纹理之前使用
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,true);。我希望应该有一个 threee.js 等价物。 -
这在three.js 中不起作用,因为three.js 在上传每个纹理之前调用
gl.pixelStore(gl.UNPACK_FLIP_Y_WEBGL, texture.flipY),这意味着它将有效地覆盖您的设置。
标签: javascript canvas three.js webgl