3D Engine Renderpipeline

Started by
5 comments, last by Sarge 21 years, 4 months ago
Hello, I''m urrently writing a new 3D Engine with DirectX 8.1 and Vertex and PixelShader support. I just got the following idea and want to hear your comments on this please I''m storing all my models and their polygons in a special list. My physics engine works on this list gives physical support like moving lights when you shoot at them etc. My Graphic engine itself works down the same list as often as possible and draws the models. Now I had the idea to put the render part into an extra thread which works parallel to the game specific part (physics, movement of characters etc) of my game and tries to draw as often as possible. This way I would have to implement some multithreading support to preven the threads from accessing the same object at the same time but I think that''s possible. Do you know how Quake III handles this or do you have any comments on this??? All comments are welcome Thanks in advance Greetings Sarge
Advertisement
Quake 3 doesn''t use threads. That''s about all I know on the subject.
There''s a GDC talk about the Q3 rendering architecture here:
http://real.mfi.com/ramgen/gamasutra/hook1.rm
http://real.mfi.com/ramgen/gamasutra/hook2.rm
You might need to get a (free) account at gamasutra to view it. I''m not sure if they discuss the kind of things that you are interested in or not, but it might be worth watching.

The best source, of course, is the Q3 source code if you''re looking for information...

I''m not sure what kind of "special list" you''re talking about, but you might want to take a look at BSP trees and octrees if you haven''t already done so.

Good luck!
Its a good idea to have the gpu and cpu work in parallell.
How ever i dont think multi threads is the right way to go.
I know in opengl that you can check how far the gpu has come in its comand stream.

if you do this with threads you will end up with a "wait and hold situation" for either the gpu or the cpu.

check at nvidia they have good docs on the subject
Pathetic - thats what most of the answers are :-)

Lets see :-)

Ok, using multiple threads is pretty nice - especially as the physics is "times" (you could say runs in certain intervals), and uses "relatively little" processing power, and it makes no sense to run it "as fast as possible".

So your proposition is:
(a) run a higher priority thread with the physics, which cycles, waits, cycles, waits. It may call DoEvents or something similar regularly.
(b) run a lower priority thread for the graphics which runs in an endless loop.

Now, this is good in theory - it has some advantages on new PIV''2 (hyperthreading - they COULD run in parallell). I a not so sure whether DirectX (8,9) actually is intelligent enough to release the calling thread when waiting for the graphics card (which might happen occasionaly - not all Dx function calls just go to the driver''s command queue).

There are problems with this, though - your whole architecture has suddenly to be threadsafe. I am not sure how much of a problem this could pose, and how much performance you might loose again on mutexes (though this is very propably VERY low - after all some good server software is heavily multithreaded). The point, though, is: you HAVE to be sure that both subsystems run good in this architecture. This is way heavier than just queueing interaction (mouse coordinates etc) in a higher priority thread.

Now on the positives: The render engine has the advantage of not changing any physics state. It basically runs through the world and - renders. It may have some state in the objects, bu tthis can be designed in such a way that this particular state is then NOT changed by the physics. So basically they can coexist pretty nicely.

The main problem I see, though, is that your renderer has to either interrupt physics, or to make sure that it is consistent. For example: If I render a complex scene with first "flat to fill the z-buffer", then "texturing" then "lightning", and if I render all objects in all passes one after the other, THEN-

- the physics engine may have changed an object''s position between the passes. -

This can be avoided (locking), but when you do this not granular enough, then basically you loose most advantages (besides hyperthreading). It can be solved in a number of ways - just be aware of it.

In concrete: I think that most game developers just lack the experience of trying ths, and follow age old concepts. I think that separating rendering and physics MAY work, and MAY be benefitial, especially as it allows better CPU usage (hyperthreading, again - and no, the task manager does NOT tell you the truth, it can not). It may give you a signifiant adtvantage. Try it out, really.

Regards

Thomas Tomiczek
THONA Consulting Ltd.
(Microsoft MVP C#/.NET)
RegardsThomas TomiczekTHONA Consulting Ltd.(Microsoft MVP C#/.NET)
Hi enouk, Z01, Chozo,
thanks for your answers. It wasn''t really the ansswer to what I asked but thanks anyways

Greetings Sarge

=======================================================

Dear Thona,
thanks for your answer it''s exactly what I mean.
I thought of splitting my engine into several threads like physics and character movement, rendering, sound etc.
All threads would operate on the same game data (vertices, polygons, etc. in this case)


The problem is the synchronization of these threads so they don''t access the same data at the same time.

like here...:
- the physics engine may have changed an object''s position between the passes. -

I wonder if John Carmack solved this problem in one of his engines.


Actually I''m running all in the app''s thread but i''m really thinking of splitting the work into several threads.

Thanks so far
Sarge
Well, there are two possibilities for this:
(a) copy the attributes of the objects into a separate storage (maybe within the object) for the renderer - basically in the first pass, after culling, the object gets "pinned", copying it''s position into a second state variable, which the renderer uses.
(b) synchronize.

I would say that (a), while still consuming memory bandwidth, can be more efficient. ESPECIALLY if you assume that you can copy all "render relevant" data into an array, then traverse over it later on in the renderer.

Actually it is not a too hard task to work with, and IMHO it is a definite go. Having only one thread is hardly efficient today, and with HyperThreading coming up, it is soon foolish. Then, otoh, besides some graphical gurus (Carmack), I find a lot of no-knowledge in the game developer area for tactics and technologies every enterprise developer SHOULD know inside out. You dont write a server without multi-threading, and especially when interacting with outside equipment that may slow you down (hint: graphics card) it it always advisable to separate this part into a separate thread.

Hm, maybe I play around a little with this and write a white paper on how to organize this. I am anyhow playing around with C# and DirectX currently, to write a white paper on how to use DirectX best out of C# - just a hint: some best practices in C++ are BAD BAD BAD in C#, you have to rethink certain strategies.


Regards

Thomas Tomiczek
THONA Consulting Ltd.
(Microsoft MVP C#/.NET)
RegardsThomas TomiczekTHONA Consulting Ltd.(Microsoft MVP C#/.NET)

This topic is closed to new replies.

Advertisement