Reputation: 31
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
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