Hurricane
Hurricane

Reputation: 31

How to do the blending in Volume Rendering using GLSL?

This introduces the method of Volume Rendering using obsolete API of OpenGL. But now, I want to complete the Volume Rendering using GLSL and I have finished some parts of it. My question is how to do the blending. In the above link, blending is completed by the following codes:

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

But how can I finish the blending using GLSL?

I tried to using the following equation:

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

Cs is the color of source object. Cd is the color of the destination object. As is the alpha of the source object. And my code in fragment shader is as following:

......
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;
......

In my project, I let the value of r, g, b, a of the 3D Texture to be the same. But I cannot obtain the result of the one of the above link. Can you help me to solve the blending problem using GLSL?

Upvotes: 1

Views: 899

Answers (1)

Yakov Galka
Yakov Galka

Reputation: 72489

It is natural to do the computations in premultiplied alpha color-space. It fits better with the emission-absorption of the volumatic phenomena. The corresponding equations are:

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

Although it is possible to do the calculations in non-premultiplied alpha color-space, it would require division by the alpha values and be generally more complicated. (Your code works in non-premultiplied and does not take it into account...)

So to set-up the OpenGL blending you use:

glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA );

and you use this formula in the shader:

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

You also have to take this into account when generating your 3D textures. For example a texture where for all pixels R = G = B = A corresponds to a white foggy substance, so you have to look it over dark background.

Upvotes: 2

Related Questions