$ssbump: Difference between revisions
RabidMonkey (talk | contribs) m (removed '60 is a good starting value' - we've found our bumps generated with this value to be too strong and inaccurate) |
(Style, grammar) |
||
(60 intermediate revisions by 27 users not shown) | |||
Line 1: | Line 1: | ||
{{LanguageBar}} | |||
{{this is a|shader parameter|name=$ssbump|since=Source 2007}} | |||
[[File:Ssbump examples.jpg|right|thumb|256px|Comparing SSBump with standard bump mapping and no mapping at all.]] | |||
It is a boolean parameter that flags a {{ent|$bumpmap}} texture as being a self-shadowing [[bump map]]. | |||
Standard bump maps only darken [[texel]]s that are facing away from a light source. Self-shadowing bump maps darken both texels facing away and also any texels which are 'behind' them, similar to Ambient Occlusion maps in modern game engines. You can read more about the technology behind it [https://steamcdn-a.akamaihd.net/apps/valve/2007/SIGGRAPH2007_EfficientSelfShadowedRadiosityNormalMapping.pdf in this paper]. | |||
{{tip|Self-shadowed normal mapping actually renders ''faster'' than standard normal maps! The precise reasons for this can be found in the paper above (see pages 1, 4 and section 3).}} | |||
[[ | ==Example== | ||
[[ | [[File:Rockwall cave 02a height-ssbump.jpg|thumb|256px|rockwall_cave_02a_height-ssbump.vtf]] | ||
[[File:Face-ssbump.jpg|thumb|256px|A simpler example: each surface is flat.]] | |||
< | {{CodeBlock|lines=9|src=rockwall_cave_02a_height-ssbump.vmt|[[LightmappedGeneric]]<nowiki> | ||
{ | { | ||
$basetexture nature/rockwall_cave02a | $basetexture nature/rockwall_cave02a | ||
$surfaceprop concrete | $surfaceprop concrete | ||
$bumpmap nature/rockwall_cave_02a_height-ssbump | $bumpmap nature/rockwall_cave_02a_height-ssbump | ||
$ssbump | $ssbump 1 | ||
$ | $ssbumpmathfix 1 | ||
} | }</nowiki>}} | ||
{{note|An ssbump can also be used as a [[$detail|detail texture]] on non-fullbright [[brush]]es and [[displacement]]s, with [[$detailblendmode|blend modes 10 or 11]] being automatically chosen if the texture has the ssbump [[VTF]] flag, depending upon whether the material has a [[normal map]].}} | |||
== | == $ssbumpmathfix == | ||
The parameter addresses an issue with SSBump textures being too bright.<br> | |||
It can be found in the VMT's of {{as|2}}, {{csgo|2}}, {{l4d2|2}}, {{bms|2}} and {{p2|2}}<br> | |||
However the parameter itself does not appear to be functional in some of them.<br> | |||
{{confirm|Which one does it work in? Confirmed : {{l4d2}}}} | |||
{{note|Does not work in {{csgo}}, however the textures still appear to have adequate brightness.}} | |||
{{expand|title=Explanation:| | |||
The parameter addresses the issue of SSBump using non-unit vectors, unlike their regular bump mapping. | |||
More specifically, unlike the <code>.x</code> and <code>.y</code> components of the bump basis, the <code>.z</code> components don't cancel out. | |||
The maximum range of the result is equal to the sum of the <code>.z</code> components. <code>3* (1.0f / sqrt(3.0f))</code> or <code>1.73205f</code> | |||
This causes SSBumps to be much too bright. | |||
Luckily, this can retroactively be accounted for by multiplying the result with <code>Desired_Range / Current_Range</code> or numerically<code>1.0f / 1.73205f</code>. | |||
{{note|It can easily be tested that this fix is applied in {{l4d2|2}} using the following method. | |||
1. Compare a <code>$ssbump</code> material using <code>$ssbumpmathfix</code> and a <code>$color</code> value of <code>1.73205</code> with the same material without both. | |||
2. Compare a <code>$ssbump</code> Material using <code>$ssbumpmathfix</code> with the same material without <code>$ssbumpmathfix</code> and a <code>$color</code> value of <code>0.57735</code>}} | |||
{{important|This issue appears to affect most, if not all, publically available SSBump generators, including Valve's. }} | |||
}} | |||
{{tip|This fix can still be applied in Source branches that don't have native support for <code>$ssbumpmathFix</code>. Multiply your <code>$color</code> parameter by <code>0.57735</code> (or, if not present, simply add <code>$color 0.57735</code>). | |||
This works because <code>$color</code> is applied specifically to the lightmap in the shader.}} | |||
The shadows cast by the bump map are permanently baked into the texture, [http://www.interlopers.net/forum/viewtopic.php?f=16&t=27513 meaning that they can only appear in one of three predefined locations]. <code>height2ssbump</code> generates shadows for light arriving from the top, bottom | ==Limitations== | ||
The shadows cast by the bump map are permanently baked into the texture, [http://www.interlopers.net/forum/viewtopic.php?f=16&t=27513 meaning that they can only appear in one of three predefined locations]. <code>height2ssbump</code> generates shadows for light arriving from the right, top-left, and bottom-left of the texture. {{idea|Add angles or specific description of exactly what direction each channel's "light" uses}} If light arrives from between those directions (such as from the left), the nearest available baked shadows are blended between, producing an acceptable but hardly ideal image. | |||
Additionally, in order to preserve the illusion of height low areas of a SSBumped material will receive less light even if it arrives head-on. This can look odd if you have too intense (rugged) a SSBump. | Additionally, in order to preserve the illusion of height, low areas of a SSBumped material will receive less light even if it arrives head-on. This can look odd if you have too intense (rugged) a SSBump. | ||
SSBumps require bumped lightmaps. As such, they are only supported on [[brush]]es and [[displacement]]s when using vanilla shaders, and implementing them on custom model shaders is non-trivial. | |||
== Creation == | == Creation == | ||
You need to use '''<code>height2ssbump</code>''', a [[command line]] SDK tool. The command is: | |||
{{pre|<nowiki>height2ssbump <options> <path\to\</nowiki>[[heightmap]]<nowiki>.tga> <</nowiki>[[float]]<nowiki>|bumpscale></nowiki>}} | |||
The output is <code><input name>-ssbump.tga</code>, in the same folder as the input file. <code>Bumpscale</code> controls the intensity of the ssbump (i.e., coarseness of the surface); {{code|10.0}} is a good starting point. | |||
{{note|Bizarrely, the tool examines ''only the [[alpha channel]] of the input TGA''. The original alpha channel will be passed on to the output TGA, but serves no purpose and should be deleted. A tutorial on how to embed a heightmap in an image's alpha channel can be found [[Creating_PBR_materials#Embedding_the_Heightmap|here]] (While this is for embedding it in the alpha channel of a normal map, the same procedure still applies).}} | |||
{{ | {{warning|Height2SSBump may crash if it is given too large of an input image. Images 2048x2048 or greater are confirmed to crash the tool.}} | ||
{{bug|'''{{code|height2ssbump}}''' is currently non-functional in {{Strata|4}} games. Use {{portal2|4}}'s instead. For [[Authoring_Tools/Counter-Strike:_Global_Offensive#Availability|users with Prime Status]], {{csgo|4}}'s is also an option (switch {{cs2|4}} to the {{code|csgo_legacy}} branch and install the {{csgotools|4|nt=1}} necessary to access '''{{code|height2ssbump}}''')}} | |||
You can use '''<code>normal2ssbump</code>''', another SDK tool, to generate an SSBump from a ''normal'' bump map (as opposed to a height or displacement map) - Unlike '''<code>height2ssbump</code>''' you do not need to run through the [[command line]] or use any additional parameters; simply drag-and-drop your normal map onto the program or a shortcut. | You can use '''<code>normal2ssbump</code>''', another SDK tool, to generate an SSBump from a ''normal'' bump map (as opposed to a height or displacement map) - Unlike '''<code>height2ssbump</code>''' you do not need to run through the [[command line]] or use any additional parameters; simply drag-and-drop your normal map onto the program or a shortcut. | ||
{{important|SSBumps created from normal maps won't have any ambient occlusion information, unlike those created from height maps, as normal maps are effectively already "flat".}} | |||
{{tip|If you are generating an SSbump from a Valve-created heightmap, you may need to remove the alpha channel from the heightmap first, and then copy the Green channel into a replacement Alpha channel in order to generate the SSbump correctly. This can be caused by leftover [[Specular]] maps in the Alpha channel most likely used in the generation of [[$envmapmask|Env map masks]] that are stored in the alpha channel of a [[Normal_Maps|Normal map]] and enabled via the {{ent|$normalmapalphaenvmapmask}} material parameter.}} | |||
{{note|Height2ssbump uses different bumpscale values than {{height2normal|2}}.}} | |||
[[File:Valve_Heightmap_SSbump_Alpha_differences.png|thumb|256px|Difference in generating an SSbump from Valve heightmaps that have preexisting alpha channels.]] | |||
[[File:height2ssbump bumpscale.jpg|thumb|256px|A showcase of how bumpscale values affect the output of height2ssbump.]] | |||
=== Options === | === Options === | ||
;<code><path/filename></code> | |||
;<path/filename> | |||
:The source [[heightmap]] (TGA format). | :The source [[heightmap]] (TGA format). | ||
;-r <[[ | ;<code>-r <[[int]]></code> | ||
:Set the number of 'rays' (default 250). More rays take more time. | :Set the number of 'rays' (default 250). More rays take more time. | ||
; | ;<code>-n</code> | ||
:Generate a conventional bump map as <code><input name>-bump.tga</code>. | :Generate a conventional bump map as <code><input name>-bump.tga</code>. | ||
;-A | ;<code>-d</code>{{since|{{l4d}}}}{{also|{{src13}}}} | ||
:Generate an ssbump detail texture, used with {{cmd|$detailblendmode}} 10 and 11. | |||
:{{modernConfirm|How does this differ from a making regular SSBump? [https://github.com/ValveSoftware/source-sdk-2013/blob/0d8dceea4310fde5706b3ce1c70609d72a38efdf/mp/src/public/bitmap/float_bm.h#L60 public/bitmap/float_bm.h] has a description.}} | |||
;<code>-A</code> | |||
:Generate ambient occlusion in the alpha channel. | :Generate ambient occlusion in the alpha channel. | ||
;-D | ;<code>-f <int></code> | ||
:Set smoothing filter radius (default 10; 0 disables). | |||
;<code>-D</code> | |||
:Write out filtered result as <code>filtered.tga</code>. | :Write out filtered result as <code>filtered.tga</code>. | ||
An example of a complete command is: | |||
{{pre|<nowiki>height2ssbump -r 275 "C:\Path\to\example-height.tga" 35</nowiki>}} | |||
=== Third Party Tools === | === Third Party Tools === | ||
Third-party tools capable of generating SSbump maps: | Third-party tools capable of generating SSbump maps: | ||
*[https://danacief.gumroad.com/l/height2ssbump? Substance Designer Utility Node] | |||
*[http://www.filterforge.com/filters/9643.html Filter Forge 2.0] | *[http://www.filterforge.com/filters/9643.html Filter Forge 2.0] | ||
*[http://www. | *[http://www.xnormal.net/1.aspx Xnormal] (In Tools, select 'Height map to normal map', then tick 'Radiosity NM') | ||
*[ | *[https://sourceforge.net/projects/ssbumpgenerator/ SSbump Generator] | ||
{{modernConfirm|Most of these tools support generating SSBumps from heightmaps and/or normal maps, but do any of them support baking an existing AO map into the generated SSBump?}} | |||
{{sdktools}} | |||
[[Category: | [[Category:Shader parameters|ssbump]] | ||
[[Category:VMT Lighting]] |
Latest revision as of 13:43, 2 September 2025


$ssbump
is a material shader parameter available in all Source games since
Source 2007.
It is a boolean parameter that flags a $bumpmap texture as being a self-shadowing bump map.
Standard bump maps only darken texels that are facing away from a light source. Self-shadowing bump maps darken both texels facing away and also any texels which are 'behind' them, similar to Ambient Occlusion maps in modern game engines. You can read more about the technology behind it in this paper.

Example

$ssbumpmathfix
The parameter addresses an issue with SSBump textures being too bright.
It can be found in the VMT's of Alien Swarm,
Counter-Strike: Global Offensive,
Left 4 Dead 2,
Black Mesa and
Portal 2
However the parameter itself does not appear to be functional in some of them.
The parameter addresses the issue of SSBump using non-unit vectors, unlike their regular bump mapping.
More specifically, unlike the ![]() ![]() 1. Compare a $ssbump Material using $ssbumpmathfix with the same material without $ssbumpmathfix and a $color value of 0.57735 ![]() |

$ssbumpmathFix
. Multiply your $color
parameter by 0.57735
(or, if not present, simply add $color 0.57735
).
This works because $color
is applied specifically to the lightmap in the shader.Limitations
The shadows cast by the bump map are permanently baked into the texture, meaning that they can only appear in one of three predefined locations. height2ssbump
generates shadows for light arriving from the right, top-left, and bottom-left of the texture.

If light arrives from between those directions (such as from the left), the nearest available baked shadows are blended between, producing an acceptable but hardly ideal image.
Additionally, in order to preserve the illusion of height, low areas of a SSBumped material will receive less light even if it arrives head-on. This can look odd if you have too intense (rugged) a SSBump.
SSBumps require bumped lightmaps. As such, they are only supported on brushes and displacements when using vanilla shaders, and implementing them on custom model shaders is non-trivial.
Creation
You need to use height2ssbump
, a command line SDK tool. The command is:
height2ssbump <options> <path\to\heightmap.tga> <float|bumpscale>
The output is <input name>-ssbump.tga
, in the same folder as the input file. Bumpscale
controls the intensity of the ssbump (i.e., coarseness of the surface); 10.0 is a good starting point.








You can use normal2ssbump
, another SDK tool, to generate an SSBump from a normal bump map (as opposed to a height or displacement map) - Unlike height2ssbump
you do not need to run through the command line or use any additional parameters; simply drag-and-drop your normal map onto the program or a shortcut.




Options
<path/filename>
- The source heightmap (TGA format).
-r <int>
- Set the number of 'rays' (default 250). More rays take more time.
-n
- Generate a conventional bump map as
<input name>-bump.tga
. -d
(in all games since)(also in
)
- Generate an ssbump detail texture, used with $detailblendmode 10 and 11.
Confirm:How does this differ from a making regular SSBump? public/bitmap/float_bm.h has a description.
-A
- Generate ambient occlusion in the alpha channel.
-f <int>
- Set smoothing filter radius (default 10; 0 disables).
-D
- Write out filtered result as
filtered.tga
.
An example of a complete command is:
height2ssbump -r 275 "C:\Path\to\example-height.tga" 35
Third Party Tools
Third-party tools capable of generating SSbump maps:
- Substance Designer Utility Node
- Filter Forge 2.0
- Xnormal (In Tools, select 'Height map to normal map', then tick 'Radiosity NM')
- SSbump Generator

|