Decals: Difference between revisions
(→Application: creating decals programmatically) |
(→Application: added how to add decals in server code) |
||
Line 51: | Line 51: | ||
void C_BaseEntity::AddStudioDecal( const Ray_t& ray, int hitbox, int decalIndex, | void C_BaseEntity::AddStudioDecal( const Ray_t& ray, int hitbox, int decalIndex, | ||
bool doTrace, trace_t& tr, int maxLODToDecal );</pre> | bool doTrace, trace_t& tr, int maxLODToDecal );</pre> | ||
In server code, this can be achieved via engine->StaticDecal: | |||
<pre>void IVEngineServer::StaticDecal( const Vector &originInEntitySpace, int decalIndex, int entityIndex, int modelIndex, bool lowpriority );</pre> | |||
Decal indices can be obtained by calling decalsystem->GetDecalIndexForName or UTIL_PrecacheDecal: | |||
<pre>int IDecalEmitterSystem::GetDecalIndexForName( char const *decalname ); // Valid decalnames are defined in scripts/decals_subrect.txt | |||
int UTIL_PrecacheDecal( const char *filename, bool preload );</pre> | |||
{{note|For decals placed in code that are meant to be applied to models (such as blood), the <code>[[VertexLitGeneric]]</code> shader should be used instead of <code>LightmappedGeneric</code>. <code>LightmappedGeneric</code> is used for decals applied to world geometry.}} | {{note|For decals placed in code that are meant to be applied to models (such as blood), the <code>[[VertexLitGeneric]]</code> shader should be used instead of <code>LightmappedGeneric</code>. <code>LightmappedGeneric</code> is used for decals applied to world geometry.}} |
Revision as of 10:13, 3 February 2009
When the player shoots his or her weapon into a wall, the marks left by the bullet impacts are called "decals". These are most easily thought of as materials that are applied to a surface and remain there as an indelible mark on the world. Posters, scorch marks, and stenciled letters can all be created using this type of graphic. Decals will clip their extents to whatever surface they are placed on to. For example, a decal applied to a staircase would cascade down on to each stair surface instead of hanging out into space. You can also think of this as how a stencil would apply a mark to the world.
Creating decals is straightforward: they are simply materials generally having an alpha channel mask of some sort, and possible using the DecalModulate
shader. Before reading this article, please read about the basics of material creation.
Standard decals
The most simple type of decal is one that simply acts like a true decal or stencil: source art is clipped and projected on to the world within some mask, specified via the material's alpha channel (centre):
Material parameters
A decal's material looks something like this:
LightmappedGeneric { $basetexture decals\mydecal $decal 1 $decalscale 0.1 $translucent 1 $modelmaterial decals\mydecal_model }
$decal <bool>
- Marks the material as a decal. Without it, the decal will not be clipped or projected onto the world properly.
$decalscale <float>
- Important because its default is one pixel to one inch. If the source texture for this decal is 128 pixels, a value of
0.1
will cause it to be 12.8 inches in size in the engine (about a foot). $translucent <bool>
- See
$translucent
. $modelmaterial <material>
- Separate
VertexLitGeneric
material to apply to models, if applicable. $decalfadeduration <float>
- Amount of time to spend fading out. Requires
$vertexcolor
. $decalfadetime <float>
- Delay before fadeout begins.
$decalsecondpass
- Todo: ??
Application
Once the material has been created the decal can be placed in Hammer with the Overlay or Decal tools.
Decals can be created in C++ in clientside code via C_BaseEntity::AddDecal(). Internally this calls C_BaseEntity::AddStudioDecal or C_BaseEntity::AddBrushModelDecal depending on the entity's model (ie. whether the entity is a brush entity). Parameters for these functions:
void C_BaseEntity::AddDecal( const Vector& rayStart, const Vector& rayEnd, const Vector& decalCenter, int hitbox, int decalIndex, bool doTrace, trace_t& tr, int maxLODToDecal ); void C_BaseEntity::AddBrushModelDecal( const Ray_t& ray, const Vector& decalCenter, int decalIndex, bool doTrace, trace_t& tr ); void C_BaseEntity::AddStudioDecal( const Ray_t& ray, int hitbox, int decalIndex, bool doTrace, trace_t& tr, int maxLODToDecal );
In server code, this can be achieved via engine->StaticDecal:
void IVEngineServer::StaticDecal( const Vector &originInEntitySpace, int decalIndex, int entityIndex, int modelIndex, bool lowpriority );
Decal indices can be obtained by calling decalsystem->GetDecalIndexForName or UTIL_PrecacheDecal:
int IDecalEmitterSystem::GetDecalIndexForName( char const *decalname ); // Valid decalnames are defined in scripts/decals_subrect.txt int UTIL_PrecacheDecal( const char *filename, bool preload );

VertexLitGeneric
shader should be used instead of LightmappedGeneric
. LightmappedGeneric
is used for decals applied to world geometry.Using modulation
For decals intended to mimic the look of pock marks or dents in a surface, the DecalModulate
(a.k.a. mod2x) shader is especially suitable: it lightens destination pixels for every source pixel that is over mid-range gray (128) and darkens any destination pixels for every source pixel that is below mid-range gray. This effect can be used to give the impression of depth when applied to a surface.
To begin, create a source image whose color channel will be used for the modulation's source values. Again, light values will lighten pixels they're drawn over, while dark values will darken the destination pixels. Mid-gray values will be treated as translucent.
Next, create an alpha channel that defines a mask for the decal. Because modulation cannot have an exact middle value currently, the mask is necessary to prevent "bordering" from occurring around the decal.
Finally, you must create a material that uses the DecalModulate
shader. Neither $translucent
nor $decal
are needed this time.