PDA

View Full Version : Creating a 3d texture from data



imanoutkast
11-21-2009, 01:17 AM
Hola,

I have been tinkering around with volume rendering to make volumetric clouds. I came across a decent nVidia demo on rendering to a 3d texture using FBOs and blending with ray marching in a shader program.

My goal is to make a 3d noise texture using libnoise and add that into the blending equation. The problem I'm having is when I create my 3d noise texture, it's only filling up about 1/3 of what it should (the block in the picture):

http://subtle-brilliance.com/images/3d_texture_problem.png

Here's how I go about creating it...it's using the same dimensions as the textures used to make the rest of the volume, but I am uncertain about the [width*height*depth*4] part.

T* texPtr = new T[width*height*depth*4]; // it's templated
int x, y, z;
unsigned nPointsInSlice = width*height;

for (z = 0; z < depth; ++z)
{
for (y = 0; y < height; ++y)
{
for (x = 0; x < width; ++x)
{
T noise = (T)scaleBias.GetValue(x, y, z);
texPtr[(z*nPointsInSlice + y*width + x)] = noise;
}
}
}

GLuint id;
glGenTextures(1, &amp;id);

glActiveTextureARB(texUnit);
glBindTexture(GL_TEXTURE_3D, id);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_REPEAT);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA16F_ARB, width,
height, depth, 0, GL_RGBA, dataType, texPtr);

I looked all over, but all I've found assumes that what I'm missing is simple I guess.

Thanks in advance.

kroneml
11-21-2009, 08:48 AM
I think your are only filling one fourth of your texture - you should do something like that in your loops:



for (z = 0; z < depth; ++z)
{
for (y = 0; y < height; ++y)
{
for (x = 0; x < width; ++x)
{
T noise = (T)scaleBias.GetValue(x, y, z);
texPtr[(z*nPointsInSlice + y*width + x)*4+0] = noise;
texPtr[(z*nPointsInSlice + y*width + x)*4+1] = noise;
texPtr[(z*nPointsInSlice + y*width + x)*4+2] = noise;
texPtr[(z*nPointsInSlice + y*width + x)*4+3] = noise;
}
}
}


Apart from that, if you only need one noise value per texel, you don't have to use GLRGBA15F, you can simply use GL_R32F and create your texture memory with the dimension width*height*depth.
And I you don't need those nested loops - just loop over each texel linearly (using one loop) and fill it with a noise value.

imanoutkast
11-21-2009, 05:52 PM
Well thank you...that was very concise. I will give it a shot. I knew that I wasn't using the most efficient method, so thank you for that as well.