• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Six222

Handling World Matrices

7 posts in this topic

So I've been working away at some projects of mine and so far I've only come to rendering a few simple objects at a time like:

[code]
For each Object:
Update World Matrix
Send World Matrix to Vertex Shader
Draw Objects Vertex Data
End Loop
[/code]

Pretty basic and it's probably the most common solution to rendering small projects but I've been wondering how this handles with large worlds with many objects I can tell already that there's going to be hundreds if not thousands of draw calls which is obviously not very efficient. So I came here to ask how you guys handle it. I've herd of a few ways of handling the draw calls but my main question is how to handle updating the world matrix? For example if i had a 16 cubes in one vertex buffer i would have to draw each 12 vertices separately and update the world matrix one by one. I thought of a few ways to handle this but i'm not too sure still:

Pre-computing it in a level editor:
This method would pre-compute all translations, rotations and scaling in the world editor and save the data into a separate file.

Pros:
Going to render fast as all data can just be done in 1(?) draw call.
Removes the task of multiplying all the data by the world matrix in a shader will obviously be a fair bit faster

Cons:
All objects would be static and wouldn't be able to update there position without manually editing the vertex data
File size would be huge.


Sending the world matrices as an array:

Pros:
Can again render all objects in a few draw calls

Cons:
Will be very memory heavy especially with lots of objects
Will probably have to be done in a few iterations due to memory
Hard to keep track in a vertex buffer on which data to apply the world matrix to

