# Calculating distance from viewer to object in a shader

Good morning,

I'm working through creating the spherical billboards technique outlined in this paper. I'm trying to create a shader that calculates the distance from the camera to all objects in the scene and stores the results in a texture. I keep getting either a completely black or white texture.

Here are my questions:

• I assume the position that's automatically sent to the vertex shader from ogre is in object space?
• The gpu interpolates the output position from the vertex shader when it sends it to the fragment shader. Does it do the same for my depth calculation or do I need to move that calculation to the fragment shader?
• Is there a way to debug shaders? I have no errors but I'm not sure I'm getting my parameters passed into the shaders correctly.

void DepthVertexShader(
float4 position : POSITION,
uniform float4x4 worldViewProjMatrix,
uniform float3 eyePosition,
out float4 outPosition : POSITION,
out float Depth
)
{
// position is in object space
// outPosition is in camera space
outPosition = mul( worldViewProjMatrix, position );
// calculate distance from camera to vertex
Depth = length( eyePosition - position );
}

float Depth : TEXCOORD0,
uniform float fNear,
uniform float fFar,
out float4 outColor : COLOR
)
{
// clamp output using clip planes
float fColor = 1.0 - smoothstep( fNear, fFar, Depth );
outColor = float4( fColor, fColor, fColor, 1.0 );
}


fNear is the near clip plane for the scene fFar is the far clip plane for the scene

Yes, the position sent to the vertex shader is generally the local coordinates of the object's vertex. Your multiplication by worldViewProjMatrix in the vertex shader is what handles the transformation from world space to camera space to projection space, all in one shot.

The GPU will interpolate any out variables from your vertex shader across the face of the triangle and send them along to the fragment shader. However, if your goal is to store the depth in a texture, you will need to set the target framebuffer to the texture you want, and your fragment shader will have to write out the depth encoded into the color, something like:

outColor = float4(Depth);


As for your final question, there is sadly no easily available way to debug shaders, unless you have software similar to PIX which captures all the data running through the framebuffer (note that PIX will only work for Direct3D applications). The best advice I can offer you to debug your shader input values is to use them in your calculation of outColor in such a way that you can determine if they look correct. For example you could do:

outColor = float4(position, 1.0);


where position is output from the vertex shader as the local position of the vertex. Doing this you would expect your object to look as if it was carved out of the color cube.

• Thanks! I stumbled on gDEBugger which might be helpful for opengl debugging: gremedy.com I'm not experienced enough with graphics programming to evaluate it well yet.
– Jay
Nov 9, 2012 at 19:20
• I tried passing the position through to the frag shader and displaying it as colors. It's pretty... but has no sharp edges. I expected it to have some sharp edges where there are objects. The color should transition at the object edges but doesn't.
– Jay
Nov 9, 2012 at 22:27
• @Jay I'm not sure I follow... do you mean the background color is also changing and the objects are blending in? Nov 10, 2012 at 1:45
• I passed position from the vertex shader to the fragment shader. I used that as the output color. Since the x,y,z maps to the r,g,b color output I expected objects near the origin in the world to show as black. Things a long distance away should be fully saturated colors. It looked completely wrong. So I either did it wrong, or the position isn't correct in the vertex shader. I will be trying to log data in the shader code to see what it sends to the graphics card.
– Jay
Nov 10, 2012 at 5:51