Three.js中同一网格物体上的多个透明纹理

是否可以在Three.js的同一个面上放置多个纹理,以便在GPU中加速GPU?

纹理是(或应该)应用到同一个面,以便底部纹理(纹理1)没有alpha通道,上面的纹理是像下面的图像示例中纹理2的方式alpha通道。

这种混合可以使用HTML5 Canvas作为预备步骤来实现,但是由于纹理位图可能很大,我倾向于跳过Canvas混合操作。

我testing了创build一个网格的副本,并应用每个网格一个纹理,并使其他网格透明,并移动了一点,这几乎成功,但有一些闪烁,因为对象不能完全在相同的位置,有一些纹理之间的空间不是正确的效果。 他们应该看起来像他们混合在例如。 Photoshop(如下图)。

在这里输入图像描述

使用ShaderMaterial并将两个纹理都设置为统一,然后在着色器中进行混合。

我做了这个例子: http : //abstract-algorithm.com/three_sh/ ,真的应该够了。

所以,你使ShaderMaterial:

var vertShader = document.getElementById('vertex_shh').innerHTML; var fragShader = document.getElementById('fragment_shh').innerHTML; var attributes = {}; // custom attributes var uniforms = { // custom uniforms (your textures) tOne: { type: "t", value: THREE.ImageUtils.loadTexture( "cover.png" ) }, tSec: { type: "t", value: THREE.ImageUtils.loadTexture( "grass.jpg" ) } }; var material_shh = new THREE.ShaderMaterial({ uniforms: uniforms, attributes: attributes, vertexShader: vertShader, fragmentShader: fragShader }); 

并使用该材质创build网格:

 var me = new THREE.Mesh( new THREE.CubeGeometry(80,80,80), material_shh ); 

你可以把最简单的顶点着色器:

 varying vec2 vUv; void main() { vUv = uv; vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 ); gl_Position = projectionMatrix * mvPosition; } 

而片段着色器将实际上进行混合:

 #ifdef GL_ES precision highp float; #endif uniform sampler2D tOne; uniform sampler2D tSec; varying vec2 vUv; void main(void) { vec3 c; vec4 Ca = texture2D(tOne, vUv); vec4 Cb = texture2D(tSec, vUv); c = Ca.rgb * Ca.a + Cb.rgb * Cb.a * (1.0 - Ca.a); // blending equation gl_FragColor= vec4(c, 1.0); } 

如果你需要混合更多的纹理,你可以使用相同的方程来混合多次。

所以结果如下:

在这里输入图像描述