Advertisement

How to get really long draw distances?

Started by January 14, 2020 03:15 AM
12 comments, last by Hodgman 4 years, 10 months ago

[C++][raw DirectX11]

I'm working on my engine atm and was wondering what is the best way to achieve really long draw distances. The longer the better, like I'd like to be able to see pixel sized objects. (Maybe not that long but I'd like to play around with it) (Also the performance is not an issue because everything is extremely low rez). The problem is that at the moment even on a small terrains I'm already hitting the camera's far plane. I know I can just increase the far plane but I've heard it could cause z battling (where the far objects pop in and out) if the far plane distance is too far from the near plane. I also know I can decrease the size of the world, but I wasn't sure if that is the correct approach either. As of the moment my “large” terrain is only about 100x50 game units. So if I want to increase the view distance by a 1000 I would have to decrease the world size by 1000 so I'd be working with tenths and hundredths of a single unit. I'd also have to scale all the move speeds by that factor as well. Can't such small numbers have a negative impact on things like physics calculations and such?

You didn't come into this world. You came out of it, like a wave from the ocean. You are not a stranger here. -Alan Watts

Move out the near plane as far as possible. Even small amounts can make a huge difference.

World scale make no difference. Everything gets squeezed down to NDC. Although floating point errors can become more noticeable.

🙂🙂🙂🙂🙂<←The tone posse, ready for action.

Advertisement

fleabay said:

Move out the near plane as far as possible. Even small amounts can make a huge difference.

What do you mean? Moving the near plane away will increase the view distance? Also isn't there a default limit it should be set to anyway, since I'll just start clipping through objects at some point when I get close to them?

You didn't come into this world. You came out of it, like a wave from the ocean. You are not a stranger here. -Alan Watts

A single ‘unit’ in your game seems really large to me - common choices might be 1.0 in world-space is 1mm, or more commonly 1m. This gives you good-enough floating-point precision for worlds that are many kilometers in size.

If you're having issues with near/far clipping planes and precision, I would suggest ensuring you're using a 32-bit depth format and using a reverse-Z depth buffer (see https://developer.nvidia.com/content/depth-precision-visualized).

From a performance perspective, achieving long draw distances is generally done by aggressive Level-of-Detail schemes for far-away objects with heavy use of instancing and simple materials.

@Valakor I don't know, I don't really have mapping of world units to metric system. I just use default “units” that DirectX has if that makes sense. Also I'm not having any difficulties with precision at the moment but I just wanted to make sure I'm doing it the right way. So I can just set the far-plane to a really large number and not worry about it as long as I use 32 bit depth buffer with reverse Z?

You didn't come into this world. You came out of it, like a wave from the ocean. You are not a stranger here. -Alan Watts

I wouldn't set it to some arbitrarily large number - it should really only be as large as the furthest distance you expect someone to be able to see in your game. If you did use metric/imperial units, that might be something like 10Km as an example. Many (most?) games cover up the lack of really, really far objects with a skybox or similar that technically is at an ‘infinite’ distance away.

Advertisement

Valakor said:

I wouldn't set it to some arbitrarily large number - it should really only be as large as the furthest distance you expect someone to be able to see in your game. If you did use metric/imperial units, that might be something like 10Km as an example. Many (most?) games cover up the lack of really, really far objects with a skybox or similar that technically is at an ‘infinite’ distance away.

So how do I coordinate that? I'd like the view distance to be as far as possible, so as long as an object can be resolved to at least one pixel I'd like to be able to see it. How should I calculate my distances?

You didn't come into this world. You came out of it, like a wave from the ocean. You are not a stranger here. -Alan Watts

This is not possible to say, because you have to render the object to get it's size in pixels in the screen to render the object … wait, infinity loop,

Instead set your far plane as far as you whish should work and when updating the camera, just test objects far away to see what LOD level you need is the best option you have. Maybe you can handle it via the LOD level and set your objects to be invisible at certain distance. This is also more dynamic then just saying "the object has to be visible at least one pixel".

LODs however have to be made by an artist or designer so they can decide case based how far the objects is visible

You can either use a 32 bit depth buffer (as suggested above) or you can render the scene with two (or more) cameras with cascaded near and far planes, and combine them in one final pass.

Also keep in mind (for realism) that air is not a perfectly transparent medium and also the human eye does not have infinite depth of field. Some fog and some blurring at distance will make the image more realistic.

I'm with @shaarigan , LODs are your friend (if you want huge draw distance with high numbers of objects).

On another thought; it also depends on the nature of the world/scene, if it's outdoor, with 100s of meters dirt ground and some mountains far away, it's quite different then being in a dense NY sized city ?

I guess it all comes down to thinking ahead and making the best fit plan/ approach for that use-case.

Crealysm game & engine development: http://www.crealysm.com

Looking for a passionate, disciplined and structured producer? PM me

This topic is closed to new replies.

Advertisement