Decals in a Foward renderer

I did a bit of searching but I admit I’m having a hard time finding a good example of a decal system for MonoGame. While I do plan to use it for battle damage (It’s a starship simulator), I want to use decals for the ship name and designation. Think the Enterprise having a standard texture for the ship, then having decals for the NCC-1701 label on the hull (ETC).

I’ve see some decal examples in deferred renderers but I admit they were a bit to deeply coupled into their respective engines for me to follow along.

You can just use a second texture for the model which has the decal on it or have the decal directly on the base texture (or place it there during runtime)

that’s the normal way.

another way, is to render all geometry twice with it’s own projection matrix … but that’s only feasible for high dynamic decals.

But if you render twice anyway, you could just use it to render the depth values and use a fullscreen pass for the decals, which would look better for randomly placed decals.

For the NCC-1701 I would either just place a second texture or integrate in the base texture in forward rendering

My issue is if I have 10-15 ships using the same model, using the base texture does not work, as I’d have to have 10-15 completely different base textures (and that isn’t remotely efficient).

If you want to keep at the forward renderer you’re a bit limited to the said possibilities I fear.

I guess, what you want is having 10-15 different ships with different texture each but you want to provide some decals and place them on those ships. You’d need information about where to place the decals anyway on a per ship basis, so it should be doable to provide just a texture of the decals and work out on CPU what the UV of that second texture should be (per ship) to fit where you want it.

or

place random decals on those ships (like shot holes or something). (I fear this is going to be solved with providing geometry which is created on CPU to fit the shape of the ship - basically quads aligned on surface)

Right traditional decal systems are geometry based. That’s exactly what I’m looking to do.

For this I would assign each ship their own rendertarget2D and draw the base ship texture to that rendertarget, then draw the decals on to it. Then simply replace the texture on the model with the rendertarget and boom, decals.

What I do is add more geometry for all the possible decals.

Then when I load the object I setup the textures for these decals.

In the render they are drawn in a second pass with a depth bias and a read only depth buffer.

Using this system all aircraft in a squadron can have the correct tail numbers. The same mesh can be used for different countries, etc.

The rendering cost is very small

StainlessTobii… That is exactly what I’m looking to do. Do you happen to have an example of this method?

I think he means creating that extra geometry together with the model (not during runtime) - which is also a good method to use - when you create your model in your 3d editor, you just add extra geometry and place them where the decals should be and they just use their own texture - now in your engine you just need to set the proper decal texture for that piece of geometry (which is already part of the model)

Yes, almost spot on.

My game objects are actually a tree of meshes.

The decals are a child object of the mesh they overlay.

I do it this way for many reasons. sub-meshes can be animated simply by altering their world matrix, they can be turned off to provide level of detail , they can be detached as a result of damage…

I also define damage meshes, so when the game object takes damage I can work out which part of the object took that damage and turn on a new mesh which displays that damage.

Have a look here https://www.sas1946.com/main/index.php/topic,59921.0.html

Hard decals are just clipping your geometry, while using a planar projection (clip-space XY normalized to 0-1 is good enough) to calculate the decal UVs on passing/new triangles, and slapping it all into another set of VBO/IBO (or appending if packing).

You can just construct an ortho matrix to describe the decal and extract the planes from that to use for clipping your input geometry. When you render you then use the offset-bias to avoid z-fighting or render the decal geometry with depth compare set to equal instead of the usual less_equal.

This made me think of the old cliche “easier said then done”… but how in programming it is often just the opposite.

“Easier done then said” lol. or maybe “easier to explain with code then words”.

Just cut a part out of your model and replace it with a mesh part that takes a separate decal texture. One drawback seems to me is that it has extra overhead to set up for on each model but it seems like that is pretty much part of the models responsibility to handle.

@willmotil indeed.

Here’s a gist that should be mostly complete:

I doubt it works out of the box, but it should be really close. Basically you pump a reference set of DecalFaces into Faces and then AddDecal does the work of clipping and appending that source data into a resolved set (as unindexed TRIANGLE_LIST).

1 Like