• Advertisement
Sign in to follow this  

none issue when near plane = 0.01, is it just matter of time when I see artifacts?

This topic is 837 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

Hi

When I use near plane as 1

D3DXMatrixPerspectiveFovLH(&d3d::MatProj, D3DXToRadian(90), 4.0f/3.0f, 1, 1000);

then I don't have artifacts (z buffer works OK at least in current stage of project) but I have issue when moving camera. When I am closing to the object then object is clipped and the result is as in the attached picture.

When I change near plane to 0 then there are some artifacts.

When I change near plane to 0.01 then there is none any issue visible (none artifacts, none clipping object before camera). I would use this solution however there is opinion in website society that near plane shouldn't be less than 1. So what is another fix to my camera issue or I shouldn't search any other soluation just use this one if I don't observe any problem?

 

FYI:
What I might say more is that when I draw triangle on another triangle (for example some indicator on the grass surface) then I use below code (my graphic card support depth bias), near plane isn't set to 0.01 - I am writing this additional information just to exclude from the above concerns this particular case.

D3DXMatrixPerspectiveFovLH(&d3d::MatProjZFight, D3DXToRadian(90), 4.0f/3.0f, 1, 1001); //for Z-Fighting based on projection matrix solution

                if(d3d::depthBias)
                {
                    DWORD x = d3d::FtoDw(d3d::DEPTHBIAS);
                    // Used to determine how much bias can be applied
                    // to co-planar primitives to reduce z fighting
                    // bias = (max * D3DRS_SLOPESCALEDEPTHBIAS) + D3DRS_DEPTHBIAS,
                    //where max is the maximum depth slope of the triangle being rendered.
                    pDev->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, d3d::FtoDw(d3d::SLOPESCALEDEPTHBIAS));
                    pDev->SetRenderState(D3DRS_DEPTHBIAS, d3d::FtoDw(d3d::DEPTHBIAS));
                }
                else
                    pDev->SetTransform(D3DTS_PROJECTION, &d3d::MatProjZFight);
Edited by anders211

Share this post


Link to post
Share on other sites
Advertisement

The value of near plane is irrelevant on its own - what matters is the relative magnitude of the near and far plane to each other.

 

Set far plane as low as you can without issues. Then near plane as high as you can without issues.

 

If theres no issues, everything is fine.

 

If there still is issues, you need to do something else in addition to simple depth testing to deal with the cases where it isnt working (like doing multiple passes for different depth ranges to increase precision withing each range, or depth biasing like you have).

Edited by Waterlimon

Share this post


Link to post
Share on other sites

The value of near plane is irrelevant on its own - what matters is the relative magnitude of the near and far plane to each other.

This. Say your units are in meters.
Near=0.1 (10cm) and Far=1000(1km) would be completely normal.

Now say your units are millimeters - for the same situation youd use Near=100(10cm) and Far=1000000(1km) -- those values will work just as well, because the ratio between them is the same.

There's nothing magic about the number 1.0 when it comes to the near plane.

These days, lots of engines actually reverse their depth coordinates and use, e.g. Near=1000 and Far=0.1 :lol:

Share this post


Link to post
Share on other sites

The value of near plane is irrelevant on its own - what matters is the relative magnitude of the near and far plane to each other.

While true, a slight change on the near plane has a much higher precision improvement than a big change on the far plane. I wish I had the numbers at hand, but it was something like you get much more precision from raising the near plane from 0.1 to 1 than from lowering the far plane from 10.000 to 1.000

As for depth precision improvements, see
https://developer.nvidia.com/content/depth-precision-visualized
http://outerra.blogspot.com.ar/2012/11/maximizing-depth-buffer-range-and.html

Share this post


Link to post
Share on other sites

The value of near plane is irrelevant on its own - what matters is the relative magnitude of the near and far plane to each other.

While true, a slight change on the near plane has a much higher precision improvement than a big change on the far plane. I wish I had the numbers at hand, but it was something like you get much more precision from raising the near plane from 0.1 to 1 than from lowering the far plane from 10.000 to 1.000

Yes and no.

If you multiply both near and far by the same value, there's no change in precision, as the ratio is unchanged.
e.g. in my above example where we go from meters to milimeters, with 10cm and 1km near/far values, assuming a 24bit depth buffer:
In meters (n/f = 0.1/1000 units), an object at 500m (500 units) has a depth precision of 0.149 units (14.9cm).
In millimeters (scale = 1000, so n/f = 100/1000000 units), an object at 500m (500000 units) has a depth precision of 149 units (still 14.9cm).
 
If you're adding a value to near and far, then yep, changing near has a massive difference compared to changing far.
Changing near from 0.1 to 1.1 will give ~tenfold more precision than changing far from 1000 to 999 will do for you, as it has a ~tenfold greater impact on the ratio comparatively.

Share this post


Link to post
Share on other sites

Actually what I meant is that when your original was [0.1; 10000]; you get more precision by doing [1; 10000] than by doing [0.1; 1000] if you still work on the same scale (i.e. you always remain on meters). This is unintuitive as in one you increase the near plane by 10x, and in the other you decrease the far plane by 10x. The ratio f / n is the same. It should have the same precision. But it does not.
 
From the NVIDIA link:

Pulling in the near plane will make the d range skyrocket up toward the asymptote of the 1/z curve, leading to an even more lopsided distribution of values (...)
Similarly, it's easy to see in this context why pushing the far plane all the way out to infinity doesn't have that much effect. It just means extending the d range slightly down to 1/z=0:

 

If the scale is also changed (i.e. from meters to centimeters) then precision should always remain the same (ignoring for one second that 32-bit floats have horrible precision at 1.000.000 cm than they do at 10.000 m; but that's another issue).

Share this post


Link to post
Share on other sites

I guess the question is, if I have the near plane to 1.0 and far plane to [whatever], what would be the appropriate scale to use? 1 unit = 1 meter? 1 unit = 1 centimeter?

Share this post


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

  • Advertisement