我有一个带有平面的场景,该场景应使用WebGL纹理(使用gl.createTexture()
创建)作为材质的贴图。基本上,此纹理的使用方式无关紧要,我只需要找到一种方法就可以以一定的一致性将其传递到ShaderMaterial
。 WebGL纹理会更新每一帧。
纹理是在其他画布元素的上下文中渲染的,并且可以在这样的上下文中使用:
var imageLocation = gl.getUniformLocation(program, "u_image");
gl.uniform1i(imageLocation, 0);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, targetTexture1);
我已经尝试过this solution。但是似乎THREE.Texture()
不能从原始WebGL纹理中获取数据。
答案 0 :(得分:1)
如果您浏览the source,此功能将从r103开始生效。当然,不能保证它将在将来使用,但nothing in three is guaranteed to work in the future之后就可以使用。
首先创建一个Texture
,然后调用forceTextureInitialization
来强制Three.js初始化纹理。
const forceTextureInitialization = function() {
const material = new THREE.MeshBasicMaterial();
const geometry = new THREE.PlaneBufferGeometry();
const scene = new THREE.Scene();
scene.add(new THREE.Mesh(geometry, material));
const camera = new THREE.Camera();
return function forceTextureInitialization(texture) {
material.map = texture;
renderer.render(scene, camera);
};
}();
然后像这样用自己的语言替换Texture
的WebGL纹理
const texProps = renderer.properties.get(someTexture);
texProps.__webglTexture = someGLTexture;
示例:
'use strict';
/* global THREE */
function main() {
const canvas = document.querySelector('#c');
const renderer = new THREE.WebGLRenderer({
canvas: canvas
});
const fov = 75;
const aspect = 2; // the canvas default
const near = 0.1;
const far = 5;
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.z = 2;
const scene = new THREE.Scene();
const boxWidth = 1;
const boxHeight = 1;
const boxDepth = 1;
const geometry = new THREE.BoxGeometry(boxWidth, boxHeight, boxDepth);
const forceTextureInitialization = function() {
const material = new THREE.MeshBasicMaterial();
const geometry = new THREE.PlaneBufferGeometry();
const scene = new THREE.Scene();
scene.add(new THREE.Mesh(geometry, material));
const camera = new THREE.Camera();
return function forceTextureInitialization(texture) {
material.map = texture;
renderer.render(scene, camera);
};
}();
const cubes = []; // just an array we can use to rotate the cubes
{
const gl = renderer.getContext();
const glTex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, glTex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 2, 2, 0,
gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([
255, 0, 0, 255,
0, 255, 0, 255,
0, 0, 255, 255,
255, 255, 0, 255,
]));
gl.generateMipmap(gl.TEXTURE_2D);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
const texture = new THREE.Texture();
forceTextureInitialization(texture);
const texProps = renderer.properties.get(texture);
texProps.__webglTexture = glTex;
const material = new THREE.MeshBasicMaterial({
map: texture,
});
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
cubes.push(cube); // add to our list of cubes to rotate
}
function render(time) {
time *= 0.001;
cubes.forEach((cube, ndx) => {
const speed = .2 + ndx * .1;
const rot = time * speed;
cube.rotation.x = rot;
cube.rotation.y = rot;
});
renderer.render(scene, camera);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
}
main();
<canvas id="c"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/103/three.min.js"></script>
当然请注意,您可以抓住Texture
已经在使用的纹理,然后使用WebGL对其进行操作