Engine design (UML inside)

Started by
9 comments, last by bilsa 18 years, 6 months ago
Hi. I've been messing with designing engine layout for the application I'm working on. I've reused most of my old engine for it, only rewriting it to C#. I would like some feedback on this. Here is the UML diagram of a part of it. I will update it with any ideas given. The main class here is XScene. It holds a pool of light, cameras, renderers and scene elements. Scene elements are parts that actually hold the data about the scene and they come in many forms. Anything from sky systems, ABT's, quadtrees or any other spatial structure. On render they are transversed and the visible geometry is added to renderer. After that the renderer sorts the render lists and renders everything to it's bound render target. It worked quite well in last engine but now I have a bit of problems with some 'new' features I would like to add to it: -So far nodes are only frustum culled so I would like to have optional occlusion culling step. I have a bit of trouble figuring out where to insert it in as I would like to be as general as possible. -So far the lights are just stored in a list in the scene and are not tied to actual geometry. Everytime a object needs a light it goes trough that list to find it (for example to find closest 4 lights). This works if there are only 10 or so lights in scene but it really breaks down with large number of small lights. How do you handle large number of possibly dynamic lights? Any ideas are welcome!
You should never let your fears become the boundaries of your dreams.
Advertisement
Without looking at the design, that diagram was quite pretty. What tool did you use to make it?
It's part of MS Visual Studio 2005.
You should never let your fears become the boundaries of your dreams.
I don't know the details of the ABT structure, but I suspect that they're similiar in some ways to ie. quadtrees (in that they divide scene into hierarchy of nodes). If so, IMHO you could store lights inside those nodes, either as part of existing nodes (ie. attached to a piece of geometry) or in node on their own.

OTOH, I think that if your lights would be stored in plain vector (pointers to them), then you could simply iterate through them as you did up to now - CPU's really like such sequential operations, so AFAIK it should be bloody fast, cache-friendly and much simpler to code than any other design.

Also, maybe this will help: OGRE object hierarchy.

HTH
the problem with UML class diagrams is they only tell part of the story. most designs, good or bad, will look good in a UML class diagram, and if no other architectural design is applied before starting the coding, they often end up in one of two very common OO ruts: the huge base class and dynamic typing. there is nothing here that looks bad, but it would be useful to flesh out the other, equally important, dimensions of the architecture such as: call hierarchy, dependency graph, lifetimes of objects relative to each other, and inter-object relationships.
And how!
I strongly suggest to you to check out Ysaneya's post in his journal about his "pipeline scheme". It has some nice ideas.
So... Muira Yoshimoto sliced off his head, walked 8 miles, and defeated a Mongolian horde... by beating them with his head?

Documentation? "We are writing games, we don't have to document anything".
@Koshmaar: I've checked out ORGE when I was studying Axiom. The engine looks nice and I did get some ideas from it, but none of them solve my biggest problems. I don't think lights sould be store in a specific scene elements as others don't (and shouldn't) have access to it.

@andhow: It's true that UML gives only half the idea. Since I don't know how to draw diagrams for the rest of stuff I'll try to explain my ideas a bit better.

Scene
The scene class holds the information about everything that needs to be renderd and is basicly current state of the world. Most of data is held in a list of scene elements. There are 2 main functions that are exposed:
-Update: Updates all render elements.
-Render: Collect visible objects from render elements and render them.

Scene Element
This is a base class for all kinds of object/geometry data. I derived a bunch of classes from it like ABTs, QTs, sky domes, or just object pools. Until now they are responsible for
-Updating the objects they hold, and
-Sending objects to renderer

Renderer
Renderer collects objects from scene and scene elements. Once all objects are collected they are sorted by material (shader, texture,...) and vertex buffer they are renderd to the currenty binded render target. Renderer is based on shader system described by Yann L so it supports the pass bouncing and things like that.


Now the problems with this design that I would like to fix:
Culling & LOD
Since now each scene element is doing it's own culling (only frustum so far). The problem come when I try to integrate a occlusion culling (or any other culling scheme) into play. If I add it to scene element, after frustum culling and before sending to renderer I lose the ability for object from one scene element to occlude the element from another scene element (like player hidden behind the hill). But if I add it to renderer (before sorting objects) I lose information that I could use for better LOD calculation.
Ultimatly I would like to have some kind of 'culling chain'. I would link together for example sphere-frustum, box-frustum and HOM.

Lights
So far the lights are stored in a collection inside the actual scene objects. At render time visible & active lights are moved to temporary collection. This is not good for a couple of reasons: Scene elements have to access scene object and they have to iterate trough it each time to find anything. A solution I have in my head right now is some kind of light manager. It would hold lights in some kind of spatial structure to increase searching. One problem with them that I still have is how to effectivly handle rendering from multiple cameras, as each camera should have it's own 'visible lights list'.



I hope this makes a bit more sense. I would really like to see some diagrams or (a bit more in-depth) descriptions now other handle this problem.


PS: If anyone is using VS 2005 class designer/diagrams: how do you make it show arrows to interfaces (so it doesn't just name them).


EDIT:
@ffx: I'm studying his ideas now. It looks very nice so far.
After reading that I'll probably change my design a bit.
You should never let your fears become the boundaries of your dreams.
Quote:Original post by _DarkWIng_
...
Now the problems with this design that I would like to fix:
Culling & LOD
Since now each scene element is doing it's own culling (only frustum so far). The problem come when I try to integrate a occlusion culling (or any other culling scheme) into play. If I add it to scene element, after frustum culling and before sending to renderer I lose the ability for object from one scene element to occlude the element from another scene element (like player hidden behind the hill). But if I add it to renderer (before sorting objects) I lose information that I could use for better LOD calculation.
Ultimatly I would like to have some kind of 'culling chain'. I would link together for example sphere-frustum, box-frustum and HOM.
...


Which method are you going to implement? Are you going for a software HOM or hardware queries? Both methods have different "best" implementations IMO, for software you probably want to be rendering the maps for the next frame while the current one is rendering. For hardware you can render one frame and readback the next frame or use a delayed readback approach on the current frame.

Culling IMO should be handled by each scene element because of their diversity and needs.

How about a two pass approach, add another method into each scene element 'RenderOccluders' which guarantees that all the occluders have been rendered when the actual rendering starts. Each node can then query for its visibility however it wants. This could be extended into the culling chain you mentioned, instead of hardcoding in 'RenderOccluders' for example. Maybe something similar to Yann L's shader thread (like the RPASS's[smile]).

HTH
What about shadows coming from different areas outside the frustum? I think you might find yourself hacking things a bit like farcry did. Otherwise the complexity is just staggering.
@nts: I'll think about your sencond idea (adding render occluders to scene elemnts)

Quote:Original post by JD
What about shadows coming from different areas outside the frustum?

How could a light (and its shadow) that is not in frustum (== light's bounding voume does not intersects with view frustum) affect the scene? Am I missing a point here?
You should never let your fears become the boundaries of your dreams.

This topic is closed to new replies.

Advertisement