Art pipeline best practices?
by Adam · in Torque Game Engine Advanced · 02/15/2007 (12:56 pm) · 7 replies
I've used TGEA on multiple projects now, but I've never really gotten a definitive answer to a question I've had from day 1. What is the best practice for setting up textures and materials? Ive approached textures and materials a few different ways in the past. I'll use examples to better explain my methods.
First is probably the most basic way of going about it. I have an object which I want to break up into 3 different materials, so I end up with 3 different textures on which to base my materials on. An example of this would be a car. I want the metal to be shiny, the glass to be transparent, and the tires and interior to have a slight specular, but mostly be flat. The metal, the interior/tires, and the glass all get unwrapped to their own map, and materials are made. This feels really unoptimized, though, especially coming from TGE, where you if you could have all the uvs of a single object sit on the same map, then that was the way to go. Now, I've heard bits about how tgea does some kind of batch rendering, so the same rules don't apply, and that it's ok to go about it this way. I don't fully understand whats going on "under the hood", though, which is a bit of knowledge I'd really like to have.
I was also told that a way boost performance is to unwrap portions of different models with similar surface properties to the same texture. To use the car example again, if I had multiple cars, the metal from each car would be unwrapped to the same map, all the glass to another, and all the interiors/tires to a third. The thing I hate about this is that it's a bit of a hassle from a workflow standpoint. It means I have to start merging my individual models into the same file for that one part of the process, then drop them all back into their own files. On top of that, it also means that the task of pre-production planning becomes much larger. Because I want to absolutely maximize my performance, I have to have a fairly comprehensive list of what I want in the game and then figure out what should be mapped with what.
I recently successfully tested a way to use oldschool "all parts of an object get mapped to the same sheet" workflow using proxy textures. To again use the car as an example, I'd unwrap all parts of the car onto the same UV map and paint it accordingly. The name of the texture would be (for example) "car_diffuse". Then when I was done, Id assign each unique material surface its own material ID in max, and apply a 2x2 proxy texture. The metal would be textured with "proxy_car_metal", the glass would be "proxy_car_glass", and the interior/tire would be "proxy_car_interior". Id export the car with the proxies applied to it. Then Id create 3 material datablocks which use the proxy textures as the "mapTo" file name. The baseTex, however, would be the original "car_diffuse" texture I painted. Using this approach, I can have the entire car use the same texture file, while still benefiting from multiple material datablocks. I really like this method because it speaks to the way I learned to do this, but Im entirely unsure if this is a costly way of setting up materials?
So all this said, is there an approach that is more correct than others? If I wanted to use TGEA to its fullest extent - that is, fully utilize the material system while getting the best performance possible - how should I be making my art? Along with that, what is the engine doing internally that makes me want to make my art in this fashion? That is, what makes the "right way to make art for tgea" the right way to make art?
First is probably the most basic way of going about it. I have an object which I want to break up into 3 different materials, so I end up with 3 different textures on which to base my materials on. An example of this would be a car. I want the metal to be shiny, the glass to be transparent, and the tires and interior to have a slight specular, but mostly be flat. The metal, the interior/tires, and the glass all get unwrapped to their own map, and materials are made. This feels really unoptimized, though, especially coming from TGE, where you if you could have all the uvs of a single object sit on the same map, then that was the way to go. Now, I've heard bits about how tgea does some kind of batch rendering, so the same rules don't apply, and that it's ok to go about it this way. I don't fully understand whats going on "under the hood", though, which is a bit of knowledge I'd really like to have.
I was also told that a way boost performance is to unwrap portions of different models with similar surface properties to the same texture. To use the car example again, if I had multiple cars, the metal from each car would be unwrapped to the same map, all the glass to another, and all the interiors/tires to a third. The thing I hate about this is that it's a bit of a hassle from a workflow standpoint. It means I have to start merging my individual models into the same file for that one part of the process, then drop them all back into their own files. On top of that, it also means that the task of pre-production planning becomes much larger. Because I want to absolutely maximize my performance, I have to have a fairly comprehensive list of what I want in the game and then figure out what should be mapped with what.
I recently successfully tested a way to use oldschool "all parts of an object get mapped to the same sheet" workflow using proxy textures. To again use the car as an example, I'd unwrap all parts of the car onto the same UV map and paint it accordingly. The name of the texture would be (for example) "car_diffuse". Then when I was done, Id assign each unique material surface its own material ID in max, and apply a 2x2 proxy texture. The metal would be textured with "proxy_car_metal", the glass would be "proxy_car_glass", and the interior/tire would be "proxy_car_interior". Id export the car with the proxies applied to it. Then Id create 3 material datablocks which use the proxy textures as the "mapTo" file name. The baseTex, however, would be the original "car_diffuse" texture I painted. Using this approach, I can have the entire car use the same texture file, while still benefiting from multiple material datablocks. I really like this method because it speaks to the way I learned to do this, but Im entirely unsure if this is a costly way of setting up materials?
So all this said, is there an approach that is more correct than others? If I wanted to use TGEA to its fullest extent - that is, fully utilize the material system while getting the best performance possible - how should I be making my art? Along with that, what is the engine doing internally that makes me want to make my art in this fashion? That is, what makes the "right way to make art for tgea" the right way to make art?
#2
I was actually going to send this to you in an email, but I figured this might be information the community at large would benefit from. Anyway, thanks a ton, this is exactly the type of response I was hoping for.
02/15/2007 (5:52 pm)
Ah Brian, thanks so much!I was actually going to send this to you in an email, but I figured this might be information the community at large would benefit from. Anyway, thanks a ton, this is exactly the type of response I was hoping for.
#3
02/15/2007 (9:53 pm)
Good stuff. I was watching this post with a great deal of interest. I didn't realize you could do something like "proxy" textures. That would add a lot of power while keeping the file count/organization down.
#4
02/16/2007 (12:21 pm)
Yeah, that is a good idea. Don't know if you have time Adam, but a short TDN article on that would be very helpful to artists new to TGEA.
#6
02/16/2007 (9:55 pm)
No promises, but the request for a proxy tutorial is certainly reasonable. :)
#7
Basically, you want to approach the "characteristics" of each object seperately. So for instance, if you want objects that are only using diffuse textures, you would batch all of the geometry with that using a single texture atlas and a single material and hopefully the batcher will batch the whole geometry set into a single draw call.
Its kind of counter-intuitive from an artist viewpoint though, because you might batch say the main part of a gun, with the main part of a vehicle, with the main part of a palm tree trunk, using the same material + texture combo. Artists I think might have a hard time thinking about that.
What would be useful, is an asset material mapping/management pipeline to sort these issues automatically.
Sorry, been reading Shader X2 and Tom F's article about this kind of thing :)
The basic concept for high performance is "reduce number of shader changes and number of draw calls", so any similar geometry can be lumped together with the same shader you get a win.
02/20/2007 (2:58 pm)
You might want to look at building texture "atlases" out of your often used textures and then build a material that works with that texture atlas.Basically, you want to approach the "characteristics" of each object seperately. So for instance, if you want objects that are only using diffuse textures, you would batch all of the geometry with that using a single texture atlas and a single material and hopefully the batcher will batch the whole geometry set into a single draw call.
Its kind of counter-intuitive from an artist viewpoint though, because you might batch say the main part of a gun, with the main part of a vehicle, with the main part of a palm tree trunk, using the same material + texture combo. Artists I think might have a hard time thinking about that.
What would be useful, is an asset material mapping/management pipeline to sort these issues automatically.
Sorry, been reading Shader X2 and Tom F's article about this kind of thing :)
The basic concept for high performance is "reduce number of shader changes and number of draw calls", so any similar geometry can be lumped together with the same shader you get a win.
Torque Owner Brian Ramage
Black Jacket Games
The quick answer is that, with batching, you can do this however you want. You can use 3 separate textures, or you can use one and go with your "proxy" method to have the 3 materials reference the same texture. The proxy method could possibly be a bit faster because it might save a texture change if the batches are processed adjacently.
What the batching does is just group up all of the geometry that uses a particular material, and then set up the video card for rendering that material, and then go through and render the geometry. So if in your example, you had a few cars, it would render all of the wheels, then all of the chassis, and then the windows. This is much more efficient than in TGE, where it renders each complete car at a time, so it has to keep switching between textures/states every time it draws a new car.
To make things such that they render in the most efficient way - use as few materials as possible and collapse all of your static geometry into as few meshes as possible. That's pretty much it.