2015-08-11 1 views
0

J'essaie d'appliquer un masque sur une texture avec transparence. L'effet que j'essaie d'obtenir est un objet avec une fissure, et vous devriez être capable de voir à travers la fissure. J'ai essayé d'utiliser des tampons de mélange et de trame sans succès.Comment appliquer un masque à une texture avec transparence pour obtenir un effet de transparence

Voici les sprites que je utilise:
La balle: http://i.stack.imgur.com/4gImO.png
(remarquez que la balle est transparente autour)
Le masque: http://i.stack.imgur.com/ij4Uw.png
(le masque est blanc avec des fissures transparentes au milieu)

Ceci est le résultat actuel, je reçois:
enter image description here
Ceci est le résultat que je cherche: enter image description here
(cela a été fait en utilisant pixmaps en vérifiant chaque pixel dans le masque, et en dessinant seulement ceux avec alpha> 0, mais il est trop lent, il se fige pendant une seconde ou deux sur Android, et je ne peux pas le précharger parce que je ne sais pas l'objet que je suis l'application du masque jusqu'à ce que je dois l'appliquer)

Ceci est ma fonction rendre:

@Override 
public void render() { 
    Gdx.gl.glClearColor(1, 0, 0, 1); 
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 
    batch.begin(); 

    mBackground.draw(batch); 

    batch.setBlendFunction(GL20.GL_ZERO, GL20.GL_SRC_COLOR); 
    mMask.draw(batch); 

    batch.setBlendFunction(GL20.GL_DST_ALPHA, GL20.GL_ONE_MINUS_DST_ALPHA); 
    mObject.draw(batch); 

    batch.end(); 
} 
+1

Êtes-vous en mesure de fournir un shader personnalisé dans libgdx? Si oui, créez un shader qui échantillonne à partir de la texture du masque et de la sphère tex pour que le masque soit appliqué dans le fragment shader ... Cela signifie que l'échantillonnage de la texture de votre masque devrait bien s'aligner avec les UV de votre sphère mesh ... Si c'est un non-starter, une autre approche pourrait être de faire une pré-passe qui marque le tampon stencil où la fissure est localisée (le shader ici devrait jeter les fragments blancs), puis utiliser le tampon stencil pour masquer les rendus suivants ... Quelques idées - je ne connais pas libgdx. – user8709

+1

Une autre option, qui peut ne pas être évolutive pour votre problème, est d'avoir deux versions de chacune des textures qui doivent être craquées ... Une avec une fissure et une sans. – user8709

+2

C'est un travail pour les combinateurs de texture, vraiment. Mais j'essaie de ne pas expliquer ces vilaines choses à moins que ce ne soit absolument nécessaire. Les shaders sont idéaux, mais cela ressemble à un truc de niveau ES 1.x. –

Répondre

1

j'ai réussi à obtenir ce travail en utilisant les shaders. Voici ma solution:
Le rendu fonction:

@Override 
public void render() { 
    Gdx.gl20.glClearColor(0, 0, 0, 1); 
    Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT); 

    batch.begin(); 
    mBackground.draw(batch); 

    batch.setShader(mShaderProgram); 

    Gdx.graphics.getGL20().glActiveTexture(GL20.GL_TEXTURE0); 
    mObjectTexture.bind(0); 
    mShaderProgram.setUniformi("u_texture", 0); 

    Gdx.graphics.getGL20().glActiveTexture(GL20.GL_TEXTURE1); 
    mMaskTexture.bind(1); 
    mShaderProgram.setUniformi("u_mask", 1); 

    Gdx.graphics.getGL20().glActiveTexture(GL20.GL_TEXTURE0); 
    batch.draw(mObjectTexture, 0, 0, 500, 500); 

    batch.end(); 
    batch.setShader(null); 
} 

Le vertex shader:

attribute vec4 a_position; 
attribute vec4 a_color; 
attribute vec2 a_texCoord0; 

uniform mat4 u_projTrans; 

varying vec2 v_texCoords; 

void main() { 
    v_texCoords = a_texCoord0; 
    gl_Position = u_projTrans * a_position; 
} 

Le fragment shader:

varying vec2 v_texCoords; 
uniform sampler2D u_texture; 
uniform sampler2D u_mask; 
uniform mat4 u_projTrans; 

void main() { 
    vec4 texColor = texture2D(u_texture, v_texCoords); 
    vec4 maskColor = texture2D(u_mask, v_texCoords); 

    gl_FragColor = texColor * maskColor.a; 
}