MOTIVATION
The idea for this sprang to life during the development of our seventh game project at The Game Assembly; a third person survival horror game inspired by games like Silent Hill and Resident Evil.
We wanted the action to feel impactful and somewhat gruesome to fit the themes of the game, which is why we opted to put a lot of work into trying something that would make the player really feel like their actions affected the enemies.
GOAL
The initial goal was to allow in-game information like positions of objects to be drawn to a separate texture that could then be used as a mask to blend between different materials, similar to how Unreal Engine uses Render Target Textures. This would then be used to facilitate the dynamic damage system for our game.
Halfway through the project however I decided that this more generic solution was a bit too ambitious and after stumbling upon a GDC presentation by Alex Vlachos1 where he described how they had approached the wound rendering in Left 4 Dead 2, I was inspired to instead focus on getting the dynamic wounds to look as polished as possible.
TIMELINE
My first idea was to simply get the world position of the point where a bullet or weapon had hit, move that in to the local space of the mesh that was hit, and then calculate the closest vertex to that point so that I could draw to the mask based on that vertex’s UV-coordinates. In our engine however we don’t expose mesh vertices as they are placed into DirectX buffers as soon as they are loaded into memory, which meant I had to do this a bit differently.
I had just implemented decals into our engine and figured I could use that for this as well, except that instead of drawing to the gbuffer I would draw directly to the texture mask of the object.
What ended up happening though was that regardless of where the decal was placed on the mesh it would always be drawn to the center of the texture mask.
Projected textures?
I figured I had to transform the decal projection box’s vertices into the texture space of the target mesh. This however didn’t go very well because what I ended up with wasn’t terribly accurate, and it also didn’t work for UV-wrapped meshes.
I spent a lot of time trying to figure out how to accurately project one texture onto another texture, scouring the internet for resources on the subject, and while some solutions seemed promising I ultimately could not get it to work for my use case.
Sphere masks?
After a lot of trial and failure I figured I would approach the problem from another angle. I found an article by Tom Looman2 where he talks about rendering wounds on characters, but instead of drawing to a render target that would act as a mask, the world position of the hit is used to create a sphere mask inside the shader of the object.
This has the downside of making the shader linearly more expensive based on how many masks you want to have active at the same time. The silver lining here is that it doesn’t require us to perform another texture sampling operation.
Based on our game I figured that keeping the data of six sphere masks would be sufficient, since enemies do not take that many bullets to kill, so when the last sphere mask has been reached the next spheremask will overwrite the oldest one. This could result in some strange visuals but usually the limit won’t be reached and it’s preferable that the player gets the feedback of having dealt damage even if it means an old wound will disappear.
Moving the mesh
Here it’s demonstrated on an animated skeletal mesh. When the damage is added, I go through all the joints of the target skeletal mesh and attach it to the closest one.
The effect works pretty well, but has some quirks where the sphere masks can sometimes intersect with limbs that are supposed to be unaffected if they move into its area of effect.
Getting the data to the GPU
While investigating this method of sphere masks I had just been sending the data up through the object buffer, so to make this a bit cleaner I figured I would give the wounds its own object buffer so that not all entities in the scene have to carry that data.
When a dynamic damage component is created it is assigned a unique ID that decides what slot in the dynamic damage buffer it will use which is in turn set in the object buffer of the entity. The ID is just a static unsigned integer that gets incremented for each component created. I haven’t added any sort of safeguard to make sure that the ID takes over unused IDs so eventually it will surpass the MAX_TARGETS amount, but for our game this is fine since we do not have that many enemies present.
The mask index controls what color channel of the lerp value that should be used for that sphere mask. The red channel blends the base material with the gore-material (Used for gunshot wounds), and the green channel blends with the bruise-material (Used for melee hits).

REFLECTION
While the implementation ended up working well for our use case, it wasn’t perfect. If I had more time I would have explored ways of reducing the sphere masks “bleeding” into other parts of the mesh, or maybe use a noise texture to blend the edges of the wounds.
Like I mentioned earlier with the IDs I could improve the system by implementing some way for new enemies to take over old unused IDs from deceased enemies, maybe through an ID manager that can keep track of which IDs are in use and which can be released, to hand these out when needed. In order to reduce the amount of data in the constant buffer these IDs could also be given out when the enemy becomes active rather than when the component is created (Many of our enemies are inactive until a certain trigger is reached).
I would also like to give credit to two people who were involved with the making of this feature: William Mårtensson & Alexander Thambert, since it was in large part due to them that the wound system turned out as good as it did. William created the enemy mesh and its materials, and Alexander prototyped the feature in Unreal as well as offering valuable testing of the system during development.
References:
1. “Rendering Wounds in Left 4 Dead 2”, by Alex Vlachos, GDC 2010
2. “Rendering Wounds on Characters”, by Tom Looman, 2017