Tutorial: The Complete Guide to Lighting Last edited 4 months ago2024-08-06 08:07:37 UTC

The Complete Guide to Lighting

This tutorial describes everything you could ever want to know about lighting in Goldsrc. It goes through various types of lighting, general usage, nifty tricks and compile settings for HLRAD. If you want to duplicate these steps, make sure you use VHLT Compile Tools version 34 and load the zhlt.fgd into your editor.

If you are missing any keyvalues used in this guide, you can refer to the name in the brackets and add the keyvalue yourself. Disable SmartEdit (1), click add (2), then add the key name and the desired value and press Ok (3).
User posted image

1. Basic lighting

There are various types of lights in goldsrc. This section will show you how to use them and their advantages and disadvantages.

1.1. Point light

User posted image
The general light entity is referred to as a point light. It’s a point in space from which light is cast in 360 degrees.

Target [target]: No function
Name [targetname] : If the light does not have a name, it’s considered a static light. It will be used in the compile process during light calculations. After that the entity will be removed from the BSP. This way it doesn’t take up space in the entity index, which is a limited resource in Half-Life. If you do give it a name, it becomes a dynamic light. You will be able to target the light with another trigger entity. It will listen for ON, OFF or TOGGLE commands. Dynamic lights are not removed during compilation and will take up a space on the entity index.
Half-Life supports up to 31 unique toggleable lights.
Brightness [_light]: You can set 4 values: Red, Green, Blue and Intensity. You can pick a color from the wheel but you’ll have to set the Intensity manually. A value of 100 or 200 is often enough to create a bright light.
Appearance [style]: You can choose one of the presets to make this light follow a certain pattern, such as pulses and flickers. If you give the light a name, the Appearance setting will be ignored. You can work around this issue by using a Custom Appearance.
Custom Appearance [pattern]: You can also set a custom pattern, from a to z, where a is black and m is fully bright and z is double brightness. You can create a pattern up to 63 characters. Here are the values used in the presets:
1 = Flicker A mmnmmommommnonmmonqnmmo
2 = Slow strong pulse abcdefghijklmnopqrstuvwxyzyxwvutsrqponmlkjihgfedcba
3 = Candle A mmmmmaaaaammmmmaaaaaabcdefgabcdefg
4 = Fast strobe mamamamamama
5 = Gentle pulse jklmnopqrstuvwxyzyxwvutsrqponmlkj
6 = Flicker B nmonqnmomnmomomno
7 = Candle B mmmaaaabcdefgmmmmaaaammmaamm
8 = Candle C mmmaaammmaaammmabcdefaaaammmmabcdefmmmaaaa
9 = Slow strobe aaaaaaaazzzzzzzz
10 = Fluorescent flicker mmamammmmammamamaaamammma
11 = Slow pulse, no black abcdefghijklmnopqrrqponmlkjihgfedcba
12 = Underwater mutation mmnnmmnnnmmnn
Warning: On AMD and Intel graphic cards the old OpenGL rendering mode Half-Life uses isn’t well supported. Using a looping appearance on your lights can cause serious frame drops on these cards. It is best to avoid these in maps where performance matters, such as deathmatch maps.
ZHLT Fade [_fade]: This setting controls the light gradient going outwards from the origin point. The higher the value, the smaller and dimmer the light will become. You can use this to create certain effects but it might be better to reduce the Intensity or switch to a light_spot.
User posted image
ZHLT Falloff [_falloff]: With this setting you can set the type of light falloff calculation. Linear fall-off will gradually reduce the amount of light over the maximum reach of the light source. It will start with 100% intensity in the center to 0% on the outer edges. Square fall-off uses a formula where the intensity is lessened with every doubling of distance. This makes the light have 100% intensity in a certain range around the origin, but beyond that point the light will start reducing exponentially. Square fall-off is a more realistic approach to light fall-off than linear. However, the effects of the different calculations are very small in goldsrc because it generally doesn't have very high quality lighting.
Initially Dark [flag:1]: You can check this box if you want the light to be OFF when the map loads.

1.2. Spot light

User posted image
The light_spot is a directional light that creates a circular spot of light on a given direction. You can set the angles of the entity to turn the spot light in any direction, including up and down.

