Dynamic impostors

Hi, I’m trying to implement a very specialized sphere shader which draws a properly lit sphere on a quad.

I’ve managed to draw a circle on the quad, but I’m having extreme difficulties with changing the fragments’ depths.

Does anyone know how to “pull” a fragment an exact distance in world coordinates?

Here’s what I have done so far in order to draw a circle:

  • draw all four vertices at the center of the sphere
  • for each vertex, send two attributes named ‘x’ and ‘y’ which each have values of -1 or 1.
  • in the vertex shader, push each vertex out in the x and y directions based on the ‘x’ and ‘y’ attributes. Also, copy the ‘x’ and ‘y’ attributes to varying variables, which will provide the fragment shader with positional information for its lighting calculations.
  • in the fragment shader use the varying ‘x’ and ‘y’ variables to draw the circle (disposing fragments that are outside of the circle), calculate lighting and depth.

Again, I can’t seem to figure out how to correlate fragment depth with the world coordinate system.

Depth is non-linear, so the exact transform of depth is dependant on the location in world space.

I’d suggest sending the model-view-projection matrix and the inverse model-view-projection matrix along to the fragment shader, and do something like this: (if you’ll pardon the horrible pseudo-code)

tmp = fragment_location * inverse_modelviewprojection_matrix;
tmp = makeSphere(tmp);
fragment_location = tmp * modelviewprojection_matrix;

There’s probably another way, but the logic required to deal with the non-linear nature of the depth buffer would probably take more time to execute than a couple of matrix multiplies.

I just tried this, but it doesn’t look like gl_FragCoord is an eye space coordinate.

To test this, I used the following code to test whether the clip space (terminology?) coordinate in the vertex shader had the same z value as the fragment coordinate (depth) in the fragment shader.

The effect is that, if the clip coordinate’s z value (as calculated in the vertex shader) is within a small range (±0.1) of the fragment depth, the color is set to white. Otherwise, it is set to blue.

Most of the “spheres” were blue, but some turned white as I moved the camera.

Any idea how to correlate the fragment (window?) coordinate to eye coordinates so that they can be translated back to world coordinates?

Vertex shader:

  
varying vec4 clipCoord;

void main()
{	
   ...
       clipCoord = ftransform();
   ...
}

Fragment shader:

varying vec4 clipCoord;
	
void main()
{
   ...
	if( clipCoord.z < gl_FragCoord.z - .1 &#0124;&#0124; clipCoord.z > gl_FragCoord.z + .1) {
		gl_FragColor = vec4(0.0,1.0,1.0, 1.0);
	} else {
		gl_FragColor = vec4(1.0,1.0,1.0, 1.0);
	}
   ...
}

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.