Plan for Daniel Neilsen
by Daniel Neilsen · 02/22/2004 (5:18 pm) · 9 comments
Hi All,
Been a long long time since my last .plan so I thought I would write another because ... well ... there isnt any real good reason I guess. Just because I can!
As most of you know, I am working on the 21-6 project GravRally which is going along really well and, most recently I have been working on two areas. AI Pathfinding and Performance Improvments.
The GravRally Team is really starting to push the limits of what TGE can do (and still keep a positive fps) so over the last week I started looking into possible methods to improve fps, especially in high complex areas (forests, heavy urban environemnts, etc). After some testing, we soon realised that dif and dts models that are behind other models and completely hidden are still drawn. Only objects that hidden behind terrain (or objects not in the view cone) are excluded from the scene (occluded). I had never actually realised this before because I had never taken the time to test it but, after noticing this, it certainly explained a lot.
I started to look into possible ways to "occlude" these obbjects from the scene. TheAce in the garagegames irc channel pointed me in the right direction early on and after a few false starts and some time spent learning what the f### goes on in the scenegraph I developed a basic occlusion method that checked if each model could be individually seen. I made a small test map and it improved fps by about 30%. I couldnt believe it, It had actually worked!! I fired up one of our real maps and my fps (normally around 50) dropped to 2 fps.
Let me say right now that I dont take disappointment or failure very well so the resulting temper tantrum was not a pretty sight ;) LOL
Anyway, some discussion with others and some more testing proved that my method was great for a small number of models but, as the number increases, so does the extent of calculations and pretty soon, its not worthwhile to run this kind of occlusion testing. (Which is probably why TGE dosnt included it by default)
(Refer to left side of image 1 for an example)
So I went away and kicked a few things and decided to try another method. This method required that I group bunchs of models together into occlusion groups and, if any part of the group can be seen, the entire group is rendered. Should the group not be able to be seen, however, it is safe to occlude the whole group. This was a little more difficult bubt in the end I ended up with an "occlusion brush" object that can be added in the editor which can be placed over difs/dts's to include them in a particular occlusion group.
Image 1

After a lot of testing and tweaking I finally ended up with a system that I believe is pretty damm good. (The right side of image 1 is an example). The metrics display on the top of the following screenshots shows the fps, the ms/frame, the number of rendered and occluded difs/dts's, the number of rendered and occluded occlusion brushes and whether occlusion mode is enabled or not. I think it only fair to let the results speak for themselves on this simple example.
Image 2 - Occlusion Mode Enabled

Image 3 - Occlusion Mode Enabled - Wireframe View

Image 4 - Occlusion Mode Disabled (Standard TGE)

Image 5 - Occlusion Mode Disabled (Standard TGE) - Wireframe View

Hope you guys found this interesting :)
Been a long long time since my last .plan so I thought I would write another because ... well ... there isnt any real good reason I guess. Just because I can!
As most of you know, I am working on the 21-6 project GravRally which is going along really well and, most recently I have been working on two areas. AI Pathfinding and Performance Improvments.
The GravRally Team is really starting to push the limits of what TGE can do (and still keep a positive fps) so over the last week I started looking into possible methods to improve fps, especially in high complex areas (forests, heavy urban environemnts, etc). After some testing, we soon realised that dif and dts models that are behind other models and completely hidden are still drawn. Only objects that hidden behind terrain (or objects not in the view cone) are excluded from the scene (occluded). I had never actually realised this before because I had never taken the time to test it but, after noticing this, it certainly explained a lot.
I started to look into possible ways to "occlude" these obbjects from the scene. TheAce in the garagegames irc channel pointed me in the right direction early on and after a few false starts and some time spent learning what the f### goes on in the scenegraph I developed a basic occlusion method that checked if each model could be individually seen. I made a small test map and it improved fps by about 30%. I couldnt believe it, It had actually worked!! I fired up one of our real maps and my fps (normally around 50) dropped to 2 fps.
Let me say right now that I dont take disappointment or failure very well so the resulting temper tantrum was not a pretty sight ;) LOL
Anyway, some discussion with others and some more testing proved that my method was great for a small number of models but, as the number increases, so does the extent of calculations and pretty soon, its not worthwhile to run this kind of occlusion testing. (Which is probably why TGE dosnt included it by default)
(Refer to left side of image 1 for an example)
So I went away and kicked a few things and decided to try another method. This method required that I group bunchs of models together into occlusion groups and, if any part of the group can be seen, the entire group is rendered. Should the group not be able to be seen, however, it is safe to occlude the whole group. This was a little more difficult bubt in the end I ended up with an "occlusion brush" object that can be added in the editor which can be placed over difs/dts's to include them in a particular occlusion group.
Image 1

