High speed rendering of distant objects

Community Forums/Showcase/High speed rendering of distant objects

sswift(Posted 2003) [#1]
Take a look at this image taken from one of my terrains...



Notice anything funny?

I'll give you a hint. That terrain is one kilometer wide. It is comprised of an 8x8 grid of tiles, each of which has a grid of 32x32 discreet heights, making for a total of 2048 polygons per tile, and 131,072 total polygons.

There is no level of detail management going on here... distant tiles have the same number of polygons as tiles nearby. Yet you can clearly see that the polygon counter says that less than 30,000 polygons are visible and the framerate is exceptionally high.

You might also notice on close inspection that the terrain in the distance appears out of focus.

What I have done is created a system which can take any 3D scene, and render the stuff in the distance to textures, which can are then used in place of said objects until such time as they become out of date.

In other words, you can walk to those mountains in the distance, and there will be no detail popping. And, because I've gotten rid of level of detail management, all the textures on the ground can be very high-res and use splatting with vertex alpha, which is pretty much impossible to do if you've got any kind of LOD management on the terrain. In addition, lighting informantion can be baked into the vertex data instead of requiring a seperate lightmap, and as a result the lighting can be fairly detailed.

I have not yet implemented any kind of texture splatting, or specialized lighting routines, as I've just gotten the rendering working, and there's still some issues to be ironed out. Namely a dramatic drop in speed when one actually walks around versus simply looking in any direction. What I need to do is put in some code to manage the texture rendering so that it doesn't render textures unneccesarily, and some code to blend between updates so that I can update less often than once every four meters.

But so far it looks really cool and I'm happy with how it's progressing. I was inspired by Zelda: WInd Waker, Mario Sunshine, and Conker's Bad Fur day, each of which appear to render objects in the distance with a method similar to this, switching to polygons only when you get near enough for it to make a difference. I may add a heat-shimmer effect as well because that may serve to hide any artifacts which still may be visible, and increase the apparent resolution of the background.... ie, hide pixelation.


Ricky Smith(Posted 2003) [#2]
Awesome !


Binary_Moon(Posted 2003) [#3]
AFAIK This is how they done the infinite polygon engine in Republic. I don't think they used a texture but a buffer that didn't get cleared until you move far enough.



So is this going to come with your terrain system :) ?

I think as long as you don't use an insane screen resolution the pixelation of distant terrain won't matter too much anyway. What you show above looks ok. It gives a sort of depth of field effect.


sswift(Posted 2003) [#4]
"So is this going to come with your terrain system :) ?"

This is part of a complete rewrite of my terrain system, and I wouldn't hold my breath waiting for it (the new terrain system) because I don't know if I will complete it anytime soon. When it is completed it will be a seperate product from my current terrain system, leaving the old system obsolete.

I may license this technology seperately for less, depending on how plug and play it turns out to be. As it currenty is, it's very simple to use. You don't even have to pass it a list of entities.

...

As for Republic... I dunno. I don't see much bluriness in that image, so it doesn't really seem like it's using impostors.

I suspect they are using a combination of models with varying levels of detail, and displacement maps which are used to deform flat surfaces as you approach to make them appear more detailed.


Binary_Moon(Posted 2003) [#5]
"and I wouldn't hold my breath waiting for it"

As I told you the other day. I am making a top down game next so it wouldn't be much use for me anyway, I just wondered if you would be selling uit or if you were using it in your own game.

"As it currenty is, it's very simple to use. You don't even have to pass it a list of entities."

Hows that work then? You're using the camera range to render the distant stuff, and then swapping back to a close range to do the nearby stuff.

As for Republic... I'm sure its something along those lines, I'm trying to remember where i read the article about it.


sswift(Posted 2003) [#6]
"Hows that work then?"

Anchient Chinese secret!


CopperCircle(Posted 2003) [#7]
Looks interesting, id like to see a demo.


(tu) ENAY(Posted 2003) [#8]
> Anchient Chinese secret!

Rice?


sswift(Posted 2003) [#9]
Customer: How do you get your shirts so clean, Mr. Lee?

Mr. Lee: Ancient Chinese Secret.

Mrs. Lee My husband, some hot shot. Here's his ancient Chinese secret. Calgon. Calgon's two water softeners soften wash waters so detergents clean better, In hardest water, Calgon helps detergents get laundry up to 30% cleaner. [yelling] We need more Calgon!

Customer: [to Mr. Lee] Ancient Chinese Secret, Huh!

Announcer: Calgon helps detergents get laundry up to 30% cleaner.

--1972 Calgon TV Commercial


Warren(Posted 2003) [#10]
If you have to explain the joke, it isn't worth it.


sswift(Posted 2003) [#11]
:-)


MadJack(Posted 2003) [#12]
I suspect Swift's rendering with a cam range set to something like 1024 near focus to 2048 far focus, in a reduced window, copying to a sprite, rendering a second cam at fullscreen with the sprite set to entityorder 1, so that it's rendered behind everything else.


Pepsi(Posted 2003) [#13]
Pretty impressive sswift... also would like to see a demo of it in action.


sswift(Posted 2003) [#14]
Madjack:
You are basically correct, as was binarymoon who suggested something similar.

What I do is render six images, one for each side of a skybox, with the camera range for the regular camera set to some low set of values, and the camera range for the distant camera set to some range that starts just before the near camera cuts out.

But I also store the location the image was rendered from, in order to determine how much the image might have changed, so I can render it only when neccessary.

The sky is included in the distant image, and the new skybox replaces it. It's entity order is set such that it rendered first, behind everything else.

I'd post a demo, but I've got most of my web space filled up with stuff I can't delete, and it's not yet ready for prime time because right now it's slow.

I need to figure out a way to speed it up. Rendering one side at a time will only help out a little. I need to find a way to render less than one side each time. Also, it would be beneficial if when I copied to the texture the alpha information in the image was retained. It currently is not, and I'm pretty sure that if I tried to copy it manually it would be too slow and would not work well.


Koriolis(Posted 2003) [#15]
It seems good. When I tried to do some exotic tiling terrain system, I used tricks of this way. And in the end I faced the same speed problem as you (as well as problem with the alpha not being retained, knowing that anyway it would maybe not a good idea to rely on the framebuffer having 32 bits of color depth). The main problem in the end for me was the mipmapping: I needed to have mipmap on, but each time I copied from the framebuffer to the texture this damd Blitz recreated the lower mipmap levels, very slowly and not in a way I could hide it (it tends to lock up the rendering). If we could set all the mipmappings levels ourselves, I'm pretty sure the overall system would be fast enough.
Anyway, you maybe don't need to have mipmapping on at all for your generated skybox (as its resolution is smaller than the screen resolution, and the maximum angle from which faces are seen shouldn't be too high). So if it's currently on, try to deactivate it and see if it helps. If it's not, well, sorry for this blabla :)


Tom(Posted 2003) [#16]
sswift, cool idea.

Don't you code in C at all? I would have thought someone with your knowledge would, and could put it to use speeding up some of your ideas.

Tom


sswift(Posted 2003) [#17]
Koriolis:
Disabling mipmapping has no effect on the speed.

Tom:
I used to code in C, but I never did like C, and I stopped programming in it years ago. I looked at getting back into programming in C a few years ago, but in order to do anything in Windows you really need to know C++ since all the example code and documentation refers to C++ stuff. I like C++ even less than I like C. So I never got into programming in DirectX in C beyond some very basic example programs.

I always prepferred Pascal to C, and Blitz is a lot more like Pascal than like C.


Jager(Posted 2003) [#18]
looks exciting sswift, good luck.


podperson(Posted 2003) [#19]
Neat stuff Sswift. I'd assume that worst case you need only render three sides of the skybox.

A simple system for reducing re-rendering. Move the skybox with the character until the character has moved a threshold distance. (Or had you thought of that already?)


Rob Farley(Posted 2003) [#20]
Very cool Shawn...

May I suggest a way of reducing the amount of renders would be to move the skybox as te cam moves it as the cam moves, ie, if you move the cam in a +X direction move the skybox in a -X direction, this way you'll get the background scaling the correct amount and maybe you won't need to render so often. You might have to make the skybox bigger to compensate for it off-setting though.

And as Podperson suggested you don't need to render behind you. But you already knew that!

Oh one more thing, you could still do you vertex splatting if you had a fixed LOD if you wanted to reduce the poly count further.

Just thoughts... looking really good though.


Koriolis(Posted 2003) [#21]
As a skybox, of course it is centered aroudn the camera (if you prefer, it moves with the player). Also the real intent of all this is of course not to render far polygons each frame, but to use a threshold. If the skybox was rendered every frame it would be a real non-sense, as you would in the end render as much as polygons as you would without this system, with the overhead of copying from the frambuffer to the skybox textures, and having mre renderworlds (to create the content of these textures)!
So yes, Podperson and Dr Av, it uses a threshold :)
Now for the idea of rendering only 3 sides in the worst case, this is maybe a good idea, but I think there are problems with that.
To be efficient and not having moments where the game is really slow, the ideal would be no to render more than 1 face by frame (in fact the ideal is to render far less per frame). Meaning at a frame the system could be rendering a face, 5 frames later, another face, and so on. If you only render 3 faces of the skybox, what happens if the player suddenly turns the camera from 180°?
1) The system updates the faces in the back, which means it will suddenly be slow and then be smooth again. Not good at all IMHO (and against the idea of the whole system).
2) The system keeps working as usual (rendering a face each 'N' frames). So for a while you'll see empty box faces (or rather faces fulled with "garbage" content, which corresponds to the way the world looked the last time you have looked in this direction).

So even if you don't look back the system should update the back faces along with the others, to be be ready when the user look back suddenly.

@SSwift: hem, tell me if I'm wrong on something, I'll shut my mouth. These are just my personal thought on the subject, as it's been a while since I'm thinking of doing such a system for taking benefit of frame to frame coherency.


sswift(Posted 2003) [#22]
"May I suggest a way of reducing the amount of renders would be to move the skybox as te cam moves it as the cam moves, ie, if you move the cam in a +X direction move the skybox in a -X direction, this way you'll get the background scaling the correct amount and maybe you won't need to render so often."


I already tried that, and for some reason it works terribly. In fact, the rendering seems to go wild and the image on the skybox jumps around like mad. I don't understand why that was occuring. I would think it was a bug, but I looked over my code a hundred times and I couldn't figure out what was going wrong.

What I did was I turned off skybox moving unless the skybox image was updated, and the image was updated evert few meters just as before. But for some reason when I would walk up hills all of a sudden the sky could turn black or shift downward suddenly. This happened even if I only moved a little bit away from the point where a render last occured. I can't for the life of me understand why it would do that.


"And as Podperson suggested you don't need to render behind you. But you already knew that!"

Well I have not actually implemented code to render only in specific directions mainly because it would still be too slow, so there's no point in optimizing that.

One method I have been considering is to somehow render smaller slices. Instead of rendering four sides of a cube, I would instead render the sides of a cylinder, which could have many more sides than the cube, so I could render much smaller sections of distant detailed terrain each frame.

Also, one thing I might do is combine multiple renders into a single texture building the texture up over time intead of rendering a whole texture at once. So even if I rendered to an 8 sided cylinder, I could divide that rendering up into an arbitrary number of render slices and render each side texture in 16 thin slices. Because only the texture needs to be square, not the render window.


JustLuke(Posted 2003) [#23]
Mr. Sswift, you sir are a liar.

Since I live in China I decided to find out about this "Ancient Chinese Secret" for myself.

I walked down the road and asked a wrinkly, wise-looking, old Chinese man about the secret of high speed terrain rendering. At first he looked confused by my english questions, so I decided that maybe I needed to talk more slooowly and LOUDLY. This made him angry. I repeated my questions once again, this time accompanied with wild gestures. His anger turned to fear.

Eventually I gave up, bought a watermelon from his cart and returned home none the wiser. Chinese secret... Yeah, right!


sswift(Posted 2003) [#24]
Was it one of those cool cubic watermellons like the ones which you can purchase in Japan because they fit in their tiny refrigerators better?

I want a bicubic watermellon.


JustLuke(Posted 2003) [#25]
Nah, it was a Chinese Watermelon - Covered in spit and with a crispy toxic pesticide coating. Ideal for underpowered Chinese refrigerators that don't keep anything fresh. Frankly, being left to rot away uneaten is the best thing for it.

Mmm... Hypercubic Watermelon. *drool*