views:

30

answers:

1

Hello,

I am trying to do something with Ogre using 3D textures. I would like to update a 3D-texture by going through it slice-by-slice and recalculating the color values. However, in each step I also need to access the previous slice somehow to read the values. Setting up a slice as a render target is easy, but is it possible to feed such a slice as a 2D-texture input to a shader, or do I need to explicitly copy it into a separate 2D texture?

Thanks.

A: 

You can address one slice of the 3D texture by playing with the 3D texture coordinates values (which i will refer to as the (u, v, w) coordinates).

For example, let's say you want to get the slices along the Z axis. Imagine that your 3D texture lives a unit cube in the 3D world. The coordinates (u, v, 0) will yield the texels of the first slice. (u, v, 0.5) will yield the texels in the middle of the volume and (u, v, 1.0), the texels of the last slice.

A first slicing shader would look like this :

// slicer.cg
//------------------------------------------------------------------------------
struct AppData
{
   float3 position   : POSITION;
   float3 normal     : NORMAL;
   float3 texcoord   : TEXCOORD0;
};

struct VertexOutput
{
    float4 position : POSITION;
    float3 texcoord : TEXCOORD0;
};
//------------------------------------------------------------------------------
VertexOutput main_vp( AppData           IN
                   , uniform float4    slice
                   , uniform float4x4  worldViewProj)
{

   VertexOutput OUT;
   OUT.position = mul(worldViewProj, float4(IN.position, 1));
   OUT.texcoord = float3(IN.texcoord.xy, slice.x);

   return OUT;
}
//------------------------------------------------------------------------------
void main_fp( float3             texcoord : TEXCOORD0
            , out float3         oColor   : COLOR
            , uniform sampler3D  volume)
{
    float val = tex3D(volume, texcoord).a;
    oColor = float3(1.0, 0.0, 0.0) ;
}

In this example, the slice index along the Z axis is passed through a uniform variable (float4 slice), in the vertex shader (main_vp). The (u, v) texture coordinates are defined in a mesh (in this case, it would be a simple 2D quad), interpolated by the GPU, and used in the fragment shader (main_fp)

I'm not sure what you're trying to achieve by accessing the previous slice, but again, you can do it by recomputing the w value in the shader and resampling the the 3D texture.

Of course, you could cut your cube along another axis, or even with an arbitrary plane, but that last one would need a little more math to get the 3 (u, v, w) coordinates.

sevas