2. OVERVIEW
Thank to advance of graphic card, we can put a volume data into graphic memory as a 3D texture, and visualize result
by slice the 3D texture using given texture coordinate. Just like 2D texture, we can retrieval the data value between non-
continues data points by interpolation done by graphic hardware, and use this information to draw the pixel. Because most
mass computation (interpolation) is done by hardware, it can speed up the rendering process almost 100 times compare to
splatting method, and create even smoother image (reconstruct using volume itself not kernel function).
3D TEXTURE CREATION
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, SHA_UPBO_TEXTURE3D_R32F_VolumeData);
glBufferData(GL_PIXEL_UNPACK_BUFFER, sizeof(GLfloat) * volume_size,
CORE_TEX_3D0x1000000R32F_VolumeData, GL_STATIC_DRAW);
glBindTexture(GL_TEXTURE_3D, SHA_TEX_TEXTURE3D_R32F_VolumeData);
glTexImage3D(GL_TEXTURE_3D, 0, GL_R32F, resolution[0], resolution[1], resolution[2], 0, GL_RED, GL_FLOAT, NULL);
glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_BORDER);
glTexParameterfv(GL_TEXTURE_3D, GL_TEXTURE_BORDER_COLOR, vmath::vec4(0.0,0.0,0.0,0.0));
glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
SLICE METHOD
We can using a billboard “slice” the billboard from:
“center – max” to “center + max”
Where center is center of data, max is distance from center to edge along the w vector of view matrix;
The center of billboard is:
[center.x + w.x*d, center.y + w.y*d, center.z + w.z*d]
Where “d” is d’s slice
And compute the coordinate of 4 points of billboard using matrix:
mat4 billboardTran = mat4(
ViewMat[0].x, ViewMat[1].x, ViewMat[2].x, 0,
ViewMat[0].y, ViewMat[1].y, ViewMat[2].y, 0,
ViewMat[0].z, ViewMat[1].z, ViewMat[2].z, 0,
Billboard_center.x, Billboard_center.y, Billboard_center.z, 1);
vec4 realVrt = (billboardTran * Vrt);
The texture coordinate (of 3D texture) then can be compute as follow:
TexCoor = vec3(
realVrt.x/VoxelRes.x,
realVrt.y/VoxelRes.y,
realVrt.z/VoxelRes.z);
VoxelRes is resolution of 3D texture.
The projection space of billboard is:
gl_Position = ProjectionMat * (ViewMat * realVrt);
3. FRAGMENT
When 3D texture coordinate pass to fragment shader it can outside 0~1. If so, discard rendering of this pixel.
if(
TexCoor.x >= 0 && TexCoor.x <= 1.0 &&
TexCoor.y >= 0 && TexCoor.y <= 1.0 &&
TexCoor.z >= 0 && TexCoor.z <= 1.0
){
// Rendering …
}else{
discard;
}
To do the blending you need a buffer store the previous color of this pixel, and compute the blending equation then store the
result back to the buffer, output the result when final slice been compute.
vec4 ImageColor = ImageBufferColor[ImageBufferId];
vec4 SrcColor = vec4(
MapColor.r*MapColor.a,
MapColor.g*MapColor.a,
MapColor.b*MapColor.a,
MapColor.a);
vec4 DstColor = vec4(
ImageColor.r*(1-SrcColor.a),
ImageColor.g*(1-SrcColor.a),
ImageColor.b*(1-SrcColor.a),
ImageColor.a*(1-SrcColor.a));
ImageBufferColor[ImageBufferId] = SrcColor + DstColor;
fargColor = SrcColor + DstColor;
ImageBufferId can compute using gl_FragCoord the pixel location on screen. And ImageBufferColor is buffer store at most
2000x2000 pixel.
int ImageBufferId = int(gl_FragCoord.x)+2000*int(gl_FragCoord.y);
the volume data can retrieval using:
vec4 VolumeFetch = texture(VolumeData, TexCoor);
4. FRONT-BACK BACK-FRONT
Between front-back and back-front will make result total different:
Front-back: Back-front:
There are different, but hard to know which is right, to decide the order of drawing it invoke how you implement the blending
equation and w-vector, if you using [src alpha,1-src alpha] for your blending equation, and w-vector is come from view matrix
(eye-center), the back to front slicing order may be the correct one.
SLICE SIMPLE RATE
The different of slice rate will create different density of stripe on the image. Higher simple rate make more stripe thus look
more continue.
Sample rate = max_of_res: Sample rate = max_of_res x 2:
5. COMPARE
As you can see, 3D texture method create more smooth result.
And also faster rendering.
3D texture: Splatting:
3D texture: Splatting: