2013-04-29 10 views
22

Czy możliwe jest nakładanie wielu tekstur na siebie na tej samej twarzy w pliku Three.js, aby proces mieszania alpha został przyspieszony w programie WebGL?Wiele przezroczystych tekstur na tej samej powierzchni siatki w Three.js

Tekstury są (lub powinny) być zastosowane do tej samej twarzy, tak aby dolna tekstura (tekstura 1) była bez kanału alfa, a powyższe tekstury są alfa channelowane w sposób podobny do tekstury 2 w poniższym przykładzie obrazu.

To mieszanie można osiągnąć za pomocą Canvas HTML5 jako pre-step, ale ponieważ bitmapy tekstury mogą być ogromne, wolę pominąć operacje mieszania Canvas.

Przetestowałem, tworząc kopię siatki i stosując jedną teksturę na siatkę i uczyniłem inną siatkę przezroczystą i przesunąłem ją trochę, co udało się prawie dobrze, ale jest pewne migotanie i ponieważ obiekty nie mogą być dokładnie w tej samej pozycji , między teksturami jest trochę miejsca, co nie jest właściwym efektem. Powinny wydawać się, że zostały połączone w np. Photoshop (jak na zdjęciu poniżej).

enter image description here

+2

można spróbować podejścia odpowiedź [tutaj] (http://stackoverflow.com/questions/13309289/three-js-geometry-in-top -of-another/13309722 # 13309722) – WestLangley

+0

Dzięki. Wydaje się być dobrym sposobem. I prawdopodobnie poradzi sobie również z renderowaniem wielu tekstur jeden na drugim. Ale jeszcze nie przetestowane do tej pory. –

Odpowiedz

51

Zastosowanie ShaderMaterial i ustawić oba tekstur jak mundury, a następnie połączyć je w cieniującego.

Zrobiłem ten przykład: http://abstract-algorithm.com/three_sh/ i to naprawdę powinno wystarczyć.

Więc dokonać 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 

}); 

I tworzyć siatkę z tego materiału:

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

można umieścić najprostszy vertex shader:

varying vec2 vUv; 

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

I fragment shader, który będzie faktycznie mieszania:

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

Jeśli trzeba połączyć nawet więcej tekstur, należy użyć tego samego równania do mieszania tylko kilka razy.

Więc oto wynik:

enter image description here

+1

Dzięki za odpowiedź. Muszę czekać 17 godzin, aby nagrodzić nagrodę. –

+0

To podejście nie pasuje do przypadku, w którym musimy umieścić wiele tekstur w określonej pozycji. – Tarun

+0

@Tarun Tak, zajmuje się tym mapowanie UV. Cóż, jakakolwiek manipulacja w zakresie koordynacji promieni UV. –

Powiązane problemy