Jump to content
  • Advertisement
Sign in to follow this  
lipsryme

Calculating Screen-Space Depth help

This topic is 2121 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm rendering sphere's as billboards using the cpu.

They are being rendered to the screen in a loop that basically interpolates the x and y position over the sphere using center and radius like this:

    const int width2 = Width / 2;
    float center_X = ScreenX*width2 + width2;
    float center_Y = ScreenY*width2 + width2;

    float RX = Radius_SS*width2;
    float RY = Radius_SS*width2;

	  for(int x = center_X-RX*2; x <= center_X+RX*2; ++x)
	  {      
		    for(int y = center_Y-RY*2; y <= center_Y+RY*2; y++)
		    {
                       const unsigned int index = x + y * Width;
                       ...

What I now want to do is emulate a kind of z-Buffer so that it eliminates overdraw.

I've been trying for a while now but I have no clue how to calculate the actual depth for each interpolated pixel value. The only thing I have is the SS depth of the center of the sphere.

Edited by lipsryme

Share this post


Link to post
Share on other sites
Advertisement

My first thought:

 

Start at x = -r and travel towards +r.

 

Compute the range of y values to iterate at a given x.  When z=0 you are just using the X-Y plane.  So your y range for a given X:  y = +/- srqt(r^2 - x^2).

 

Finally at a given x,y pair simply use Pythagoras to compute your depth.  z = sqrt(r^2 - x^2 - y^2).

 

Pseudo-code:

 

Edit:  This is for a sphere oriented at the origin.  You'll have to use offsets for spheres moved elsewhere.

for( x = -r; x <= r; ++x )
{
    upp_y = floor(sqrt(r^2 - x^2));
    low_y = -1 * upp_y;
    for( y = low_y; y <= upp_y; ++y )
    {
       z = sqrt(r^2 - x^2 - y^2);
    }
}
Edited by Cosmic314

Share this post


Link to post
Share on other sites

First of all thanks for the post but I'm a little confused as to how I convert the code you posted to my loops wacko.png

Do you mean to replace the condition in my loop with the ones you've got there ? Is there a way around that ?

Edited by lipsryme

Share this post


Link to post
Share on other sites

I guess I need a little better understanding of what your variables represent.  But basically, if you already know which x,y pairs are on your translated sphere, then the depth is simply by Pythagoras:  (You call it 'index' for z, I believe)  index = sqrt(r^2 - (x-xcenter)^2 - (y-ycenter)^2).

Edited by Cosmic314

Share this post


Link to post
Share on other sites

Sorry no index is the index in my "framebuffer" array. So basically the pixel (flattened 2D array [width*height]) that should be written to.

So the z value (if x,y and radius in screen space is known) is z = sqrt(r² - (x-xcenter)² - (y-ycenter)²) ?

But is that correct for the "global" depth value inside the scene (towards +Z) and not the depth from the sphere center ?

 

edit: This doesn't seem to work, my sphere's look like someone cut around them if I cull based on that z value.

like so: http://d.pr/i/v05n

Edited by lipsryme

Share this post


Link to post
Share on other sites

oic.

 

Yes, I believe your depth is the 'z' computed value, assuming object towards the viewer are positive.  I assume the circle which represents the sphere is a post-translated world-space to screen space.

 

However, where I'm confused is how you determine the positioning of your sphere in 3D space.  Don't you also need to know offset of the depth for where you place the billboard?  The equation I gave would assume the billboard depth is at 0.  If it's at some other number you'd have to had the depth of the billboard to it.

Share this post


Link to post
Share on other sites

My sphere's are predefined with x,y,z coordinates.

They are then transformed (rotation) and then offset by some amount so they are in front of the viewer.

And after that transformed to screen space like so:

float X_SS = X / Z;
float Y_SS = Y / Z;
float Z_SS = Z;

Share this post


Link to post
Share on other sites

If I understand your problem correctly, you use a billboard (a flat object) to represent the sphere.  It would mean that the Z value for your translation to SS would be fixed for the billboard (for any given X,Y pair that is on the billboard).  For depth testing you want to find the adjusted Z value as if the billboard were replaced by a spherical object.

 

With your billboard Zoff as the base offset, your new Z computation would become:  Z = sqrt( R^2 - X^2 - Y^2) + Zoff.

 

Your above equation would become:

float Z_SS = sqrt(R**2 - X**2 - Y**2) + Zoff;
float X_SS = X / Z_SS;
float Y_SS = Y / Z_SS;
Edited by Cosmic314

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!