I want to create blood wounds on my character's bodies by using projected textures. I've watched some commentaries on games like Left 4 Dead and they say they use projected textures for the blood. But the way projected textures work is that if you project a texture on a rigged character, say his chest, it will also appear on his back. So what's the trick? How to get projected textures appear only on one "side" of the mesh?

I use the Panda3D game engine, if that will help.


2 Answers 2


It sounds like you are using ancient projected textures in a fixed-function pipeline. If that is true, you will not be able to solve your problem without a custom shader that checks the dot product of the blood-inducing vector to the vertex normal. However, if you can use programmable pipeline, you can abandon 90s and venture forth into 21 century with decals. Decals are being used for tasks such as blood marks, explosion craters, wall posters, etc. since forever.

Chances are, L4D devs meant that they used decals which were projected geometrically onto objects. Nice article about these decals can be found here.

If you're stuck with fixed pipeline, I guess the best approach is texture blending. For example, prepare bloody texture of some limb, and then blend it with the limb texture when said limb gets hit.

But in L4D the texture is projected on animated models. Will this work on animated models?

It is, of course, also possible to do skinned decals. The only difference I can see is that for an animated models you have to adjust the decal frustrum, so decal position will be adjusted back to the bind pose.

For example, here is one way of doing it. Represent the decal as a sphere and find the biggest colliding bone in current animation. Let's call it decalBone. Also let's say it stores the per-bone transformations in decalBone.Offset, and it's possible to get world transformations via decalBone.WorldTransform. Then your adjusted transformation will be something like targetDecalTransform = Matrix.Inverse(decalBone.WorldTransform * decalBone.Offset). Use it to adjust the raw decal frustrum centered on the world position.

With this frustrum you can now do the same thing you've already done with static model decals: get affected mesh faces, clip them against frustum, triangulate the resulting faces into decal vertices, calculate UVs and transform vertices to the mesh local space.

  • \$\begingroup\$ But in L4D the texture is projected on animated models. Will this work on animated models? As far as I know if the model moves or animates, the texture won't stay in place. That's not the case with L4D. \$\endgroup\$
    – user17402
    Jul 4, 2013 at 7:15
  • \$\begingroup\$ @user975135 I've edited answer a bit, hope it helps. \$\endgroup\$
    – EnoughTea
    Jul 5, 2013 at 18:15

Alternatively, you can combine your approach with shadow mapping in order to make it work dynamically and get correct occlusion. If you create a camera that renders its depth information into a texture set to the Texture.FT_shadow filter type, and then use a combination of texture modes (or a shader) to only apply your projected texture where the shadow map compare succeeds, that should do the trick.


You must log in to answer this question.