Decals on complex surfaces

Started by
6 comments, last by spek 17 years ago
Hi, How to make (bigger) decals that "wrap" themselves upon the surface? For example, a blood decal on a corner? I've seen 2 ways so far; 1- via projected texture 2- with a second mesh I'm interested in the "mesh" option (or will projective textures be more powerfull?). So far I know where the decal "hits", and I can find the surrounding polygons that are in the decal "range". But after that, I need to shrink/clip the decal, since the polygons where the decal is placed on, are ussualy way too big. How to clip them, and how to (re-calculate) its texture coordinates?. I know Eric Lengyel (did I spell that right?) wrote something about this in a book, but I don't have that... And although decals are in every game nowadays, I can't find a proper demo either. Only some advanced math sheets about clipping, but my math isn't that good... greetings, Rick
Advertisement
you could use a hybrid system


with projected textures you could place as many decals as you want onto the same surface as long as your projection of each decalse doesn t differ too much(e.g.: always shoot from the same location)


you could do this in the CPU once the decal is applied
all you need are some decal textures, with the decal in the center and the surrounding pixels fully transparent

a) calculate the projection matrix
b) multiply the vertex positions of your mesh with that matrix
results in a set of texture coordinates
c) see if any of the pixels of the triangle will be covered by a decal, if so add the triangle & the tex coordinates to a vertex buffer
as far as I can think you don t have to take care about clipping in this case,
just some backface culling should be applied, but thats trivial to implement and maybe so some redial culling, skipping all those triangles that are to far away in the same mesh,
that reduces computation time and avoids back projection problems


this way you have one vertex buffer per decal


another approach would be to sort the decals by their projection direction

and render them to a texture, this solution will become very storage consuming the more decal projections occur


I d favor the 2nd approach you mentioned

http://www.8ung.at/basiror/theironcross.html
I don't bother clipping triangles for decals.

For one, most geometry being fed into a modern engine doesn't have triangles that are that large.

For another, if you're re-rasterizing the exact same triangles, and using z less-or-equal, you don't have to muck about with depth bias or anything else to avoid z-fighting between the decals and the underlying geometry. If you actually clip the triangles, subtle precision issues can cause z-fighting.

So, I just extract the triangles that will be affected by the decal, and put them into a separate buffer, and do my decal coordinate projection on them.

I'd expect that you'd want different decals to share the same vertex buffer - one VB per decal seems excessive.
of course nobody would place each decal into a seperate VBO

but you need to implement a VBO generator that takes care about ordering, so all decals with the same image are in a row
http://www.8ung.at/basiror/theironcross.html
The decals are placed on triangles that are ussually way bigger than the decal itself (let's say a 50x50 cm decal on a 3x3 metres surface). I guess it's not a bad idea to make the decals as small as possible, to limit the amount of invisible pixels that take away speed for nothing. I think the decals will only hit 1/2, maybe 3 triangles in most cases. But there can be more complex surfaces as well though (on a rounded pipe, or on a body).

The decals can come from "any" direction, and the camera can also view them from most directions. I think a good example would be the blood decals in Doom3, and I also liked the holes used in F.E.A.R. I think some of those decals used parallax mapping to give the larger holes some depth effect.

Yet another thing is that I want to use multiple decal textures. All the textures could be in the same atlas texture(s) though, so decals can share the same material. But only with different offset texture coordinates.


Maybe I understand this wrong, but if I do projective texturing, doesn't that mean I have to draw the affected triangles for each decal again? I think there can be quite much decals (imagine firing a machine gun on a wall in front of you). If I don't clip the relative large triangles, wouldn't that require much speed since transparent surfaces aren't that fast, and most of the pixels will be invisible?

Thanks for helping,
Rick
Yes, using a single projection for each decal could potentially mean re-rendering the same triangle repeatedly. If the fill rate eaten by this causes problems, there are a few ways you can limit it. 1) Limit the number of allowable decals. 2) Require that your visual geometry is tesselated more finely to avoid burning fill (at the cost of extra geometry). 3) Combine decals by "splatting" into a texture and using that texture to render the decals.

#3 is going to be the most complicated to implement, and there are a couple fundamentally different ways of approaching it.

The technique I came up with for Stranglehold was what I called "Copy-on-write." Basically, for a wall (or whatever) that's going to get shot up, it uses a texture shared with other similar-looking surfaces. When it gets modified, a copy of the texture is made, that particular surface is pointed at the new copy of the texture, and then changes are written into that texture copy. The copy of that texture then has a limited lifetime.

Another approach would be to, instead of modifying any underlying textures, allocate an overlay texture that's mostly transparent. Then, when you add a hit mark or whatever, you splat that into the overlay texture, and modify the overlay's alpha.

Btw, the COW approach was actually used to modify an alpha mask between a "clean" version of the surface and a "damaged" version of the surface.
I wouldn t use an extra texture, from my experience even with the old quake 3 team arena engines I must say the number of polygons you can generate with normal map editors such as the radiant editors
doesn t really matter anymore. adding some decal triangles to a VBO and rendering some additional decals doesn t matter anymore too. Just keep in mind to implement some sort of decal cache that gets rid of old decals following the FIFO principal

I dunno if you understood the projected decal algorithm correctly

the way I would use it is to use the projection in order to determine the texture coordinates and the triangles that are covered by visible decal textures,
then move these triangles including the texture coordinates into a VBO and render this




http://www.8ung.at/basiror/theironcross.html
Well, I think I don't understand the projective technique indeed :) My head is exploding last days, hard to concentrate. You explained earlier 3 steps. Are these used to render an existing decal, or to construct one? I guess to construct one, but just fore sure...

>> a) calculate the projection matrix
From which "viewpoint"? Camera?

>> b) multiply the vertex positions of your mesh with that matrix
>> results in a set of texture coordinates
Which mesh? You mean the polygon(s) where the decal should be projected on? Or the decal itself (a "small" rectangle, but one that can be "wrapped" on a surface).

>> c) see if any of the pixels of the triangle will be covered by a decal, if >> so add the triangle & the tex coordinates to a vertex buffer.
Probably I need to understand step A and B first.

By the way, why using a VBO? I know a VBO renders geometry faster, but I don't think there will be that much decal meshes. Especially not when using a relative small list (maximum 50 decals or something). So far I only used static VBO's. From what I know, updating a VBO takes somewhat more time (although putting all the stuff in lists takes time as well).

thanks again,
Rick

This topic is closed to new replies.

Advertisement