2016-09-18 2 views
2

This introduit la méthode de rendu du volume en utilisant l'API obsolète d'OpenGL. Mais maintenant, je veux terminer le rendu du volume en utilisant GLSL et j'en ai terminé certaines parties. Ma question est comment faire le mélange. Dans le lien ci-dessus, le mélange est complété par les codes suivants:Comment faire le fondu dans le rendu de volume en utilisant GLSL?

glEnable(GL_BLEND); 
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 

Mais comment puis-je terminer le mélange à l'aide GLSL?

J'ai essayé d'utiliser l'équation suivante:

C = Cs*As + Cd(1 - As) 

Cs est la couleur de l'objet source. Cd est la couleur de l'objet de destination. Comme l'alpha de l'objet source. Et mon code dans shader fragment est comme suivant:

...... 
vec3 dir = backPoint - frontPoint; 
float len = length(dir); 
float stepSize = 0.01; 
vec3 deltaDir = normalize(dir)*stepSize; 
float deltaLen = length(deltaDir); 
float accLen = 0; 
float accAlpha = 0; 
float sampleAlpha = 0; 
vec4 accColor = vec4(0.0); 

vec3 samplePoint = frontPoint; 
vec4 sampleColor; 
while(accLen < len && accColor.a <= 1.0){ 
    sampleColor = texture(texture3D, samplePoint); 

    accColor = sampleColor*sampleColor.a + accColor*(1-sampleColor.a); 

    accLen += deltaLen; 
    samplePoint += deltaDir; 
} 
color = accColor; 
...... 

Dans mon projet, je laisse la valeur de r, g, b, a de la texture 3D pour être le même. Mais je ne peux pas obtenir le résultat de celui du lien ci-dessus. Pouvez-vous m'aider à résoudre le problème de mélange en utilisant GLSL?

+0

La fusion est effectuée par HW lui-même et non par des shaders dans GLSL. Vous devez donc laisser les champs glEnable et glBlendFunc dans votre projet GLSL et sortir de fragment shader uniquement la couleur à fusionner ne traitant pas l'équation de mélange. Cela ne fonctionnerait que si vous faites chaque primitive Blended sous forme de rendu séparé vers/à partir de la texture qui est incroyablement lente ... à moins que le nombre de primitives ne soit pas élevé. – Spektre

+0

Par exemple, voir [mon shader de diffusion atmosphérique simple dans GLSL] (http://stackoverflow.com/a/19659648/2521214) qui combine le mélange natif de la carte gfx et des shaders GLSL (bien que dans le rendu 2 passes, mais cela n'a rien à voir avec blending) – Spektre

+1

Ceci est raycasting, et le mélange fait en effet partie de l'algorithme. – kaerimasu

Répondre

1

Il est naturel de faire les calculs dans l'espace couleur alpha prémultiplié. Il correspond mieux à l'émission-absorption des phénomènes volumiques. Les équations correspondantes sont:

C = Cs + (1 - As)*Cd 
A = 1 - (1 - As)*(1 - Ad) = As + (1 - As)*Ad 

Bien qu'il soit possible de faire les calculs non-prémultipliée espace couleur alpha, il faudrait une division par les valeurs alpha et généralement plus compliquée. (Votre code fonctionne en non-prémultipliée et ne prend pas en compte ...)

donc de mettre en place le mélange que vous utilisez OpenGL:

glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 

et que vous utilisez cette formule dans le shader:

accColor = sampleColor + accColor*(1-sampleColor.a); 

Vous devez également en tenir compte lors de la génération de vos textures 3D. Par exemple une texture où pour tous les pixels R = G = B = A correspond à une substance blanche brumeuse, de sorte que vous devez le regarder sur un fond sombre.