Lightmap: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
mNo edit summary
(added manual lightmap edition section)
 
(114 intermediate revisions by 23 users not shown)
Line 1: Line 1:
A lightmap is the static lighting data for each [[Brush]] face. This light data is applied additively to each surface texture to produce the final lit effect. Especially common in [[BSP]] based engines, it's the method used for most lighting effects within the source engine.
{{lang|Lightmap}}
{{tabsBar|main=gs2|base=Lightmap}}
{{toc-right}}


Determined during the [[vrad]] compile process lightmaps are only applied to brush faces as models are lit differently.  
A '''lightmap''' is a generated [[texture]] applied to [[brush]] faces to simulate [[lighting]]. The color values in the surface's [[diffuse]] or [[albedo]] are multiplied by the color values in its lightmap.


== Lightmap Scale ==
Lightmaps are created by [[VRAD]] each time a map is compiled, although [[VBSP]] allocates the lightmaps. They are static and cannot change, though it is possible to switch lightmap 'pages' on and off (see [[Naming Lights]]).
The '''lightmap scale''' determines how sharp or diffuse the static shadows will be on a particular facet. It is defined by the number of [[dimensions|game units]] per lightmap pixel (luxel). The default value in Hammer is 16 units/luxel. Smaller values increase the sharpness of shadows, but mean more luxels,  larger lightmap file size and slower compile times.
* In Hammer, the "lightmap" viewmode shows the lightmap scale on all surfaces in the camera view. For individual surfaces, view and edit lightmap scale in the [[Hammer_Face_Edit_Dialog|Face Edit Dialog]].
* Faces such as [[displacement]] maps calculate and use their own lightmap scale; different values will often get reset by Hammer to match the displacements' lightmap size.


[[image:intlight_lmap4.jpg|thumb|left|A lightmap scale of 4]]
In November 16, 2024, with the release of the {{Hl2|1}} 20th anniversary update, {{tf2|1}}'s February 18, 2025 patch (also includes {{css}}, {{dods}}, {{hl2dm}} and {{hldms}}), and later May 20, 2025 update for {{portal|1}}, lightmaps are now Bicubic filtered if the player set the video options to "Very High". This can be toggled independently with the {{cmd|r_lightmap_bicubic}} [[cvar]].
[[image:intlight_lmap16.jpg|thumb|left|A lightmap scale of 16]]
[[image:intlight_lmap64.jpg|thumb|left|A lightmap scale of 64]]
{{clr}}


{{tip|A couple of things to bear in mind when configuring static shadow diffusion:}}
{{note|{{src13mp|4.1}}, the {{tf2branch|nt=0|4.1}}, and {{gmod|4.1}} also support lightmaps on [[MDL]] props using [[VertexLitGeneric]].<br>Prop lightmaps are capable of being higher resolution than brush or displacement lightmaps, but come with their own share of complications; see {{ent|$lightmap}} and {{ent|prop_static}} for specifics.}}
:* Generally, shadows will become more diffuse as they get further away from your average light bulb or flame. As these light sources are radial, the illuminated surface area is much smaller closer to the light. Thus increasing the lightmap density for these small, close areas is relatively [[cheap]].  
{{bug|tested={{hl2dm}} {{dods}}|{{src}} Lightmap seams can sometimes occur at brush face subdivisions when [[MSAA]] is enabled. As subdivision size ([[chop]]ping) is affected by luxel scale, this is more noticeable at lower luxel scales (higher-resolution lightmaps). Engine modifications and a modified VBSP are required to reduce face subdivisions at lower luxel scales.}}
:* However, Direct light from the Sun or Moon (see [[light_environment]]) has negligible falloff and spread (ie parallel rather than radial rays) because these strong light sources are so far away. Direct parallel light will tend to cast equally sharp/diffuse shadows at any distance within a map.
:* Thicker Fog (see [[env_fog_controller]]) increases atmospheric scattering, which means all shadows will be be (a lot) more diffuse.