I can't see any of these being viable solutions, i'm probably under-estimating the processing power these days as i could use option 1 for all static and world data and then use the method i was using before to just update dynamic objects(physics props, npc's etc.)
0

Share this post


Link to post
Share on other sites
I am far from being an expert in this type of stuff, but the way I understand is basically what you said in your last sentence.

Perhaps you can create a buffer object to batch vertices (using CPU time) to the GPU, then draw them when the buffer is full, cutting down on the amount of draw calls. I do not know the "sweet spot" between using CPU and minimizing draw calls, but this is the method used (I think) by the [url="http://create.msdn.com/en-US/education/catalog/sample/primitives"]XNA Primitive Batch[/url] example. Also (having to do with XNA, but perhaps worth a read even if you are not) is [url="http://msdn.microsoft.com/en-us/library/bb975156.aspx"]this article[/url].

I do know that you can run into "stitching" problems when using separate meshes and using a transform matrix to try and line them up - floating point inaccuracies can cause seams to appear where you would expect perfect joins. I know this, because I've recently had this happen in a project of mine, and now I am in the process of re-writing my level baking code...
1

Share this post


Link to post
Share on other sites
Thanks for the reply! I thought i might have been over complicating things a bit i just needed some clarity on it :P Anyway I have another question now, i'm aware of some techniques for reducing draw calls, batching, instancing etc. but i'm not 100% on how the world matrix is applied to each object, hence the title for this thread. If your rendering a group of objects in one draw call then how does each object get translated, scaled, rotated? Back to my original example[color="#1C2837"][size="2"] "if i had a 16 cubes in one vertex buffer i would have to draw each 12 vertices separately and update the world matrix one by one" with batching this would be done as:[/size][/color]

[color="#1C2837"][size="2"][code]
for each object until vertex buffer is full:
insert data into vertex buffer
end loop
Draw all 16 cubes
[/code]

[color="#1C2837"][size="2"]And what i'm not to sure is how these would get their world matrices applied to them? The only way i can see this working is if i did:[/size][/color]

[color="#1C2837"][size="2"][color="#000000"][size="3"]
[color="#1C2837"][size="2"][code]
or each object until vertex buffer is full:
insert data into vertex buffer
end loop


for each cube
Update World Matrix
Draw 1 cube
end loop
[/code][/size][/color][/size][/color][/size][/color]
[color="#1C2837"][size="2"][color="#1C2837"][size="2"][color="#000000"] [/color][/size][/color][/size][/color]
[color="#1C2837"][size="2"][color="#1C2837"][size="2"][color="#000000"][size="3"]But then wouldn't this just end up with lots and lots of draw calls?[/size][/color][/size][/color][/size][/color]
0

Share this post


Link to post
Share on other sites
[quote name='Six222' timestamp='1313680008' post='4850792']
So I've been working away at some projects of mine and so far I've only come to rendering a few simple objects at a time like[/quote]There's a few different processes going on in your example.
It's often better for performance to split things up so you're only doing one kind of operation at a time -- e.g. update all object's matrices, and then draw all objects.
[code]For each active object:
Update World Matrix and bounding volume
For each active object
Determine visibility
For each visible object
Add to rendering queue
For each item in sorted rendering queue
Send World Matrix to Vertex Shader
Draw Objects Vertex Data[/code]
[quote]I've been wondering how this handles with large worlds with many objects I can tell already that there's going to be hundreds if not thousands of draw calls which is obviously not very efficient.[/quote]In my current engine, ~1000 draw calls takes ~1.5ms of CPU time. In other engines, I've seen 1000 draw calls take 10ms of CPU time... so it really depends on how you structure things.

Your 'pre-computation' method is common for static geometry, it's also known as baking/collapsing the transforms/matrices into the vertex data. Generally you end up with one draw-call per material ([i]as different materials have different shader parameters, textures, shader programs, etc[/i]).

Your 'array' method is supported via [url="http://www.google.com.au/search?q=hardware+instancing+directx"]instancing[/url], and is commonly used the reduce the amount of draw-calls required when drawing many of the same object (e.g. a field of grass).

[quote]... instancing etc. but i'm not 100% on how the world matrix is applied to each object, hence the title for this thread. If your rendering a group of objects in one draw call then how does each object get translated, scaled, rotated?[/quote]With instancing, you have a VB containing the vertices for a single cube, and an another buffer containing 'N' matrices. You issue an instanced draw call, asking for the cube to be rendered 'N' times, and then the shaders for each object are passed a value from '0' to 'N-1'.

[quote]Back to my original example "if i had a 16 cubes in one vertex buffer i would have to draw each 12 vertices separately and update the world matrix one by one" with batching this would be done as:
[font="Courier New"]for each object until vertex buffer is full:
insert data into vertex buffer[/font][/quote]Why are there 12 verts in a cube? And you shouldn't be writing into a vertex buffer every frame -- the cubes should already be present in the buffer.

* If you were using instancing, there would only be a single cube in the buffer.
* If the cubes are static, there will be 16 of them in the buffer, pre-transformed.
* If the cubes are dynamic, then, yes, the 'standard' method would involve one draw-call per cube.
* If the cubes are dynamic and you want to draw them all in a single-draw call, then in their vertex data you would add another stream that contains an object-ID number. e.g. all the verts for the first cube would store the number 0 in this stream, the second cube's verts would store 1, etc... Then in the vertex shader, you can use this data as an array index into your array of transforms.
1

Share this post


Link to post
Share on other sites
[quote name='Hodgman' timestamp='1313719496' post='4851028']
-snip-
[/quote]

Ah thanks for the reply, I understand want i need to do now. I just needed some clarity on how fast this method runs, i'm really under-estimating how long it takes to do this :P Thanks again for the replies!


and also
[quote name='Hodgman' timestamp='1313719496' post='4851028']
[color=#1C2837][size=2]Why are there 12 verts in a cube? And you shouldn't be writing into a vertex buffer every frame -- the cubes should already be present in the buffer.[/size][/color]
[/quote]
[size="2"][color="#1c2837"]My bad there's 12 polygons and 36 verts ;)[/color][/size]
0

Share this post


Link to post
Share on other sites
[quote name='Six222' timestamp='1313720182' post='4851032']
[quote name='Hodgman' timestamp='1313719496' post='4851028']
[color="#1C2837"][size="2"]Why are there 12 verts in a cube? And you shouldn't be writing into a vertex buffer every frame -- the cubes should already be present in the buffer.[/size][/color]
[/quote]
[size="2"][color="#1c2837"]My bad there's 12 polygons and 36 verts ;)[/color][/size]
[/quote]
With indexing, you could cut that down to 8 verts ;)
0

Share this post


Link to post
Share on other sites
[quote name='yckx' timestamp='1313731261' post='4851058'][quote name='Six222' timestamp='1313720182' post='4851032']My bad there's 12 polygons and 36 verts ;)[/quote]With indexing, you could cut that down to 8 verts ;)[/quote]Or 24 verts if normals aren't shared across face-edges ;)
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0