Decals: Difference between revisions
| SirYodaJedi (talk | contribs)  (→Hammer) | SirYodaJedi (talk | contribs)  m (→C++:  remove border from code) | ||
| Line 37: | Line 37: | ||
| Created in response to impacts, blood, and so on. Limited in number by the value of [[r_decals]], [[CRecipientFilter#Reliable vs. Unreliable|unreliable]] when transmitted, and not transmitted to players who connect after creation. | Created in response to impacts, blood, and so on. Limited in number by the value of [[r_decals]], [[CRecipientFilter#Reliable vs. Unreliable|unreliable]] when transmitted, and not transmitted to players who connect after creation. | ||
| {{note|Only materials registered in < | {{note|Only materials registered in <tt>scripts/decals_subrect.txt</tt> can be used!}} | ||
| ; < | ; <tt>CBaseEntity::DecalTrace([[trace_t]]* pTrace, const char* decalName)</tt> | ||
| : Shared code. The trace defines where the decal is projected from and its location. {{todo|How to avoid transmission being suppressed due to prediction?}} | : Shared code. The trace defines where the decal is projected from and its location. {{todo|How to avoid transmission being suppressed due to prediction?}} | ||
| ; < | ; <tt>C_BaseEntity::AddDecal( <lots of args> );</tt> | ||
| : Client function where the decal is actually created. In most cases you are better off just calling < | : Client function where the decal is actually created. In most cases you are better off just calling <tt>DecalTrace()</tt>. | ||
| ==== Static ==== | ==== Static ==== | ||
| Line 48: | Line 48: | ||
| Normally created by the level designer. These decals last forever and are always transmitted, including to players who connect later on. Any material can be used. | Normally created by the level designer. These decals last forever and are always transmitted, including to players who connect later on. Any material can be used. | ||
| ; < | ; <tt>engine->StaticDecal( Vector localOrigin, int decalIndex, int entityIndex, int modelIndex, bool lowpriority )</tt> | ||
| : Server only. This system does not appear use entities. | : Server only. This system does not appear use entities. | ||
| :; < | :; <tt>Vector localOrigin</tt> | ||
| :: Where the decal will be created, relative to the target's origin. | :: Where the decal will be created, relative to the target's origin. | ||
| :; < | :; <tt>int decalIndex</tt> | ||
| :: A value received from < | :: A value received from <tt>UTIL_PrecacheDecal()</tt>. ''Don't'' use <tt>GetDecalIndexForName()</tt>. | ||
| :; < | :; <tt>int entityIndex</tt> | ||
| :; < | :; <tt>int modelIndex</tt> | ||
| :: Information about the target entity. | :: Information about the target entity. | ||
| :; < | :; <tt>bool lowpriority</tt> | ||
| :: Low priority decals are not saved/restored, and can be "re-used on the client preferentially". | :: Low priority decals are not saved/restored, and can be "re-used on the client preferentially". | ||
| ; < | ; <tt>UTIL_PrecacheDecal(const char *filename, bool preload)</tt> | ||
| : Returns a decal index for use with < | : Returns a decal index for use with <tt>StaticDecal()</tt>. If this is in <tt>[[precache()]]</tt>, remember that it may be called statically; store the result in a global var. | ||
| == Creating == | == Creating == | ||
Revision as of 17:53, 17 February 2025
Decals are materials projected onto existing surfaces. They can be placed by the level designer, and are also generated by the engine for bullet impacts, blood, and other effects.
 Note:Each decal affects one entity only. (The world is one big entity.)
Note:Each decal affects one entity only. (The world is one big entity.)Decals are "sprayed" from a location and mark every surface in their path. For instance, a decal applied downward onto a staircase would cascade down onto the top (but not front) of each step.
Using
 Note:VertexLitGeneric decals won't show up on brushes, and LightmappedGeneric ones won't appear on models. Decals using
Note:VertexLitGeneric decals won't show up on brushes, and LightmappedGeneric ones won't appear on models. Decals using DecalModulate or $modelmaterial work everywhere (see below).Hammer
- Decal tool  
- Creates infodecal entities, which decal brushes and displacements.
- info_projecteddecal
- An entity that decals models or displacements (but not brushes). The angle of projection can be set, allowing for distortion.
- Overlay tool  
- Overlays are manipulatable decals on brushes and displacements that offer level designers more control.
infodecal and info_projecteddecal create edicts that last until the decal is sprayed (for unnamed decals, this is a split second after the map spawns). info_overlay only creates edicts if named.
 Tip:If a decal entity has a name it will appear when used (i.e. blank input) or on receiving the
Tip:If a decal entity has a name it will appear when used (i.e. blank input) or on receiving the activate input, instead of when the map starts. The entity then disappears. Note:Decals can also be made out of brushes or displacements using
Note:Decals can also be made out of brushes or displacements using $decal materials, by having the decal be coplanar to the face that it is decaling. Due to VBSP performing a CGG pass on map geometry, however, decal brushes which aren't part of a separate bmodel (i.e. using func_illusionary) may not reliably appear in-game. Additionally, brush-based decals will use additional brushsides.
 Confirm:func_detail-based decals will reliably show up on structural world brushes and brush entities, but what about on other func_details?
 Confirm:func_detail-based decals will reliably show up on structural world brushes and brush entities, but what about on other func_details?C++
Standard
Created in response to impacts, blood, and so on. Limited in number by the value of r_decals, unreliable when transmitted, and not transmitted to players who connect after creation.
 Note:Only materials registered in scripts/decals_subrect.txt can be used!
Note:Only materials registered in scripts/decals_subrect.txt can be used!- CBaseEntity::DecalTrace(trace_t* pTrace, const char* decalName)
- Shared code. The trace defines where the decal is projected from and its location. Todo: How to avoid transmission being suppressed due to prediction?
- C_BaseEntity::AddDecal( <lots of args> );
- Client function where the decal is actually created. In most cases you are better off just calling DecalTrace().
Static
Normally created by the level designer. These decals last forever and are always transmitted, including to players who connect later on. Any material can be used.
- engine->StaticDecal( Vector localOrigin, int decalIndex, int entityIndex, int modelIndex, bool lowpriority )
- Server only. This system does not appear use entities.
- Vector localOrigin
- Where the decal will be created, relative to the target's origin.
- int decalIndex
- A value received from UTIL_PrecacheDecal(). Don't use GetDecalIndexForName().
- int entityIndex
- int modelIndex
- Information about the target entity.
- bool lowpriority
- Low priority decals are not saved/restored, and can be "re-used on the client preferentially".
 
- UTIL_PrecacheDecal(const char *filename, bool preload)
- Returns a decal index for use with StaticDecal(). If this is in precache(), remember that it may be called statically; store the result in a global var.
Creating
- This section assumes that you understand the basics of material creation.
Any material can be used as a decal. They generally have an alpha channel however, and can use some special parameters and/or the DecalModulate shader.
Material parameters
- $decal <bool>
- Prevents decal texture clipping.
 Note:This parameter is not exclusive to decal entities; any material can have $decal to modify how it is sorted when coplanar with another surface. Note:This parameter is not exclusive to decal entities; any material can have $decal to modify how it is sorted when coplanar with another surface.
- $decalscale <float>
- Same as a brush face's texture scale value: the number of units that each texel covers. Normally 0.25 or lower.  Note:This defines the size of the decal's geometry, and cannot be changed after its creation. Use $basetexturetransform if you want motion. Note:This defines the size of the decal's geometry, and cannot be changed after its creation. Use $basetexturetransform if you want motion.
- $modelmaterial <material>
- A separate VertexLitGenericmaterial to that will replace this one if the decal hits a model.
- $decalfadeduration <float>
- Amount of time to spend fading out. Requires $vertexcolor.
 Bug: This is broken in
Bug: This is broken in  Source 2013, decals will not fade out  [todo tested in ?]
 Source 2013, decals will not fade out  [todo tested in ?]- $decalfadetime <float>
- Delay before fadeout begins.
 Bug: This is broken in
Bug: This is broken in  Source 2013, decals will not fade out  [todo tested in ?]
 Source 2013, decals will not fade out  [todo tested in ?]- $decalsecondpass <bool>
- ALWAYS render this decal on top of decals without this parameter. If two decals with this parameter intersect, they will treat each other how two without the parameter would.
- $fogscale <float>
- Template:L4D2 add Scales the amount of fog affecting the decal. Useful for making important decals stand out in foggy levels.
- $splatter <bool>
- Template:CSGO add Todo: What does this do?
Decals do not support normal maps in all engine branches prior to CS:GO. The underlying brushes/displacements must have bumped lightmaps for the decal's normal map to have any effect.
 Confirm:Is CS:GO the first game to support this feature? Confirm:Is CS:GO the first game to support this feature?
DecalModulate
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 with DXTn compression, the mask is necessary to prevent "bordering" from occurring around the decal. You can avoid "bordering" without creating an alpha channel simply by using BGR888 format instead of DXT1/DXT5 when you create your VTF, at the cost of being triple the file size.
 Confirm:Does I8 (greyscale) work, like with
 Confirm:Does I8 (greyscale) work, like with $detailblendmode 0, or does the shader require RGB data? I8 is the same size as DXT5, and but accurately represent all 256 possible modulation values (albeit without color). Note:It has also been observed in
Note:It has also been observed in  Left 4 Dead 2 that DXT1 compressed textures using DecalModulate shader (such as blood splatters and "graffiti wall writing") with background colors RGB 124 126 124 are considered unmodulated, alleviating "bordering". L4D2's vtex will output that specific color from the source image pixels are gray RGB 127 127 127. This solution may also apply to other engine branches (and other versions of vtex) that use RGB 124 126 124 as the color indicating lack of modulation in-game, but needs further testing.
 Left 4 Dead 2 that DXT1 compressed textures using DecalModulate shader (such as blood splatters and "graffiti wall writing") with background colors RGB 124 126 124 are considered unmodulated, alleviating "bordering". L4D2's vtex will output that specific color from the source image pixels are gray RGB 127 127 127. This solution may also apply to other engine branches (and other versions of vtex) that use RGB 124 126 124 as the color indicating lack of modulation in-game, but needs further testing.Finally, you must create a material that uses the DecalModulate shader. Neither $translucent nor $decal are needed this time.
 Tip:DecalModulate is equivalent to the "Overlay" layer mode in image editors such as
Tip:DecalModulate is equivalent to the "Overlay" layer mode in image editors such as  GIMP or
 GIMP or  Adobe Photoshop.
 Adobe Photoshop.






























 Split
 Split

