Latest News
spacer View All spacer
 
November 21, 2009
 
Video Game Watchdog National Institute On Media And The Family Shutting Down [10]
 
Modern Warfare 2 Infinity Ward's 'Most Successful PC Version' Yet [8]
 
New Tech, Design Details Of Project Natal To Emerge At Gamefest In February
spacer
Latest Features
spacer View All spacer
 
November 21, 2009
 
arrow Upping The Craft: Susan O'Connor On Games Writing [5]
 
arrow Small Developers: Minimizing Risks in Large Productions - Part II [6]
 
arrow iPhone Piracy: The Inside Story [48]
spacer
Latest Jobs
spacer View All     Post a Job     RSS spacer
 
November 21, 2009
 
Sucker Punch Productions
Texture Artist
 
Sucker Punch Productions
3D Environment Artist
 
Sucker Punch Productions
Network Programmer
 
Sucker Punch Productions
Character Artist
 
Crystal Dynamics
Sr. Level Designer
 
Monolith Productions
Sr. Software Engineer, Engine - Monolith Productions - #113767
 
Sony Online Entertainment
Brand Manager
 
Gargantuan Studios
Lead World Designer
spacer
Blogs

  How To Project Decals
by David Rosen on 11/09/09 08:17:00 pm   Expert Blogs   Featured Blogs
7 comments
Share RSS
 
 
  Posted 11/09/09 08:17:00 pm
 

We've been talking a lot about decals recently, showing off our editor and explaining how the shading works. However, we haven't explained how the decals are actually projected geometrically onto complicated objects. We've been getting some questions about that, and I remember how hard it was to find information about decals when I was getting started, so here's an overview of the decal projection algorithm I created for Overgrowth. Let's start with this scene here. 

Decal

It's a bit too clean for me... I want to add a decal to give it some subtle weathering. To place a decal, I need to first set up the projector. The projector is just a 3D rectangular prism with three properties: size, position, and orientation. Of these, the orientation can be the most confusing. For decal projectors, I represent the orientation as an orthogonal basis, which is a set of three vectors that are all perpendicular to each other. For example as the XYZ axes form an orthogonal basis, as do 'forward', 'up', and 'right'. This gives us a complete orientation in 3D space, and is easier to think about than matrices and quaternions

Decal

The secret to projecting decals is to not think about creating a mesh that conforms to the model. Instead, think of it as starting with the model, and cutting away everything that is not in the projector box. I found that thinking of the problem like this made it easier to figure out what to do. Let's start by checking which triangles in the scene intersect with the decal projector. I first implemented this in a brute force fashion, and once that was working, changed it to work hierarchically using octrees [to bring the runtime from O(n) to O(logn)]. 

Decal

Next is the hardest part: we have to crop the triangles so that they don't extend out from the projector. Why is this important? Think about firing a thousand machine gun shots at a wall that is made of just two triangles. If we don't crop our bullet holes, we will have to draw the entire wall a thousand times! Since the wall is so much bigger on the screen than the bullet holes, this will use up too much fillrate, and bring the framerate to a crawl. However, with decal cropping, I can do this and maintain maximum framerate!So now that you're convinced that decal cropping is important, how do we actually do it? Cutting arbitrary 3D triangles to fit in an arbitrary 3D box is a daunting task. To make it easier, I thought about it in 2D. We can transform the triangles from world space to projector space, crop them, and transform them back. This makes the problem much simpler. In projector space, the projector box is just a square from (0,0) to (1,1), like this: 

Decal

A triangle in projector space might look like this: 

Decal

So now all we have to do is crop the triangle to fit in the square. This seems like a tricky task itself, but we can break it down even more. First, we can start with one border at a time. Let's pick the left border. To crop the triangle, we start by marking every vertex in violation of the rule -- in this case, the leftmost one. Then we look at every line between a marked vertex and an unmarked vertex, and add a vertex at the point at which it crosses the border. 

Decal

We can then simply remove the marked vertex (or vertices), and move onto the next border. 

Decal

Once we've checked all the borders, we have a cropped triangle! 

Decal

After doing this for every triangle, and projecting back into world space, we have a cropped decal mesh. 

Decal

If we keep track of each vertex's coordinates in projector space, those are also the projected texture coordinates! That's why I set up the projector space to be (0,0) to (1,1) -- that's the range that OpenGL uses for texture coordinates. Here's what the decal looks like using those texture coordinates on a test texture. 

Decal

 Now we can just substitute in our real decal texture, and we're done! 

Decal

Here's the original camera angle with the finished decal applied. It's a pretty subtle effect, but I think the extra detail helps make the damaged area look more realistic -- nothing would be able to take a huge chunk out of that block without scuffing up the surfaces around it. 

Decal

So that's an overview of how decal projection works in Overgrowth! If you're not familiar with linear algebra, you might be confused about how to transform triangles from one space to another, and why it's important to have a complete orientation. I could write a blog post explaining vector spaces and transformations in game development terms, but I'm not sure if anybody would be interested. Do you have any other technical subjects you would like me to talk about?

Follow us here!
Facebook iconModDB iconSteam iconTwitter iconYouTube icon

 
 
Comments

Sean Farrell
profile image
Nice article. But there is a point I don't understand. You say that cropping the triangles will reduce fillrate. Thinning out the mesh to only the affected triangles makes sense. But the way you crop the triangles, you add more and that will increase the number of triangles that are submitted. What did I miss?

Chris Howe
profile image
@Sean: Fillrate is essentially the number of pixels drawn. If you split a triangle into several smaller triangles that cover less total screen area then you reduce the number of pixels drawn and hence the fillrate. Since fillrate is the bottleneck for most games these days it is more important to reduce fillrate than it is to reduce triangle counts.

raigan burns
profile image
Great article! I really wish more people would reveal these sort of nuts-and-bolts details.

I don't really understand the distinction between an orthogonal basis and a rotation matrix though.. aren't they the same thing?

Patrick Coan
profile image
This is a question from an artists point of view; why not bake the details into the original uv maps?

Benjamin Quintero
profile image
@Patrick - In real-time engines, adding a new uv channel can be expensive. baking the detail can be difficult if the uvs are tiled. tiling is very common in cases for terrain or other areas larger than the available texture space. This means you can't share the same uv set unless you mapped it all between [0 - 1]. Even still, for one decal, you'd end up using a tiny piece of that full [0 - 1] texture space unless you literally painted the decal into the same diffuse texture. Unless you have id Software's Megatextures, this is not reasonable to load up gigs of unique textures with decals painted on them.

http://decalcreator.inlandstudios.com

This is a tool that does a similar technique within Maya.

Patrick Coan
profile image
That makes sense, thanks for the feedback. So it seems like the strategy is to lay down a cheap base layer, one that has universal use for a given element like cement, and then add independent 'decals' where necessary to spice it up. And I'm assuming that wherever we can implement procedural textures, we will?

Benjamin Quintero
profile image
@Patrick - you can use procedural textures, but they need to be baked out to something reasonable for most real-time engines (512 or 1024 resolution). Generally for things like terrain, you use whatever that engine has; they are all different. Many popular engines with outdoor rendering (Source, Unreal 3, idTech5, Crytec) they all have some kind of specialized terrain tools. It's not too common that an engine will just take your Maya/Max mesh and treat it optimally as terrain.

Decals ARE one way however to circumvent this restriction, since you can tile a single base texture (painted or baked procedural) and sprinkle some decals to add a little randomness. It's not perfect, or always ideal, but it can get you some nice results. Over-use will kill your performance and cause z-fighting, so be frugal with your decal work and make each one meaningful.



none
 
Comment:
 


Submit Comment