Author Topic: Decals and Nameplates  (Read 3435 times)

0 Members and 1 Guest are viewing this topic.

Offline Aardwolf

  • 211
  • Posts: 16,384
    • Minecraft
Re: Decals and Nameplates
A double-post was deemed necessary.

I wasn't 100% certain that people understand the concept I was proposing, or that the concerns people have brought up aren't things I had already taken into account, so I explained the whole concept on #SCP

The following is the IRC log, with most of the irrelevant comments/events removed for readability:

Quote
Aardwolf: i think i gotta explain first the storage / creation, and then the rendering.
Aardwolf: so, each ship would have associated with it a collection of "decals" (including nameplates, insignias, and "damage decals")
Aardwolf: (alternatively it might be associated with specific subobjects/submodels)
Zacam-Work: Associated how?
Aardwolf: well, there's more than one way to do it
Aardwolf: there could be a big table of all the decals in existence (i think that's how decals.cpp did it), and each ship (or submodel) would contain a collection of indices into that table
Aardwolf: basically just that somewhere in memory there's a list of decals (or multiple lists), and that each sublist goes with a specific model (or submodel)
Aardwolf: whether it's a list or a vector or a dictionary is at this point inconsequential
Aardwolf: there would be a decal structure, which all decals are instances of
Aardwolf: it would contain a reference (using the word in the loose sense, not a technical one) to a texture--i don't know the details of how bmpman does stuff, or how textures are normally referenced, but probably it'd be the same way
Aardwolf: additionally, it would have the info needed to get the vertex data; again, there's some wiggle-room with some details of the implementation, but basically each decal would need either a "hard copy" or some sort of reference to the vertex data of the submodel
Aardwolf: but considering a single submodel might be much bigger and more complicated than the area the decal covers, it might be better to store references to triangles of the submodel (a decal would typically only ever be on maybe 10 triangles anyway)
Aardwolf: then, for each vertex the decal is using, the decal would store a (u,v) texture coordinate
Aardwolf: i'm not sure if it matters whether it be on a per-unique-vertex basis or a per-triangle's-vertex basis. it might not matter, but one might be much easier to implement
Aardwolf: oh, one other thing; if there are multiple decals which use the same texture, but do not share any triangles, it might be useful to combine them into a single decal instance containing the combined data
Aardwolf: but if they would share a triangle, the decal would have to go into a new decal instance
Aardwolf: that's a little bit of an optimization though, just as a possibility, more than a "must do it this way"
Aardwolf: oh, lastly each decal would need to store some "timer" info, basically either a lifetime counter or a time when it will have "cooled down", so that the "burn" (decal glow) could fade or otherwise animate as the decal ages. probably the same as however animated textures work elsewhere, but without looping.
Aardwolf: Decal Creation:
Aardwolf: the nameplate/insignia decals would be defined (TBD later) in the model file, and would probably end up using texture replacement similar to how it works now
Aardwolf: they'd be instantiated when the ships come into existence (although because their geometry/texcoords are predetermined their could probably be some caching/other optimization done there as well)
FUBAR|Outside: how would a damage decal apply over a hull texture that is an eff already?
Aardwolf: when i get to the rendering part, i'll explain that, it should clear it up
FUBAR|Outside: Think shadow bio hull
Aardwolf: So yeah, damage decals (and any other sort of dynamically created decals, if there is a need for 'em) would be created at run-time. I don't know the best way (math-and-aesthetics-wise) to position and orient a decal on a surface, but that math would be done when a shot impacts (or whatever other event causes a decal to come into existence)
Aardwolf: Rendering:
Aardwolf: first, the ship is drawn as normally (depth testing on, depth mask on, etc.)
Aardwolf: next all of the decals on the ship get drawn...
Aardwolf: basically, depth test has to be on, and set to == mode. that is, if the depth of the pixel about to be drawn is equal to the depth already drawn on that pixel, it will draw, and otherwise it will not.
Aardwolf: because the decals would be using EXACTLY the same vertex coordinates as those of the ship's geometry, there's no need to worry about z-fighting. it will be a perfect match.
Aardwolf: depth mask (i.e. whether or not it writes to the depth buffer) could be set to false while drawing the decals...  the depths wouldn't be changing, so overwriting the depth values might be unnecessary, but i'm not sure if it matters, or whether there'd be any speed boost at all
Aardwolf: blending would have to be enabled and the blending should be set to use alpha opacity... the more opaque the decal, the more visible it is, and the less visible the stuff underneath (i.e. whatever was drawn previously)
Aardwolf: alpha testing could possibly be used to save having to draw where the opacity is zero, but i'm not sure if that matters, or how well that'd work with GLSL; i've never used the two together
Aardwolf: the decal textures themselves would be set up (using whatever function we've got that's doing glTexParam or equivalent) to clamp (or clamp to border) so they don't tile weirdly in parts that aren't inside the decal, the border would be set to 1 (that might actually be a glTexImage thing rather than a glTexParam option), and the border color set to transparent
Aardwolf: that way parts of the decal-affected triangles that aren't part of the decal aren't just not tiled, they're transparent. with blending on, whatever color was there previously will stay there...  it won't make the hull see-through
Aardwolf: then repeat the process for the rest of the decals. as i mentioned earlier, if some are using the same texture but don't share any geometry, it might be possible to combine them ... then again, if they use animated textures which aren't synchronized, that might not be possible until the animation finishes,
Aardwolf: ...unless FSO is using 3d textures for its animated effects. if it is, great. otherwise, decals with the same animated texture can't be combined
Aardwolf: i think that's pretty much it.