After a lot of testing and tweaking I finally ended up with a system that I believe is pretty damm good. (The right side of image 1 is an example). The metrics display on the top of the following screenshots shows the fps, the ms/frame, the number of rendered and occluded difs/dts's, the number of rendered and occluded occlusion brushes and whether occlusion mode is enabled or not. I think it only fair to let the results speak for themselves on this simple example.
Image 2 - Occlusion Mode Enabled

Image 3 - Occlusion Mode Enabled - Wireframe View

Image 4 - Occlusion Mode Disabled (Standard TGE)

Image 5 - Occlusion Mode Disabled (Standard TGE) - Wireframe View

Hope you guys found this interesting :)
About the author
#2
The second I have to test what is in the brush every tick it starts creating too many calcs. This system can only really be used for TSStatics and Interiors.
Basically, on mission start, I initialise the occlusion brush's and store a list of which objects are contained in these brushes to save calc time later.
02/22/2004 (6:46 pm)
It dosnt handle moving objects for obvious reasons.The second I have to test what is in the brush every tick it starts creating too many calcs. This system can only really be used for TSStatics and Interiors.
Basically, on mission start, I initialise the occlusion brush's and store a list of which objects are contained in these brushes to save calc time later.
#3
02/22/2004 (7:01 pm)
Woo! Any chance this will be released as a code pack or resource? It should really be in the codebase but no doubt many people would buy it as an addon.
#4
02/22/2004 (7:37 pm)
Eventually it will probably out as a resource but it needs to be "run in" some more before that will be occuring.
#5
02/22/2004 (7:46 pm)
I'd definitely like to help you do that. :)
#6
One question though: those occlusion groups / brushes make sense to me for trees, grass, etc., but what about partially occluded buildings in city environments and the like ...
I've read some papers about occlusion horizons, hierarchical occlusion maps etc. which illustrate the problem I'm talking about:

Do you think that would be possible with your approach?
02/22/2004 (11:17 pm)
Cool Daniel, glad you got that working! :)One question though: those occlusion groups / brushes make sense to me for trees, grass, etc., but what about partially occluded buildings in city environments and the like ...
I've read some papers about occlusion horizons, hierarchical occlusion maps etc. which illustrate the problem I'm talking about:

Do you think that would be possible with your approach?
#7
Anyway, one of the things I recall about this, is that in general, its better to not just have all objects as occluders, but just the larger objects.
Dan, ok, here's another issue. When you come round the corner of your wall above, youre going to hit a frame-rate barrier, as the large brush your grass is in becomes visible at the edges. How are you going to handle that??
02/23/2004 (12:12 am)
That looks like some kind of edge detection thing beffy.. Silouette all occluders..Anyway, one of the things I recall about this, is that in general, its better to not just have all objects as occluders, but just the larger objects.
Dan, ok, here's another issue. When you come round the corner of your wall above, youre going to hit a frame-rate barrier, as the large brush your grass is in becomes visible at the edges. How are you going to handle that??
#8
Yes you could alter the scenegraph using vector calculations rather than a ray cast method such as I am doing. The problem is that you have to make sure that doing the calculations to test all of the models in the view cone (In a forest with a vis distance of 500 you could be looking at 700-1000 models!!) are faster than actually rendering the object itself.
That could be very tricky. The is an opengl function in new cards called occlusion_query which returns how many pixels of a shape are actually rendered on the screen and this can be used to occlude models. (At least theoretically I believe this is possible, any opengl experts care to comment?)
I didnt go there for two reasons.
1) I know buggar all opengl
2) We wanted to support older cards as well (Idealy)
@Phil
It is a good point and there is a substantial amount of tweaking that the level designer has to do to get this system to work successfully. The example above shows a single brush containing over 150 trees where, in reality, you would probably use 3 brushes each containing 50 trees.
Admittedly the fps will drop slightly as you move around the corner but there is a good chance that another brush that was previously in the viewcone is now occluded so will cancel the change out. Worst case, we have the lessor of the two evils where the fps drops slightly cause an extra 50 models are being rendered but its better than not having any occlusion which would be lot of extra models.
This method is certainly not useful for every purpose. Trying to use this method to occlude large buildings just would not be worthwhile as, from my testing, you need about 5-10 models in a brush to make the fps increase worthwhile. But, if you are looking at an urban cityscape situation. You might not occlude all the buildings, but all the lampposts, park benches, rubbish tins, etc, etc, etc can all be chopped out of the render real easy when they are behind other buildings.
02/23/2004 (3:30 am)
@Stephen:Yes you could alter the scenegraph using vector calculations rather than a ray cast method such as I am doing. The problem is that you have to make sure that doing the calculations to test all of the models in the view cone (In a forest with a vis distance of 500 you could be looking at 700-1000 models!!) are faster than actually rendering the object itself.
That could be very tricky. The is an opengl function in new cards called occlusion_query which returns how many pixels of a shape are actually rendered on the screen and this can be used to occlude models. (At least theoretically I believe this is possible, any opengl experts care to comment?)
I didnt go there for two reasons.
1) I know buggar all opengl
2) We wanted to support older cards as well (Idealy)
@Phil
It is a good point and there is a substantial amount of tweaking that the level designer has to do to get this system to work successfully. The example above shows a single brush containing over 150 trees where, in reality, you would probably use 3 brushes each containing 50 trees.
Admittedly the fps will drop slightly as you move around the corner but there is a good chance that another brush that was previously in the viewcone is now occluded so will cancel the change out. Worst case, we have the lessor of the two evils where the fps drops slightly cause an extra 50 models are being rendered but its better than not having any occlusion which would be lot of extra models.
This method is certainly not useful for every purpose. Trying to use this method to occlude large buildings just would not be worthwhile as, from my testing, you need about 5-10 models in a brush to make the fps increase worthwhile. But, if you are looking at an urban cityscape situation. You might not occlude all the buildings, but all the lampposts, park benches, rubbish tins, etc, etc, etc can all be chopped out of the render real easy when they are behind other buildings.
#9
Things like large occluders etc.
Also, how about some kind of visibility graph? instead of the normal scene graph, or the box raycast thing, why not try a visibility graph, which can pre-process the level into some kind of quadtree? I always disliked the quadtree's because of theier worst-case performance looking across the level on the diagonals, but they would be better than doing some manual brush placement (I would expect).
I'm sure there's a load of info on these things, but hey, if youre solution works well enough for the game :) thats what counts.
02/23/2004 (4:35 am)
Well, there's been a lot of research papers on this subject, I'd suggest doing a bit of digging :)Things like large occluders etc.
Also, how about some kind of visibility graph? instead of the normal scene graph, or the box raycast thing, why not try a visibility graph, which can pre-process the level into some kind of quadtree? I always disliked the quadtree's because of theier worst-case performance looking across the level on the diagonals, but they would be better than doing some manual brush placement (I would expect).
I'm sure there's a load of info on these things, but hey, if youre solution works well enough for the game :) thats what counts.

Associate Kyle Carter
How do you handle objects moving from one brush's area to another?