For other values, see chapter 1.1 point light.
Target [targetname]: Instead of manually setting an angle, you can create a target entity for the spot light to point at. This makes it easier to get the spot light to shine on the right place. This can be any entity with a targetname but it’s advised to use the info_null for this job. This entity will be removed after compilation and doesn’t count towards the entity limit.
Inner (bright) angle [_cone]: Controls the size of the inner circle where the light is the brightest.
Outer (fading) angle [_cone2]: Controls the size of the outer circle where the light fades.
User posted image
Pitch: Used for environment light, see chapter 1.3.
Is Sky: Used for environment light, see chapter 1.3.

1.3. Environment light

User posted image
Environment light is used in outdoor areas that are exposed to the SKY texture. Instead of using the light_environment entity, we’ll use the light_spot. The light_spot entity can also be used for environment lighting and has a few advantages over light_environment. See chapter 3 for more info.

Is Sky: [_sky]: When this is set ‘Yes’ or [1], you can use your light_spot as an environment light. Make sure the entity is in the outdoor area where you want it to cast its light.
Pitch, Yaw, Roll [angles]: You can use this to set the direction where the light is coming from. You can do this by setting the Yaw dial in the properties window, or the Z value: 0 45 0. The angle corresponds to the 2d top view in the editor.
Pitch [pitch]: The pitch indicates the height of the sun on the horizon from 0 to -90. This value will determine how bright your outside area will be and the length of the shadows. This way you can create the right conditions for the time of day: long shadows on early mornings, short shadows around noon.
User posted image
User posted image
Ambient Color [_diffuse_light]: This will give all your environment light a colored overlay, like a filter. The advantage of this setting over the normal brightness is that the shadows will also receive this color filter. This can be very useful for night maps that need a cold blueish tint to simulate moon light. You can set a colour by entering a 3 digit number for Red, Green and Blue. Add a 4th number to adjust the Intensity of the colour.
User posted image
Sun Diffuse [_diffuse_light2]: While _diffuse_light adds a tint to all sunlight, _diffuse_light2 will only apply to bounced sunlight. This will mostly affect shadows.
User posted image
Sun Spread [_spread]: Used to create larger shadow gradients in a range from 0 (sharp) to 10 (soft). Use a low value in very sunny environment to create sharp shadows. Higher values can be used in more overcast environments where light is more diffused by the clouds.
User posted image

1.4. Texture light

You can also set up textures to cast light. The brightness is determined by the size of the brush itself. Very small lights will need high Intensity values to give off enough light. Where a value of 100 was enough for a point light, texture lights often need values ranging between 1000 and 10.000 depending on their size.

You can determine the color of the light yourself by picking a color or you can let the compiler determine the color itself. It will then take the most dominant color in the texture and use that for its lighting. In the latter case, you only need to set the Intensity level.
User posted image
There are several ways to set up texture lighting. Here’s are the methods you can use:

1.4.1 RAD file

You can use an external text file to store the texture names and brightness values. This can be useful if you want to use these light settings on multiple maps or when you collaborate with other mappers. The downside is that you have to use a text editor outside of your mapping editor.

Create a new text file with the .rad extension and load it in your favorite text editor. Then just enter the name of the texture and the desired brightness:
+0~LIGHT1    234 255 254 1000     // color determined by user
+0~LIGHT3    5000             // color determined by compiler
EMERGLIGHT    9000            // tiny light needs a lot of Intensity
Put the file in the folder with your HLRAD compiler and set up a new parameter in the RAD compile options: -lights yourradfile

It will now use your RAD information for light calculations. Note that HLRAD will automatically use the default lights.rad file if it’s available in the same folder. If you do not want conflicts, delete or rename this file.

1.4.2 info_texlights

Just like a RAD file, you can use the info_texlights entity to add texture lights. The compiler will automatically pick up any info left in this entity. Disable Smartedit, click on add and start adding lines to the entity.
User posted image
You can use a RAD file and info_texlights at the same time, as long as they do not contain duplicates of the used textures.

1.4.3 light_surface

RAD files and info_texlights only create static lights and give you no control. This is where light_surface comes in. It will give you all functions of light and light_spot. It will also give you control over which individual textures to use and not to use based on range and entity name.