== Related [[ConCommand]]s ==
== Scale ==
*[[Lightmap Commands#mat_filterlightmaps|mat_filterlightmaps]]
The '''lightmap scale''' of a face defines the resolution of its lightmap. The default scale of 16 makes each lightmap pixel ("luxel") 16 [[unit]]s across, while a lightmap scale of 1 makes one luxel equal one unit. The [[Hammer Face Edit Dialog]] is used to change the value per-face.
*[[Lightmap Commands#mat_showlightmapcomponent|mat_showlightmapcomponent]]
*[[Lightmap Commands#mat_showlightmappage|mat_showlightmappage]]
*[[Lightmap Commands#r_avglightmap|r_avglightmap]]
*[[Lightmap Commands#r_lightmap|r_lightmap]]


== See Also ==
Lowering scale will make lightmap shadows sharper, but leads to larger map filesize, slightly slower rendering and exponentially slower compiles (that at ''very'' low scales start to eat up shocking amounts of system memory).
[http://www.vadear.com/koko/?p=194 Basic Lightmaps on Vadear.com]


<div style="text-align:center;margin:auto;width:608px;background:F9F9F9;border:1px solid #CCCCCC;padding:.3em;">
<div>[[File:intlight_lmap4.jpg|200px|Lightmap scale 4]] [[File:intlight_lmap16.jpg|200px|Lightmap scale 16]] [[File:intlight_lmap64.jpg|200px|Lightmap scale 64]]</div>
<div style="font-size:.75em;">Lightmap scales of 4, 16, and 64.</div>
</div>


When generating lightmaps, VRAD does not create [[Wikipedia:Umbra|penumbras]]. The effect can be done by placing multiple lights near each other to simulate a non-point source of light, and/or increasing lightmap scale (which is why the relatively large value of 16 is the default).


[[Category:Level Design]]
{{note|Each compiled [[brush]] polygon can host a maximum of 31x31 luxels. [[VBSP]] will subdivide brush faces to get extra luxels on if it needs to.
[[Category:Glossary]]
* This limit is 124x124 luxels on displacements, which can't be automatically chopped by VBSP; see [[Displacement Luxel Density]].
* The limit for brushes is increased to 127x127 luxels in {{mcv}}{{strata}}.
* Too many brush faces with low luxel scales will result in [[VBSP]] failing with [[Too many unique verts]].}}
 
{{tip|
*[[Fog]] in reality increases atmospheric scattering, making all shadows a lot more diffuse. Look at {{ent|light_environment}}'s sun spread angle
*{{src}} Luxel scale does not need to be a power of two; it does not directly correspond to lightmap resolution. Any integer value can be used, but even scales are preferred to avoid seams; odd values may be also more prone to [[Engine Hunk Overflow]]{{confirm}}.
}}
{{important|Faces which have lightmap scale set to 0 are treated as being set to 16 by [[VBSP]], but [[Hammer]] rounds up the value of such faces to 1 instead when applying any changes to the brush face. This affects [[VMF]]s which are exported from [[Jack]].}}
 
<div style="text-align:center;margin:auto;width:502px;background:F9F9F9;border:1px solid #CCCCCC;padding:.3em;">
<div>[[File:Lightmap.PNG|500px|Scales and effects.]]</div>
<div style="font-size:.75em;">Scales and effects of [[Lights.rad#Lights files|light textures]].</div>
</div>
 
== Optimization ==
[[File:Intlight_lightmaps.jpg|thumb|Optimizing lightmap scales.]]
 
Lightmap optimization can be done by eye with the aid of a compiled map: faces with low lighting contrast can have their scales increased, and vice versa faces with high contrast should be considered for lower scale. Just beware of setting a face's scale so high that it ends up a 'blob' of light that doesn't blend with its neighbors (use <code>mat_fullbright 2</code> to spot this).
 
Remember to take into account the size of a face, too. Moving a very large face even one point up or down can have a huge impact. Don't be afraid to split the face up if that helps, or to drop a bit of detail from huge floor or wall faces.
 
== Hammer View ==
Clicking the ''camera'' control in the top-left of a 3D view in Hammer provides the option of "3D Lightmap Grid". This view textures each brush surface with a grid that represents its lightmap scale (shown in the last section).
 
Tool brushes are textured like any other in this mode, despite being invisible in-game, so switch them all off from their auto-[[visgroup]] (or in {{hammer++|1}}, the [[File:Hammer++_show_tool_textures_icon.png|15px|link=|Show tool textures]] show tool textures icon).
 
<div style="text-align:center;margin:auto;width:768px;background:F9F9F9;border:1px solid #CCCCCC;padding:.3em;">
<div>[[File:3D_lightmap_grid_4.png|128px|Lightmap scale 4 (appears red when Luxel scale <7)]] [[File:3D_lightmap_grid_8.png|128px|Lightmap scale 8 (appears yellow when Luxel scale 8-15)]] [[File:3D_lightmap_grid_16.png|128px|Lightmap scale 16 (appears white)]] [[File:3D_lightmap_grid_32.png|128px|Lightmap scale 32 (appears light blue when Luxel scale 17-63.)]] [[File:3D_lightmap_grid_64.png|128px|Lightmap scale 64 (appears green when Luxel scale >64.)]]</div>
<div style="font-size:.75em;">Lightmap scales of 4, 8, 16, 32, and 64 in 3D Lightmap Grid view.</div>
</div>
 
== Bicubic lightmaps ==
{{hl2|2}}, {{hls|2}}, {{portal|2}}, and the {{tf2branch|2}} include the "Very High" shader detail option, which also enables bicubic filtering on lightmaps, smoothing out the aliasing ("stair-stepping") at the cost of reduction of thinner details and more prominent seams. This can be also toggled independently with the {{cmd|r_lightmap_bicubic}} [[cvar]]. Bicubic lightmaps require {{dx9}}. Due to being implemented in shader code, it only affects [[LightmappedGeneric]] and [[WorldVertexTransition]] materials.
 
The images below compare between disabled and enabled, highlighting the benefits and issues. Click on the images to see them in full size.
<div style="text-align:center;margin:auto;width:400px;background:F9F9F9;padding:.3em;">
<div>[[File:Bicubic_lightmaps_comparison.jpg|400px|Bicubic lightmaps comparison - disabled and enabled.]]</div>
<div style="font-size:.75em;">Bicubic lightmaps comparison - disabled and enabled.</div>
</div>
 
<div style="text-align:center"><gallery mode=nolines widths=480 heights=270>
anzio high res bicubic lightmap example - off.jpg|Standard bilinear lightmaps on a brush with luxel scale set to 2.
anzio high res bicubic lightmap example - on.jpg|The same scene, but using bicubic lightmaps. Note how the fence shadow is fainter and the static prop lightmap on the wall is unaffected.
</gallery></div>
 
<div style="text-align:center"><gallery mode=nolines widths=480 heights=270>
TF2_Bicubic_lightmap_comparison_-_Off.jpg|Standard bilinear lightmaps.
TF2_Bicubic_lightmap_comparison_-_On.jpg|Same scene with bicubic lightmaps, but in Team Fortress 2.
</gallery></div>
 
<div style="text-align:center"><gallery mode=nolines widths=270 heights=270>
bicubic lightmap seams - off.jpg|Standard bilinear lightmaps.
bicubic lightmap seams - on.jpg|The same scene, but using bicubic lightmaps. Note how the lightmaps' UV seams are much more prominent
</gallery></div>
 
== Console Commands ==
The following are all [[sv cheats|cheats]], except {{code|r_lightmap_bicubic}}:
 
[[File:Mat fullbright 2.jpg|thumb|<center><tt>'''mat_fullbright 2'''</tt></center>]]
 
; <tt>mat_fullbright 2</tt>
: Replaces all [[albedo]]s with a grey tone, leaving just lighting information.
; <tt>mat_luxels <[[boolean|bool]]></tt>
: Display [[luxel]]s on all brush surfaces and props with prop lightmaps. {{note|Distorts on [[displacements]], this is not a bug.}}
: {{bug|tested={{tf2branch}}, {{gmod}},{{hl2}} 20th, {{hl2}} 2012 build|This command is broken in {{src09}}, {{srcmp}}{{confirm}} and {{src13sp|2}} and doesn't display correctly, due to missing shaders (see [https://github.com/ValveSoftware/Source-1-Games/issues/3803 GitHub issues #3803]). This issue is not affected in {{tf2branch|1}} games ({{css}}, {{dods}}, {{hldms}}, {{hl2dm}}, {{tf2}}), most {{src13mp|1}} games and both legacy and 2025 version of {{srcsdk13|1}}.</br>Remains unfixed on {{hl2|1}} (20th anniversary). <br> Fixed in {{gmod|1}} </br> |since=src09|fixed=l4dbranch}}
: {{bug|tested={{dods}}|Lightmaps show up incorrectly on displacements when this command is used.}}
; <tt>mat_filterlightmaps <[[boolean|bool]]></tt>
: Control whether luxels are smoothed together in the same way as [[texel]]s.
; <tt>r_avglightmap <[[boolean|bool]]></tt>
: Doom mode! Averages lightmap values across each polygon.
; <tt>mat_showlightmappage <[[integer|int]]></tt>
: Unwraps each lightmap into a small, tessellating display in the top left of the screen. Not terribly useful to modders.
: {{tip|You can see all lightmaps by opening [[mat_texture_list]] and clicking '''Render Targets and Special Textures'''.}}
; <tt>r_lightmap <[[integer|int]]></tt>
: Specifies the light style index to compute and display the lightmap for. If set to <tt>-1</tt> (default), computes for all light styles. Primarily used for debugging and inspecting specific light styles' effects on the lightmap.
; <tt>r_unloadlightmaps <[[boolean|bool]]></tt>
: Controls whether lightmap data is unloaded from memory after being updated. When set to <tt>1</tt>, the engine unloads lightmap data to save memory. Useful for debugging or when frequent changes to lighting occur.
; {{code|r_lightmap_bicubic <[[boolean{{!}}bool]]>|preset=0}}  {{only|{{hl2}} {{hls}} {{portal}} {{tf2branch}}}}
: Enable [[#Bicubic lightmaps|bicubic lightmap sampling]]. Only available in {{hl2|2}} and {{hls|2}} since Half-Life 2 20th Anniversary, {{portal|2}} (May 20, 2025 update), and {{tf2branch|2}} since the February 18, 2025 patch.
 
== Manual lightmap edition ==
The lightmap samples are not stored as an embedded texture but rather as raw samples. It is possible to preview, export and import lightmaps for selected or all faces using {{bspentspy|4.1}}.
[[File:Bspentspy lightmap.jpg|thumb|right|500px|Lightmaps being preview in BSPEntSpy v1.67.]]
 
== See also ==
* {{ent|LightmappedGeneric}}
* [[Displacement Luxel Density]]
[[Category:Level Design]][[Category:Glossary]][[Category:Lighting]]

Latest revision as of 13:45, 11 August 2025

English (en)Français (fr)Русский (ru)Translate (Translate)

A lightmap is a generated texture applied to brush faces to simulate lighting. The color values in the surface's diffuse or albedo are multiplied by the color values in its lightmap.

Lightmaps are created by VRAD each time a map is compiled, although VBSP allocates the lightmaps. They are static and cannot change, though it is possible to switch lightmap 'pages' on and off (see Naming Lights).

In November 16, 2024, with the release of the Half-Life 2 20th anniversary update, Team Fortress 2's February 18, 2025 patch (also includes Counter-Strike: Source, Day of Defeat: Source, Half-Life 2: Deathmatch and Half-Life Deathmatch: Source), and later May 20, 2025 update for Portal, lightmaps are now Bicubic filtered if the player set the video options to "Very High". This can be toggled independently with the r_lightmap_bicubic cvar.

Note.pngNote:Source 2013 Multiplayer Source 2013 Multiplayer, the Team Fortress 2 branch TF2 branch, and Garry's Mod Garry's Mod also support lightmaps on MDL props using VertexLitGeneric.
Prop lightmaps are capable of being higher resolution than brush or displacement lightmaps, but come with their own share of complications; see $lightmap and prop_static for specifics.
Icon-Bug.pngBug:Source Lightmap seams can sometimes occur at brush face subdivisions when MSAA is enabled. As subdivision size (chopping) is affected by luxel scale, this is more noticeable at lower luxel scales (higher-resolution lightmaps). Engine modifications and a modified VBSP are required to reduce face subdivisions at lower luxel scales.  (tested in: Half-Life 2: Deathmatch Day of Defeat: Source)

Scale

The lightmap scale of a face defines the resolution of its lightmap. The default scale of 16 makes each lightmap pixel ("luxel") 16 units across, while a lightmap scale of 1 makes one luxel equal one unit. The Hammer Face Edit Dialog is used to change the value per-face.

Lowering scale will make lightmap shadows sharper, but leads to larger map filesize, slightly slower rendering and exponentially slower compiles (that at very low scales start to eat up shocking amounts of system memory).

Lightmap scale 4 Lightmap scale 16 Lightmap scale 64
Lightmap scales of 4, 16, and 64.

When generating lightmaps, VRAD does not create penumbras. The effect can be done by placing multiple lights near each other to simulate a non-point source of light, and/or increasing lightmap scale (which is why the relatively large value of 16 is the default).

Note.pngNote:Each compiled brush polygon can host a maximum of 31x31 luxels. VBSP will subdivide brush faces to get extra luxels on if it needs to.
  • This limit is 124x124 luxels on displacements, which can't be automatically chopped by VBSP; see Displacement Luxel Density.
  • The limit for brushes is increased to 127x127 luxels in Military Conflict: VietnamStrata Source.
  • Too many brush faces with low luxel scales will result in VBSP failing with Too many unique verts.
Tip.pngTip:
  • Fog in reality increases atmospheric scattering, making all shadows a lot more diffuse. Look at light_environment's sun spread angle
  • Source Luxel scale does not need to be a power of two; it does not directly correspond to lightmap resolution. Any integer value can be used, but even scales are preferred to avoid seams; odd values may be also more prone to Engine Hunk Overflow[confirm].
Icon-Important.pngImportant:Faces which have lightmap scale set to 0 are treated as being set to 16 by VBSP, but Hammer rounds up the value of such faces to 1 instead when applying any changes to the brush face. This affects VMFs which are exported from Jack.
Scales and effects.
Scales and effects of light textures.

Optimization

Optimizing lightmap scales.

Lightmap optimization can be done by eye with the aid of a compiled map: faces with low lighting contrast can have their scales increased, and vice versa faces with high contrast should be considered for lower scale. Just beware of setting a face's scale so high that it ends up a 'blob' of light that doesn't blend with its neighbors (use mat_fullbright 2 to spot this).

Remember to take into account the size of a face, too. Moving a very large face even one point up or down can have a huge impact. Don't be afraid to split the face up if that helps, or to drop a bit of detail from huge floor or wall faces.

Hammer View

Clicking the camera control in the top-left of a 3D view in Hammer provides the option of "3D Lightmap Grid". This view textures each brush surface with a grid that represents its lightmap scale (shown in the last section).

Tool brushes are textured like any other in this mode, despite being invisible in-game, so switch them all off from their auto-visgroup (or in Hammer++, the Show tool textures show tool textures icon).

Lightmap scale 4 (appears red when Luxel scale <7) Lightmap scale 8 (appears yellow when Luxel scale 8-15) Lightmap scale 16 (appears white) Lightmap scale 32 (appears light blue when Luxel scale 17-63.) Lightmap scale 64 (appears green when Luxel scale >64.)
Lightmap scales of 4, 8, 16, 32, and 64 in 3D Lightmap Grid view.

Bicubic lightmaps

Half-Life 2 Half-Life 2, Half-Life: Source Half-Life: Source, Portal Portal, and the Team Fortress 2 branch Team Fortress 2 branch include the "Very High" shader detail option, which also enables bicubic filtering on lightmaps, smoothing out the aliasing ("stair-stepping") at the cost of reduction of thinner details and more prominent seams. This can be also toggled independently with the r_lightmap_bicubic cvar. Bicubic lightmaps require (DX9 SM2). Due to being implemented in shader code, it only affects LightmappedGeneric and WorldVertexTransition materials.

The images below compare between disabled and enabled, highlighting the benefits and issues. Click on the images to see them in full size.

Bicubic lightmaps comparison - disabled and enabled.
Bicubic lightmaps comparison - disabled and enabled.

Console Commands

The following are all cheats, except r_lightmap_bicubic:

mat_fullbright 2
mat_fullbright 2
Replaces all albedos with a grey tone, leaving just lighting information.
mat_luxels <bool>
Display luxels on all brush surfaces and props with prop lightmaps.
Note.pngNote:Distorts on displacements, this is not a bug.
Icon-Bug.pngBug:This command is broken in Source 2009, Source Multiplayer[confirm] and Source 2013 Singleplayer Source 2013 Singleplayer and doesn't display correctly, due to missing shaders (see GitHub issues #3803). This issue is not affected in Team Fortress 2 branch games (Counter-Strike: Source, Day of Defeat: Source, Half-Life Deathmatch: Source, Half-Life 2: Deathmatch, Team Fortress 2), most Source 2013 Multiplayer games and both legacy and 2025 version of Source SDK Base 2013.
Remains unfixed on Half-Life 2 (20th anniversary).
Fixed in Garry's Mod
  (tested in: Team Fortress 2 branch, Garry's Mod,Half-Life 2 20th, Half-Life 2 2012 build)
Icon-Bug.pngBug:Lightmaps show up incorrectly on displacements when this command is used.  (tested in: Day of Defeat: Source)
mat_filterlightmaps <bool>
Control whether luxels are smoothed together in the same way as texels.
r_avglightmap <bool>
Doom mode! Averages lightmap values across each polygon.
mat_showlightmappage <int>
Unwraps each lightmap into a small, tessellating display in the top left of the screen. Not terribly useful to modders.
Tip.pngTip:You can see all lightmaps by opening mat_texture_list and clicking Render Targets and Special Textures.
r_lightmap <int>
Specifies the light style index to compute and display the lightmap for. If set to -1 (default), computes for all light styles. Primarily used for debugging and inspecting specific light styles' effects on the lightmap.
r_unloadlightmaps <bool>
Controls whether lightmap data is unloaded from memory after being updated. When set to 1, the engine unloads lightmap data to save memory. Useful for debugging or when frequent changes to lighting occur.
r_lightmap_bicubic <bool> (only in Half-Life 2 Half-Life: Source Portal Team Fortress 2 branch)
Enable bicubic lightmap sampling. Only available in Half-Life 2 Half-Life 2 and Half-Life: Source Half-Life: Source since Half-Life 2 20th Anniversary, Portal Portal (May 20, 2025 update), and Team Fortress 2 branch Team Fortress 2 branch since the February 18, 2025 patch.

Manual lightmap edition

The lightmap samples are not stored as an embedded texture but rather as raw samples. It is possible to preview, export and import lightmaps for selected or all faces using BSPEntSpy BSPEntSpy.

Lightmaps being preview in BSPEntSpy v1.67.

See also