Three.jsの同じ面に複数のテクスチャを重ねて配置して、アルファブレンドがwebGLでGPUアクセラレーションされるようにすることはできますか?
下のテクスチャ(テクスチャ1)にアルファチャネルがなく、上記のテクスチャが下の画像の例のテクスチャ2のようにアルファチャネル化されるように、テクスチャは同じ面に適用されます(または適用する必要があります)。
このブレンディングはHTML5 Canvasをプリステップとして使用して実現できますが、テクスチャビットマップは非常に大きくなる可能性があるため、Canvasブレンディング操作をスキップすることを好みます。
メッシュのコピーを作成し、メッシュごとに1つのテクスチャを適用し、他のメッシュを透明にして少し動かしてテストしましたが、ほとんどうまくいきましたが、ちらつきがあり、オブジェクトを正確に同じ位置に配置できないため、いくつかあります。適切な効果ではないテクスチャ間の空間。彼らは、例えば、それらにブレンドされたように見えるはずです。 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
});
そして、そのマテリアルでメッシュを作成します:
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);
}
さらに多くのテクスチャをブレンドする必要がある場合は、同じ方程式を使用して複数回ブレンドするだけです。
これが結果です: