I can't seem to get my volume raycaster to work properly. I've been poking around changing things for days trying to get it to display my volume correctly but I seem only to get distorted mutations of it.

What I tried to do was a 1-pass renderer because the 2-pass one I made wasn't good enough for my purposes. I'm using C# XNA and the renderer wont have to handle transparency so it only has to get in and fetch the first color it bumps into.

How it should look:

enter image description here

How it looks:

enter image description here

float4 OnePassPS(OnePassVSOutput input, float2 pixelCoord : VPOS) : COLOR0 {

float3 rayDir = normalize(mul(float3(((pixelCoord / WindowSize) * 2) - 1.0, -FocalLength), ModelView));

float4 pos = float4(RayOrigin + (rayDir * (input.pos.z / input.pos.w)), 0);
float3 Step = rayDir * StepSize;

float4 color = float4(0, 0, 0, 0);
for(int i = 0; i < Iterations; i++)
    color = tex3Dlod(VolumeS, pos); 

    if(color.a > 0)

    pos.xyz += Step;
return color; }

1 Answer 1

float3 rayDir = normalize(mul(float3(((pixelCoord / WindowSize) * 2) - 1.0, -FocalLength), ModelView));

this code is defintly wrong, i see the following problem here:

  • (a) You use a usual matrix operation to transform a direction, which is plainly wrong (you need different matrices for transforming positions and directions)

Your Matrix looks like this (from your comment)

Matrix.CreateTranslation(-Vector3.One / 2) * Matrix.CreateScale(10) * Matrix.CreateLookAt(camera.Position, Vector3.Zero, Vector3.Up);

to illustrate the problem here we take as an example a (0.7, 0.7, 0.0) unity normalized vector, when i multiply it with Matrix.CreateTranslation(5.0, 0.0, 0.0) i get as direction (5.7, 0.0, 0.0) which is no more normalized and wrong.

After showing why it is wrong i give you the advice, let (most of) the matrix stuff out of it and do the following (a version using matrices exists too for sure but i do it with vectors):

  • calculate the (normalized) direction of the look direction lookDir with rotating a unity vector
  • calculate the HorizontalVector using the cross product HorizontalVector = lookDir.cross(UpVector).normalized()
  • calculate the vertical vector VerticalVector = HorizontalVector.cross(lookDir).normalized()

now you can calculate the direction for each pixel with the following formula

Dir = (lookDir + VerticalVector.scale(pixelCoord.X / WindowSize.X - 0.5f) + HorizontalVector.scale(pixelCoord.Y / WindowSize.Y - 0.5f)).normalized()

Note that you have to check that the Vertical and Horizontal Vectors point in the right direction, if not switch the cross product.

  • \$\begingroup\$ Thanks for the answer! But what exactly is wrong with my matrix and what would I have to do differently to fix it? And for (b) yes that is what it does and yes it's a float vector. And the second bit I dont think is wrong because it moves the position forwards so it wont have to traverse the long distance to get to the volume. \$\endgroup\$
    – Lorto6
    Jul 11, 2013 at 13:34
  • \$\begingroup\$ This is the matrix i give the shader: Matrix.CreateTranslation(-Vector3.One / 2) * Matrix.CreateScale(10) * Matrix.CreateLookAt(camera.Position, Vector3.Zero, Vector3.Up); \$\endgroup\$
    – Lorto6
    Jul 11, 2013 at 13:35
  • \$\begingroup\$ Thanks for the explanation ^^ I implemented the vector method as you suggested and it looks exactly the same with all the same problems. Really confusing. \$\endgroup\$
    – Lorto6
    Jul 20, 2013 at 12:49
  • \$\begingroup\$ Wasnt able to get your method working... But i came up with a better method that was simpler after tearing my hair out and resorting to paper and pen XD \$\endgroup\$
    – Lorto6
    Jul 26, 2013 at 15:03

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .