Scene Graph
Moderator: Moderators
Scene Graph
Hi,
Right now, getting scenes that make use of bitmaps with alpha channels or semi-transparent materials to appear on the screen the way you want is quite a painful undertaking, especially in 3d games ( where the camera doesn't always have the same direction ). A simple scene graph that sorts models ( ideally you could also choose mesh .. or triangle .. and if you want to go all out; real-time splitting for intersecting triangles ) depending on their z-depth before rendering would help significantly.
I'm aware that this has been mentioned before some time, and that it requires the OnRender components to be stored in a cue instead of being directly executed .. so I understand it's easier said then done.
K
Right now, getting scenes that make use of bitmaps with alpha channels or semi-transparent materials to appear on the screen the way you want is quite a painful undertaking, especially in 3d games ( where the camera doesn't always have the same direction ). A simple scene graph that sorts models ( ideally you could also choose mesh .. or triangle .. and if you want to go all out; real-time splitting for intersecting triangles ) depending on their z-depth before rendering would help significantly.
I'm aware that this has been mentioned before some time, and that it requires the OnRender components to be stored in a cue instead of being directly executed .. so I understand it's easier said then done.
K
- jph_wacheski
- Posts: 1005
- Joined: Sat Feb 16, 2008 8:10 pm
- Location: Canada
- Contact:
Dynamic too !
just noticed this article on the subject;
Dynamic Scene Graphs sound even more fun
http://www.gamedev.net/reference/progra ... namic3Dsg/Extending a scene tree to a scene graph allows us to create fractal-like objects with infinite details. In games, this means objects like trees or plants can be defined that have infinite detail. It allows the construction of unique worlds that would have otherwise been impossible to construct, such as worlds with the world contained in itself all over again. Some of the implementation details required for a true scene graph to be feasible will also be useful in their own right, allowing for massive scenes including objects of vastly differing magnitudes. Imagine zooming out from a leaf, to a tree, to a landscape, to a planet, to a solar system, and then to the entire galaxy, seamlessly.
Dynamic Scene Graphs sound even more fun
iterationGAMES.com
Hi jph,
LOD ( Level-Of-Detail ) type solutions as part of a Scene Graph can be quite useful / powerful. Thing is, you can already do this quite easily* yourself. I've used it in ZGE on several occasions.
However, sorting the render order of Models from furthest away to closest to camera is currently impossible ( while you probably want this to be the default ).
K
*One of the changes I made in the source to make this easier, is to change the integer properties of Mesh Component to casted floats ( since integers can't be accessed through ZExpressions ). Alternatively you could just use several static LODs.
LOD ( Level-Of-Detail ) type solutions as part of a Scene Graph can be quite useful / powerful. Thing is, you can already do this quite easily* yourself. I've used it in ZGE on several occasions.
However, sorting the render order of Models from furthest away to closest to camera is currently impossible ( while you probably want this to be the default ).
K
*One of the changes I made in the source to make this easier, is to change the integer properties of Mesh Component to casted floats ( since integers can't be accessed through ZExpressions ). Alternatively you could just use several static LODs.
Oh, and a procedure in the scenegraph ( or component ) that checks whether or not a model is within the View Frustum would be a huge performance savior. Of course you can do this using ZExpressions yourself ( and I am ), but I'm sure nobody wants to have their framerate hog over meshes that don't even appear on-screen. You can find some documentation here.
K
Just some thoughts:
For mesh-culling there is the problem of actually knowing the models dimensions. Maybe we could add two properties to a model: UseCulling, and CullingRadius. The radius would need to be set by the developer so that it always is enough to embed the model in a sphere for a quick and easy culling test.
About the render-order we would need a way of controlling this, perhaps with a RenderOrder property on Application: Unordered (like today) or ZOrder. That way games that does not need z-correct ordering can turn it off and not pay the extra cpu-time needed for sorting.
And of course for both these features (like all zge-features) we need to find robust, small and cpu-efficient algorithms. Let's keep this thread open for discussions on how we can implement this.
For mesh-culling there is the problem of actually knowing the models dimensions. Maybe we could add two properties to a model: UseCulling, and CullingRadius. The radius would need to be set by the developer so that it always is enough to embed the model in a sphere for a quick and easy culling test.
About the render-order we would need a way of controlling this, perhaps with a RenderOrder property on Application: Unordered (like today) or ZOrder. That way games that does not need z-correct ordering can turn it off and not pay the extra cpu-time needed for sorting.
And of course for both these features (like all zge-features) we need to find robust, small and cpu-efficient algorithms. Let's keep this thread open for discussions on how we can implement this.
Hej Ville,
That's the exact culling approach I'm using now ( calculate model depth, calculate screen coordinates of model center, check if radius/depth overlaps the screen ). Although you'd need to add FOV to the equation as well when it's not constant. Ideally you'd want the radius to be assigned automatically .. but I guess it's tricky since you could be updating meshes and such. A box alternative would be nice too though ( floors, walls etc. ).
Concerning Z-Sorting; instead of a global switch, perhaps having properties on Models and even Render components would be a more flexible approach. That way you can use certain techniques only on operations that need it. Internally you'd for example still execute instances in order of priority ( which is collision group right now ), unless they have a Z-property assigned. In that case they are skipped, written off to a list, and rendered at the end of the priority pass.
K
That's the exact culling approach I'm using now ( calculate model depth, calculate screen coordinates of model center, check if radius/depth overlaps the screen ). Although you'd need to add FOV to the equation as well when it's not constant. Ideally you'd want the radius to be assigned automatically .. but I guess it's tricky since you could be updating meshes and such. A box alternative would be nice too though ( floors, walls etc. ).
Concerning Z-Sorting; instead of a global switch, perhaps having properties on Models and even Render components would be a more flexible approach. That way you can use certain techniques only on operations that need it. Internally you'd for example still execute instances in order of priority ( which is collision group right now ), unless they have a Z-property assigned. In that case they are skipped, written off to a list, and rendered at the end of the priority pass.
K
Yes that is another approach... so perhaps like this:
Model.RenderOrder (Normal, Z-Sorted)
So on each frame: First render all models with "normal" like today. Insert the "Z-Sorted" models in a list that is ordered on z-position. Then render that list.
That would work, wouldn't it? Or am I simplifying too much?
Model.RenderOrder (Normal, Z-Sorted)
So on each frame: First render all models with "normal" like today. Insert the "Z-Sorted" models in a list that is ordered on z-position. Then render that list.
That would work, wouldn't it? Or am I simplifying too much?
Hej Ville,
Depends a little on what you mean by "Z-Position". If it's just the Z-Distance of a Model origin relative to the camera's orientation, that would certainly be a method ( and a fast one probably ), but you'd get in trouble with objects that have identical positions ( but different rotations for example ), or objects of which their meshes aren't really located "around" their center at all. But again, it's a method, and certainly better then nothing ( when you need it ).
K
Depends a little on what you mean by "Z-Position". If it's just the Z-Distance of a Model origin relative to the camera's orientation, that would certainly be a method ( and a fast one probably ), but you'd get in trouble with objects that have identical positions ( but different rotations for example ), or objects of which their meshes aren't really located "around" their center at all. But again, it's a method, and certainly better then nothing ( when you need it ).
K
It is the same problem as with culling: it's hard to get the positions of all the vertices a OnRender-list generates since it can contain loops, particle systems etc. So the distance from the camera to the Model origin could be a first attempt, and maybe we can improve it later. I always strive to find the simplest solutions that can result in small code implementations, especially for features like these that not all kind of games benefit from. Just so that we can keep ZGE:s runtime as lightweight as possible.
Kjell, since there is math involved... any chance you can help me here? Perhaps some pseudo-code for determining the distance from the camera to a model? I guess you transform the model to camera space with a matrix multiplication? Which if I'm correct is needed for the culling algorithm also, so maybe we can combine these features somehow. Any code-snippets or idea how to implement will help me.
Kjell, since there is math involved... any chance you can help me here? Perhaps some pseudo-code for determining the distance from the camera to a model? I guess you transform the model to camera space with a matrix multiplication? Which if I'm correct is needed for the culling algorithm also, so maybe we can combine these features somehow. Any code-snippets or idea how to implement will help me.
Hej,
Can't you just use glProject()? Not sure if that's faster then calculating it yourself though. Here's a snippet of what I use when it's just 2 axis ( Z Rotation of Camera is always 0 ).
K
Can't you just use glProject()? Not sure if that's faster then calculating it yourself though. Here's a snippet of what I use when it's just 2 axis ( Z Rotation of Camera is always 0 ).
Code: Select all
MatrixX = CurrentModel.Position.X-App.CameraPosition.X;
MatrixY = CurrentModel.Position.Y-App.CameraPosition.Y;
MatrixZ = CurrentModel.Position.Z-App.CameraPosition.Z;
Angle = CameraX*Pi*2*-1;
CacheX = cos(Angle)*MatrixX-sin(Angle)*MatrixZ;
CacheZ = sin(Angle)*MatrixX+cos(Angle)*MatrixZ;
MatrixX = CacheX;
MatrixZ = CacheZ;
Angle = CameraY*Pi*2;
CacheY = cos(Angle)*MatrixY-sin(Angle)*MatrixZ;
CacheZ = sin(Angle)*MatrixY+cos(Angle)*MatrixZ;
Good morning Kjell!
I've never heard of glProject before. It's not a standard GL-call is it? Do you mean this: glProject?
And I think it is pretty cool that you do your own culling with scripting. So I guess you use a Condition-component in your OnRender? Have you measured that you really win performance this way?
I've never heard of glProject before. It's not a standard GL-call is it? Do you mean this: glProject?
And I think it is pretty cool that you do your own culling with scripting. So I guess you use a Condition-component in your OnRender? Have you measured that you really win performance this way?
Hej Ville,
Ah yea .. I forgot, it is part of the GLU library.
It all depends on your setup obviously, sometimes objects can do with a simpler calculation to determine whether or not something should be rendered. But in true 3d games, with high enough poly meshes, it's definitely worth it. I usually also divide levels up into area's, only having the current and neighboring area's active.
You can also use screen-coordinates to for example display heads-on information on 3d objects in your GUI (like Rez, Zone of the Enders etc. ). So in those cases you're using the calculation for multiple purposes.
More information here.
K
Ah yea .. I forgot, it is part of the GLU library.
It all depends on your setup obviously, sometimes objects can do with a simpler calculation to determine whether or not something should be rendered. But in true 3d games, with high enough poly meshes, it's definitely worth it. I usually also divide levels up into area's, only having the current and neighboring area's active.
You can also use screen-coordinates to for example display heads-on information on 3d objects in your GUI (like Rez, Zone of the Enders etc. ). So in those cases you're using the calculation for multiple purposes.
More information here.
K
- jph_wacheski
- Posts: 1005
- Joined: Sat Feb 16, 2008 8:10 pm
- Location: Canada
- Contact:
intersting stuff,. I would like to see more simple examples from you kjell you seem to have some advanced engine skills going on,. level zoning specificly,. I am usely concerened that doing too many calculation just to determine what to draw is a negative overall effect,. however I suppose simple testing gives you the truth of it,.
Can this glProject be used to implement some form of mouse object picking? Could we use OBB collision like a ray cast ?? (
Once I find a way to do mouse picking of objects I will build my 3d chess client. it is not 2d chess in 3d view but a 8x8x8 chess game,. .
we had a board working in gl years ago,. old info here;
http://iterationgames.com/PTDChess.html
Can this glProject be used to implement some form of mouse object picking? Could we use OBB collision like a ray cast ?? (
Once I find a way to do mouse picking of objects I will build my 3d chess client. it is not 2d chess in 3d view but a 8x8x8 chess game,. .
we had a board working in gl years ago,. old info here;
http://iterationgames.com/PTDChess.html
iterationGAMES.com
Hey jph,
Well .. not exactly, 3d mouse picking is kind of the opposite of this. Plus you'd either need to loop through object vertices to check whether the ray intersects .. or it's bounding box. It's possible already ( using Arrays ), but it's a bit of a hassle. Should be easier once PAPPE is fully implemented.
And in the end, all = math. Rendering can get costly / complicated quickly ( even though you don't "see it" ), so sometimes / often ( even when scripted ), it pays off to do some analyzing before rendering your scene.
K
Well .. not exactly, 3d mouse picking is kind of the opposite of this. Plus you'd either need to loop through object vertices to check whether the ray intersects .. or it's bounding box. It's possible already ( using Arrays ), but it's a bit of a hassle. Should be easier once PAPPE is fully implemented.
And in the end, all = math. Rendering can get costly / complicated quickly ( even though you don't "see it" ), so sometimes / often ( even when scripted ), it pays off to do some analyzing before rendering your scene.
K