2013-04-29 23 views
22

Ist es möglich, in Three.js mehrere Texturen übereinander auf derselben Fläche zu legen, sodass die Alpha-Mischung in webGL GPU-beschleunigt wird?Mehrere transparente Texturen auf der gleichen Mesh-Fläche in Three.js

Die Texturen sind (oder sollten) auf dieselbe Fläche angewendet werden, so dass die untere Textur (Textur 1) ohne Alphakanal ist und die obigen Texturen wie in Textur 2 im Bildbeispiel Alpha gechannelt sind.

Diese Überblendung kann mit HTML5 Canvas als Vorschritt erreicht werden, aber da Textur-Bitmaps sehr groß sein können, überspringe ich Canvas-Überblendungen lieber.

Ich testete durch Erstellen einer Kopie des Netzes und die Anwendung einer Textur pro Netz und machte anderes Netz transparent und bewegte es ein wenig, was fast gelungen ist, aber es gibt etwas Flackern und weil Objekte nicht genau in der gleichen Position sein können Es gibt einen gewissen Abstand zwischen Texturen, was nicht der richtige Effekt ist. Sie sollten so aussehen, als wären sie z. Photoshop (wie das Bild unten).

enter image description here

+2

Sie den Ansatz in der Antwort versuchen könnte [hier] (http://stackoverflow.com/questions/13309289/three-js-geometry-in-top -von-einem anderen/13309722 # 13309722) – WestLangley

+0

Danke. Scheint ein guter Weg zu sein. Und möglicherweise können auch mehrere Texturen übereinander dargestellt werden. Aber noch nicht so weit getestet. –

Antwort

51

Verwenden ShaderMaterial und beide Texturen als Uniformen gesetzt, und sie dann innerhalb Shader mischen.

Ich machte dieses Beispiel: http://abstract-algorithm.com/three_sh/ und das sollte wirklich genug sein.

Also, Sie ShaderMaterial machen:

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 

}); 

Und schaffen Masche mit diesem Material:

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

Sie können einfachste Vertex-Shader setzen:

varying vec2 vUv; 

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

und Fragment-Shader, die die Mischung tatsächlich tun wird:

#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); 
} 

Wenn Sie noch mehr Texturen mischen müssen, verwenden Sie dieselbe Gleichung nur mehrmals für das Mischen.

Also hier ist das Ergebnis:

enter image description here

+1

Danke für die Antwort. Ich muss 17 Stunden warten, um das Kopfgeld zu vergeben. –

+0

Dieser Ansatz eignet sich nicht für den Fall, dass wir mehrere Texturen an einer bestimmten Position platzieren müssen. – Tarun

+0

@Tarun Ja, UV-Mapping kümmert sich darum. Nun, jede Art von UV-koordinierter Manipulation. –

Verwandte Themen