Javascript 如何在three.js中创建纹理,然后通过着色器进行渲染?

Javascript 如何在three.js中创建纹理,然后通过着色器进行渲染?,javascript,three.js,shader,Javascript,Three.js,Shader,现在我有了数组:uint8clampedaray(大小:512*512*4),我想将此数组转换为three.js中的纹理,然后使用three.ShaderMaterial渲染对象。 new THREE.ShaderMaterial( { vertexShader: document.querySelector( '#blendModel-vert').textContent.trim(), fragmentShader: document.querySelector( '#ble

现在我有了数组:
uint8clampedaray(大小:512*512*4)
,我想将此数组转换为three.js中的纹理,然后使用
three.ShaderMaterial
渲染对象。

new THREE.ShaderMaterial( {
    vertexShader: document.querySelector( '#blendModel-vert').textContent.trim(),
    fragmentShader: document.querySelector( '#blendModel-frag' ).textContent.trim(),
    uniforms: {
        buffer:  { value: texture },
    }
});
该着色器如下所示:

<script id="blendModel-vert" type="x-shader/x-vertex">
    varying vec2 vUv;
    varying vec4 gPosition;
    void main() {
        vUv = uv;
        gPosition=gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }
</script>
<script id="blendModel-frag" type="x-shader/x-fragment">
    varying vec2 vUv;
    uniform sampler2D buffer;
    varying vec4 gPosition;
    void main() {
        gl_FragColor.rgb = texture2D(buffer, vUv).rgb;
        gl_FragColor.a = 1.0;
    }
</script>

可变vec2 vUv;
可变的vec4-gPosition;
void main(){
vUv=紫外线;
gPosition=gl_Position=projectionMatrix*modelViewMatrix*vec4(位置,1.0);
}
可变vec2 vUv;
均匀采样二维缓冲区;
可变的vec4-gPosition;
void main(){
gl_FragColor.rgb=纹理2d(缓冲区,vUv).rgb;
gl_FragColor.a=1.0;
}
一种可能性是使用。
提供给
Three.DataTexture
的数据缓冲区必须是
Uint8Array
类型,而不是
uint8clampedaray
。文档中提到了这一点。
缓冲区必须由[0255]范围内的字节值组成:

e、 g

设t_cx=512;
设t_cy=512;
设t_data=newuint8array(4*t_cx*t_cy);
for(设i=0;i
此外,必须在新创建的纹理对象上设置属性
true

var texture=new THREE.DataTexture(t_data,t_cx,t_cy,THREE.RGBAFormat);
texture.needsUpdate=true;
也可以创建临时的2D画布和图像对象。这可以通过
THREE加载。TextureLoader像往常一样:

let canvas=document.createElement('canvas');
设ctx=canvas.getContext('2d');
canvas.width=t_cx;
canvas.height=t_cy;
设idata=ctx.createImageData(t_-cx,t_-cy);
idata.data.set(t_数据);
ctx.putImageData(idata,0,0);
让dataUri=canvas.toDataURL();
var texture=new THREE.TextureLoader().load(dataUri);
canvas.remove();
请参见示例:

(函数onLoad(){
变量加载器、摄影机、场景、渲染器、轨道控制;
init();
制作动画();
函数init(){
renderer=new THREE.WebGLRenderer({
反别名:是的,
阿尔法:是的
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth、window.innerHeight);
renderer.shadowMap.enabled=true;
document.body.appendChild(renderer.doElement);
摄像头=新的三个透视摄像头(70,window.innerWidth/window.innerHeight,1100);
摄像机位置设置(0,1,-2);
//摄像机。注视(-1,0,0);
loader=新的三个.TextureLoader();
loader.setCrossOrigin(“”);
场景=新的三个。场景();
scene.background=新的三种颜色(0xffffff);
场景。添加(摄影机);
window.onresize=调整大小;
var环境光=新的三个环境光(0x404040);
场景。添加(环境光);
var方向光=新的三个方向光(0xffffff,0.5);
定向灯位置设置(1,2,1.5);
场景。添加(方向光);
轨道控制=新的三个轨道控制(摄像机);
addGridHelper();
createModel();
}
函数createModel(){
设t_cx=512;
设t_cy=512;
设t_data=newuint8array(4*t_cx*t_cy);
for(设i=0;i

可变vec2 vUv;
void main(){
vUv=紫外线;
gl_位置=projectionMatrix*modelViewMatrix*vec4(位置,1.0);
}
高精度浮点;
均匀采样二维缓冲区;
可变vec2 vUv;
void main(){
gl_FragColor=纹理2D(缓冲区,vUv);
}

看看。uint8clampedaray(大小:512*512*4)是函数tf.toPixels()的输出。您可以绘制HTML画布,然后像使用纹理一样解决问题。这里有