Name [targetname]: You can use this to control this texture light and fire ON, OFF or TOGGLE.
Texture name [_tex]: Put the name of the texture here (eg. +0~LIGHT3A)
Brightness [_light]: Set the color yourself or just the intensity to let the compiler pick the color for you.
Classname in game [convertto]: You can set it to light or light_spot. When set to light_spot you can also set inner and outer fading properties.
Filter max range [_frange]: You can set this to only affect texture lights that are within the radius of this light_surface. In the example below, only four of the lights are within the set 128 radius from the entity.
User posted image
User posted image
This can also be useful if you want to use the same texture multiple times but with different appearances. In this example I’ve put the light_surfaces close to the lights I want to affect and set the range to 16 units. The left is static, the right one is set to Fluorescent Flicker.
User posted image
Filter max dist to plane [_fdist]: This setting works similar to _frange but the range only affects lights that are on the same plane as the set limit. In the example below, the top row is on a horizontal plane that is within 32 units of the entity. The lower row is outside the range and will not be lit.
User posted image
User posted image
Filter entity classname [_fclass]: With this setting you can specify a certain entity class to be the only to use this texture for lighting. For instance, if you want +0~LIGHT1 to only be lit when it’s applied on func_wall, you can enter func_wall here. +0~LIGHT1 on all other entities and world geometry will then be ignored.
Filter entity name [_fname]: Same as above but now for entity names. It will only cast this texture’s light from entities with that exact name. For instance, use lightbrush in this field and all entities with the name lightbrush will cast light with this texture.
Dark gap in front of tex light [_texlightgap]: Used to fix light bleeding. See chapter 2.23.
Note that, even without a targetname or Appearance setting, light_surface will always end up in the entity index and counts towards the entity limit. If you are closing in on this limit, use a RAD file or info_texlight instead for your static lights.

2. Advanced Lighting

There are several advanced options and techniques to make your lights and shadows look better or act more realistically. This chapter will review those options.

2.1. Glow

You can make your lights more interesting by adding an env_sprite in front of them with a glow effect. Half-Life comes with 5 different styles of glows (/sprites/glow01.spr/, glow02.spr, etc.). Set the scale value to match the size of your light. A lower scale (0.5) will make the sprites sharper.
There are two modes to consider: Additive or Glow. Additive creates a static glow and Glow creates an effect where the sprite will resize based on the player’s distance. Coming closer makes the sprite smaller and more intense, moving away makes the sprite larger and less visible.
User posted image
You’ll have to experiment with the FX amount of the glows. In dark areas it’ll be good to use a high value (150-255) but in well-lit areas it’s best to use a lower value (50-100).

Generally, you’ll want the glow mode effect but note that it will never completely fade out the sprite. Even on large distances you can still see the haze from the glow sprite, which can come off strange. In this case it might be better to use additive mode.

2.2. Additive overlays

Many light textures in the halflife.wad file have fixtures around them. If you use texture lighting on these textures, the entire fixture will also become fully lit, which can be undesirable. Also, if you let the compiler choose the color for you, it might pick the dominant color of the fixture instead of the light tube or bulb itself.

A way to fix this is to separate the glowing parts and the fixture with a image editor such as Photoshop. Put the glowing parts on a black background and save them to the WAD using Wally or HL Texture Tools.

Most textures have an unlit variant of the light texture. Place a thin 1 unit thick func_illusionary brush in front of the unlit light fixture. Put the new glow texture on this func_illusionary and texture all other sides with NULL. Set the render mode to Additive and use a high FX amount between 200 and 255.

Add your new glow texture to your RAD file / info_texlight / light_surface. If the contrast between the glow overlay and the unlit fixture is too high, you can add the fixture to your texture lights with a small Intensity such as 20.
User posted image
For the best lighting effect, combine the overlays with glow sprites (see chapter 2.2).

2.3. Volumetric light

You use a brush to emulate volumetric light. These can add some flavor to your lighting particulary in dim areas.

Create a new brush and use Vertex Manipulation to widen the points at the bottom of the brush. Apply the FADE or FADE2 texture to the side faces with the lightest part on the top, darkest on the bottom of the face. Turn this brush into a func_illusionary and apply the Additive render mode. The effect will look the most realistic with a low value of 20 - 50, depending on the brightness of your light.

You can make the volumetric light even more realistic by letting it render both sides of the face. To do this, apply the CONTENTWATER texture to the bottom and the top of the brush.
User posted image

2.4. Moving light

Half-Life only has a few moving dynamic lights, such as the flashlight and some of the weapon muzzle/flare effects. These are lights you normally cannot use as a mapper except for for two effects.

To use this you must set up a func_train (or any other moving brush entity), disable SmartEdit and add the effects keyvalue with a value of 4. This will create an EF_BRIGHTLIGHT on this entity. Then set up a few path_corner for the train to travel on and watch the bright light move with the train. You cannot alter the color or brightness of this light.
User posted image
Alternatively you can tie a EF_LIGHT to your brush entity with effects and the value 64. This creates a flare effect normally used for the RPG rocket.
User posted image
Warning: Dynamic lights like these can be quite costly for the engine to render, especially on AMD and Intel graphic cards where the old OpenGL rendering mode Half-Life uses isn’t well supported. It is best to avoid these in maps where performance matters, such as deathmatch maps.

3. Tweaks and Tricks

3.1. Lightmap scale

The quality of the lighting and shadows is determined by the lightmap. This is a 16x16 grid overlaid on your textures. Each dot can be lit up to create light and shadow. You can actually see this grid if you stand close to a texture and slowly move the flashlight around.
User posted image
As you can see, there are a lot of gaps between the points and that’s why shadows become jagged. The lightmap scale is tied to the texture scale, so you can improve the lighting by scaling down your textures. Here are some examples of different texture (and thus lightmap) scales:
User posted image
Generally, Half-Life uses 128x128 textures on 1.0 scale. If you want to use lower scales within the normal grid sizes, you have to create new textures with higher resolution. 0.50 scale corresponds with 256x256 and 0.25 with 512x512 (Source quality). Goldsrc doesn’t support 1024x1024 textures.

Going down in texture scale will increase memory usage, compile times, create far more wpoly and you’ll reach engine limits a lot sooner. 256x256 textures on 0.5 scale are possible while maintaining decent performance and map size. 512x512 textures are to be used sparingly.

On the other hand, going up in scale (2.0 and higher) can make engine performance better and compile times lower. You can sacrifice some detail in places that players will not see up close.

3.2. Light Bounce

Light naturally bounces off surfaces and helps illuminate the rest of the area. The -bounce setting in HLRAD will simulate that behavior. Setting bounce to 0 will create very harsh shadow effects and will generally look very unnatural. Going above bounce 8 will make shadows look a bit washed out.
The sweet spot is somewhere between 2 and 8. It depends on what kind of atmosphere you’re going for and also which type of materials you’re generally using. If your textures contain a lot of metal and shiny reflective surfaces, then use bounce 6 or 8. In real life, light would reflect off those surfaces more. If you have a lot of softer and less reflective materials such as carpet and rough concrete, then you’d be better off with bounce 2 or 4.
User posted image
Light bounce will also pick up the brightness of the surface it is reflected from. The lighter the texture on that surface, the more light will be reflected. Next to brightness, it will also reflect the color of the texture.
User posted image
User posted image

3.3. Reflection

Goldsource has no metadata for individual textures, so you can’t specify how reflective a surface is. Carpet will be just as reflective as polished aluminum. If you want to use colorful carpet, you’d have to make sure that there are enough other light sources to overwrite the bounced light from the floor.

If you have a lot of unwanted light color or brightness bounce, then you can set the global reflectivity scale to tone it back (or increase it) by adding the -texreflectscale option to HLRAD.
User posted image
Just like the reflection scale, there’s a setting to adjust the gamma of the reflections. It will reflect lighting as it did before but with less or more brightness. Add -texreflectgamma to HLRAD to tweak this.
User posted image

3.4. Shadows on brush entities

By default, brush entities will not cast shadows. You can set the ZHTL Lightflags [zhlt_lightflags] to Opaque [2] to create shadows.
User posted image
The opaque light flag can also be used to create shadows with transparent textures.
User posted image
In some cases, such as func_breakable or func_wall_toggle, you want the shadows to disappear once the entity gets disabled, killtargeted or destroyed.

Let’s start with a func_breakable. Set the light flag to opaque to generate the shadow. Give the func_breakable a name (crate1). Then set a target on break (crate1_shadow).

Create a light_shadow entity and name it (crate1_shadow). Set the Target Solid Entity to the func_breakable (crate1). Set the Flag to Initially Dark. Then create a light_bounce with the same name and targets as the light_shadow, but do not set the Initially Dark flag.
User posted image
You can also create shadows for an appearing func_wall_toggle. Give it a name (wall1) and set the flags to Start Invisible. Create a light_shadow and name it (wall1) and give it a target (wall1). These names should be identical. The Initially Dark flag should not be ticked. Create a light_bounce with name (wall1) and target (wall1) and Initially Dark flag enabled. Now set up a trigger_multiple or func_button and target the setup (wall1). You can now toggle it ON or OFF.
User posted image

3.5. Custom shadows

You can use the Custom Shadow [zhlt_customshadow] option to manually adjust the brightness of any individual brush entity. You can use a value of 0 (dark) to 1.0 (light).
User posted image
You can even create colored shadows by using three values (Red Blue Green) from 0 to 1.0.
User posted image

3.6. Shadow Blur

Blur is used to blur out the edges of shadows. Because Half-Life has very limited lightmap, shadows can become jagged and blocky. You can mitigate this slightly by adding a bit of blur by using the -blur option in HLRAD. However, too much blur will turn shadows into shapeless blobs. A value between 1.5 and 2.0 is recommended.
User posted image

3.7. Smoothing

Using the -smooth option in HLRAD smooths out the light and shadows along angled surfaces, such as rounded corners and cylinders. The value set corresponds with the angle on which both surfaces sit. If the angle is less than the set value, it will be smoothed.

In this example, the red barrel is 8 sided and the barrel in front is 16 sided. The 8 sided barrel will have steeper angles on its edges than the 16 sided barrel. Value ‘45’ was enough for the front barrel to be smoothed but not for the 8 sided one. Setting it to the default of ’50’ is enough to smooth this one as well.

In most cases, 50 is enough to smooth out even very blocky cylinders and curves. If there isn’t enough smoothing on your object even on value 50, then it might be better to add more edges to your brush.
User posted image
The -smooth option only smooths out adjacent textures with the same name. If you want to smooth a rounded object with different textures, you should also set -smooth2.
User posted image
You can also set smoothing angle per-texture using info_smoothvalue.

3.8. Embedded lightmaps

By default, transparent brushes using the Texture render mode do not receive proper lighting. This is especially noticeable with bright glass in dark rooms. To fix this, set zhlt_embedlightmap to 1 (enabled).
User posted image
This can drastically increase file size. You can optionally set zhlt_embedlightmapresolution to 2, 4, 8, or 16 to divide the resulting texture's file size by the given amount.

3.9. Translucent brushes

With the info_translucent entity you can specify a certain texture to let through light. This way you can simulate thin materials such as curtains. Place an info_translucent and disable SmartEdit. Now add a new keyvalue with the name of the texture. Then set a value between 0 and 1.0, where 0 means the face will be fully lit from the backside and 1.0 means the face will be fully lit from the front. Value 0.5 will make it be lit from both sides equally.
User posted image
The translucency is only visible if the thickness of the brush corresponds with the -depth option on HLRAD. By default it’s only 2 units, but you can increase it to whatever you like. With this option you can make sure that only your thin brushes will end up translucent and you can use the assigned texture normally in other places in your map.

3.10. Minimum light level

Every brush texture has the option to add a ‘Minimum Light Level’ [_minlight]. You can set a value between 0 and 1.0.
User posted image
You can use this to highlight certain brushes when they are in dark areas. However, minlight is a very artificial way to brighten brushes and often feels unrealistic. It’s better to use an actual light source to highlight important objects.

You can also do a global minlight setting by using the -minlight option in HLRAD. You can use this if you feel your map is too dark and bring the minimum light levels up to a certain value. For instance, if your shadows have a brightness value of 10, then by setting the minlight to 25, the shadows will become brighter.
User posted image
Minlight is a very artificial way to make your maps brighter. You will not be able to have fully dark shadows. If you feel your map is too dark, you can try a higher bounce value, the gamma value, the scale value or just add more light sources.

3.11. Light scaling

The -scale option in HLRAD will scale up the amount of light in your map. By default this value is 2.0, so setting it to 1.0 will decrease your light by 50% and 4.0 will increase it by 200%.
User posted image

3.12. Light gamma

The -gamma setting in HLRAD can globally increase of decrease the amount of light and shadow. The higher the value, the darker the map.
User posted image

3.13. Chop

The chop value is the grid size that lays over your textures. The points on this grid (patches) are used to calculate bounced light. The smaller the grid, the more patches and the higher the quality of your bounced light. However, a smaller grid also increases compile time and memory usage. For a final compile it will be good to lower this value to 32 and get better quality lighting and better shadows. You can use this by setting the option -chop in HLRAD.
User posted image
Texchop does the same thing but for texture lights, with the -texchop option in HLRAD. The more patches a texture light surface has, the better the lighting results. You should generally set this limit to half the amount of the chop value.
User posted image
There is also an undocumented entity in VHLT that allows mappers to set a chop scale for individual textures called info_chopscale. To use it, create a new entity, rename it and remove all old keyvalues. Now add a new keyvalue with the name of the texture and the chop value you'd like to use.
User posted image
Having a low chop value can increase compile times quite a bit, so you could potentionally pick a few textures where you want the extra chop resolution. However, the extra compile time it takes to compile a map with a lower chop value probably doesn't compare to the effort of manually adding textures to an info_chopscale, so the usage of this entity is questionable.

3.14. Light origin target

Movable objects such as func_pushable, func_train, etc. will only receive lighting once where they were placed. This can lead to undesirable cases where a dark object moves into a bright spot.
User posted image
To fix this, find a more suitable spot that averages the lighting and place an info_null there. Give it a name (light_target). The go into the func_pushable and enter that name in the Light Origin Target [light_origin] field.
User posted image

3.15. Multiple environment lights

By default, whenever you add a light_environment (or a light_spot with _sky set to 1), the environment light is set globally. Even if outdoor areas are separated, they will use the same environment light. You can, however, create different lighting conditions in separate outdoor areas by using the -noskyfix option in HLRAD.

Create two separate outdoor areas with the SKY texture, connect them with a corridor and put a light_environment or light_spot in both of them. The lighting conditions you set will now only be applied to the area they are in.
User posted image
As you can see, you’re not able to change the skybox texture but -noskyfix can still be useful in a few circumstances. You can tweak light conditions in separate areas if you want a different angle or pitch or just a bit more or less brightness in general.

3.16. Dynamic environment lights

Just like normal lights, you can toggle environment lights ON or OFF. This creates the option to change lighting conditions via trigger. Note that this only works if you use global environment lighting, so do not use the -noskyfix option from chapter 2.17 here.
User posted image
Create three light_spot (is Sky) and name them: env_light1, env_light2 and env_light3. Set up a trigger_relay and name it set_envlight1. Set the target to env_light1 and the Trigger State should be ON. Now copy this trigger_relay, and change the Target to env_light2 and the Trigger State to OFF. Copy it once more, name it env_light2 and make sure the Trigger State is OFF.

You can now duplicate these relays and rename them to set_envlight2. Then change the Trigger States so that now env_light2 will be set to ON and env_light1 and env_light3 to OFF. You can expand this system to a third light where env_light3 gets the ON trigger.

Now set up a few func_button or trigger_multiple to trigger set_envlight1, set_envlight2, etc. Fire the trigger and watch the environment light change.
User posted image

3.17. Light styles

When it comes to static (unnamed) lights, you can have as many as you like in close proximity of each other. They will override one another based on their brightness and distance to the surface.

This is different when it comes to dynamic lights. Goldsrc can only have up to four styles of light per face. That’s one style for static light and three for dynamic lights.
User posted image
As soon as you try to add a fifth layer, you’ll run into errors. HLRAD might report: ‘too many light styles on a face’ and you’ll notice strange lighting behavior in game.
User posted image
Dynamic lights are lights that have a name or have an Appearance setting. If your lights have the same name or same Appearance setting, they will be grouped in the same dynamic layer. So, you can have four or more toggleable light close to each other, as long as some of them share the same name or use the same appearance setting. This can be useful for a disco map, where you put all your toggleable colored lights into three separate groups without getting any errors.
User posted image

3.18. Angular fade

You can use the info_angularfade entity to set the amount of light fading on a certain texture. The default value is 1. Going lower will make the light fade more and going higher makes the light fade less on the specified texture.

To use this feature, disable SmartEdit and add the name of the texture and the desired value:
C3A2A_W1G 0.50
You can add multiple textures in one info_angularfade entity.
User posted image
You can use this to simulate light scatter for different types of surfaces.

3.19. Oversampling

Adding the -extra option to HLRAD will enable 9 point oversampling, generating slightly better looking shadow and fade effects. It makes the compile process a little longer but should definitively be enabled on final compiles.
User posted image

3.20. Overbright limiter

This setting is the threshold for the generation of bright lights. It was introduced in VHLT v31 to prevent overbright spots and resemble the original Half-Life radiosity calculations more.

The author of VHLT has been a bit too conservative when setting the default to 188. Especially on reflective surfaces, the lack of shine is very clear. It also greatly dulls the glow effect from the texture lights. Setting this to 225 makes the light effect look a lot better. If your map has a lot of shiny reflective materials (and you like stark contrasts) you could even go up to 255.
User posted image

3.21. Texture light gap

Because HL’s lightmaps are large and crude, putting a light on a wall can create a light bleeding effect behind the fixture. You can set the -texlightgap option in HLRAD to create a small gap between the texture light and where it will actually start emitting light. Note that the light will have less brightness because of the gap. If you use these lights a lot, you can set the value to 8 to prevent bleeding. Additionally, try to use textures with 0.5 scale on the wall, so the lightmaps are smaller and there is less bleeding to begin with.

The texlightgap can be set on individual texture lights by using the light_surface entity.
User posted image

3.22. Soft sky gradient

The -softsky option in HLRAD creates a smoother gradient from areas that are affected by environment lights to areas that are affected by interior light. This is enabled by default, as recommend.
User posted image

3.23. Environmental shadow control

If you feel that the shadows in your outdoor area have become too dark or too light, you can use the -sky option in HLRAD to adjust their brightness.
User posted image

3.24. Coring

You can set a threshold for pure black shadows in your lighting with the -coring option in HLRAD. Anything with a light level lower than the value you've set will become completely black.
-coring only works for lights with a targetname. Any unnamed static lights will not be affected by coring.
User posted image
There is also a special keyvalue to control the shadows on predefined Appearances on light and light_spot entities. To use it, go into a light or light_spot entity, disable SmartEdit and add zhlt_stylecoring with the desired value. Any brightness values under the set value will be rendered completely black.
User posted image
Even though you're adding zhlt_stylecoring to a single light entity it will affect also all other lights with the same Appearance style.

4. Models and lighting

Refer to the Models and Lighting tutorial for more info:

5. Other HLRAD Options

Let’s go through the rest of the settings of the HLRAD compiler and see which effects they have. The default setting can be found in the brackets [].

5.1. Mapper Tools

Argument Description
-sparse This setting compresses vismatrix data and allows you to go beyond the original patches limit. It requires some more CPU power but that is no concern with today’s computing power. Sparse is on by default and should be kept that way.
-fade [1] Fade will determine how fast the brightness of the light will fade outwards. The higher the value, the dimmer it will appear. Note that all lights have _fade set to 1 by default in their entity class. This will always overwrite the global value, making the usefulness of this parameter questionable.
-dscale [1] You can also increase the global amount of all direct lights only. I’ve not seen any difference between using the scale or dscale parameter.
-dlight [10] Should be able to set a threshold for direct lighting, acting as a maxlight parameter. I have not been able to see any effect of this.
-ambient [0 0 0] With ambient you can set the light levels of red, green and blue on every surface, from 0 to 1. You can use this to either increase or decrease the amount of color in your map. You can create some really interesting and crazy effects but this setting is generally best to be left alone.
-fast [off] Fast will create a very crude and dirty light rendering. It will compile a lot quicker but it shouldn’t be used in final compiles. It can be used if you want to do a quick compile to test something but you might as well just disable HLRAD fully in this case. Maps can also run without the light info and will just be fully bright.
-nospread Disable sunlight spread angles for this compile
-nopaque Disable the opaque zhlt_lightflags for this compile
-notextures Disable bounced lights picking up the colour of the texture of the surface it bounces off from. Use this to emulate the original HL SDK's QRAD lighting.
-notexscale Do not scale radiosity patches with texture scale
-nolerp Disable radiosity interpolation, nearest point instead
-noemitterrange Don't fix pointy texlights.
-nobleedfix Don't fix wall bleeding problem for large blur value.
-rgbtransfers Enables RGB Transfers (for custom shadows)
-customshadowwithbounce Enables custom shadows with bounce light
-blockopaque [1] Remove the black areas around opaque entities.(0=off 1=on)
-colourgamma r g b Sets different gamma values for red, green and blue
-colourscale r g b Sets different lightscale values for red, green and blue
-colourjitter r g b Adds noise, independent colours, for dithering.
-jitter r g b Adds noise, monochromatic, for dithering
-customshadowwithbounce Enables custom shadows with bounce light
-rgbtransfers Enables RGB Transfers (for custom shadows)

5.2. Developer Tools

These are tools used by the HLRAD developers. You won’t need them as a mapper.
Argument Description
-circus find all unlit lightmaps. It ignores light that has been generated by bounced light. It’ll give all shadows a random color.
-drawoverload see where full bright spots in the lightmaps are. Using this setting will make everything in your map dark, except for the bits that have maximum light levels.
-drawnudge see all smoothed edges.
-drawlerp show bounce light triangulation status.
-drawedge export smooth edge positions to file 'mapname_edge.pts'.
-drawpatch export light patch positions to file 'mapname_patch.pts'.
-drawsample x y z r Export light sample positions in an area to file 'mapname_sample.pts'.
-compress # compress tranfer ( 0=32bit 1=16bit 2=8bit )
-rgbcompress # compress rgbtranfer ( 0=96bit 1=48bit 2=32bit 3=24bit )
-notextures Don't load textures.

5.3 Emulating QRAD classic lighting

Even with all lighting RGB and brightness values from point and texture lights identical, the resulting lighting differs greatly between the original HL SDK's QRAD and the latest version of VHLT:
Left: HLSDK QRAD, Right: VHLT HLRADLeft: HLSDK QRAD, Right: VHLT HLRAD
The following compiler parameters emulates the lighting of the original HL SDK's QRAD:
-notextures -dscale 2 -limiter 255
Where: Result:
Left: HLSDK QRAD, Right: VHLT HLRADLeft: HLSDK QRAD, Right: VHLT HLRAD

7 Comments

Commented 9 months ago2024-02-16 12:54:53 UTC Comment #105985
Can you test the difference between light_surface's Filter max range [_frange] and Filter max dist to plane [_fdist]? I know what the words mean, but the description seem to contradict my understanding of the meaning of planes and how they work.

I have a few test case ideas:
  1. A wall of tiling 16x16 brushes textured with a texlight.
    • _frange should make only a disk of those brushes around the light_surface emit light.
    • _fdist, if my interpretation of plane is correct, should light up all of them since the normal distance of all the faces to the plane is identical even if they're infinitely far away. That's the nature of planes.
  2. Similar setup to the above but the next row above recedes 16u behind the previous row, producing a staircase. Place light_surface in the middle of this flight of stairs.
    • _frange should produce a sphere of lit up faces.
    • _fdist, if my interpretation of plane is correct, should have all faces on the same row light up until a certain distance away from the entity because again, all of them should have same normal distance to the plane.
Unfortunately I can't do these tests myself right now as my drive did a resonance cascade and I'll be afk for a couple of days.
Commented 9 months ago2024-02-17 21:49:10 UTC Comment #105988
LOL choose your fighter: "mamamamamamajakldjfkjksdjflksjdfmama" or "mnmqnmnnqmnmnqnmn" im sorry xD
Commented 9 months ago2024-02-20 13:55:04 UTC Comment #105993
Back from AFK, got HL and JACK back and working again.

I tested light_surface and it works exactly as I expected, proving the description is indeed incorrect. I will pass my test map to you for you to incorporate into this page. (tip: gl_wireframe 1 would be useful when taking screenshots for this map)
Edit 2024-03-17
No correction on the above has been made yet. As of now the information on light_surface page is updated and correct, yet this page is still repeating the outdated and incorrect information.
Commented 8 months ago2024-04-06 03:52:27 UTC Comment #106111
可以在这个页面对灯光样式有一个直观的预览:
You can have an intuitive preview of the lighting styles on this page:

https://www.bilibili.com/read/cv26034264/?spm_id_from=333.337.0.0
Commented 5 months ago2024-06-25 11:01:32 UTC Comment #106212
I've added some examples of _fdist and _frange to the info_surface entity part.
Commented 4 months ago2024-07-25 13:18:35 UTC Comment #106269
Added undocumentend features: _diffuse_light2 and info_chopscale.
Commented 2 months ago2024-09-13 07:20:16 UTC Comment #106394
I'm shocked to find today that for whatever reason default builds of VHLT removes all falloff code from the executable. No _falloff KV, no -falloff # argument. Codebases that have #ifdefs removed outright removed the code for the feature altogether! Idk how falloff even functions now.

You must log in to post a comment. You can login or register a new account.