Darkplaces lighting

From Blood Wiki
Revision as of 23:20, 5 August 2012 by VorteX (Talk | contribs)

Jump to: navigation, search
This page is not finished
You can help by editing and extending it.
This page requires a screenshot or video of the subject
Want to make one?

Darkplaces engine uses combined lighting model. Several lighting methods are implemented to give best results at cases they are aimed for.

Contents

Lighting model

Lighting visualized. Blue is shadow volumes, bright orange is zones being processed for dynamic realtime lighting.

Darkplaces uses a variation of Phong shading as a default lighting model. It is based on per-pixel lighting - a technique of computing lighting equations for each pixel independently. Renderer contains lots of tricks to allow shading to be fast and flexible. Default model is used on both GL2.0 rendering paths and pre-shader rendering paths (GL1.4), although not all lighting features are possible on pre-shader fixed rendering pipeline.

Lighting are breaked into the passes:

  1. Base pass (lightmap/lightgrid/vertex lighting)
  2. Dynamic light 1
  3. Dynamic light 2
  4. ...
  5. Dynamic light X
  6. Photon Mapping (optional)
  7. Fog (optional)

Basically Darkplaces lighting model involves this data to be processed for each pixel:

  • Vertex normal : values between vertices of pixel's triangle are interpolated by Gouraud shading
  • Color Map : base texture (best way to use diffuse texture)
  • Normal Map : texture storing additional surface curvature (optionally, alpha storing height)
  • Gloss Map : texture is used for specular and containing gloss color (RGB) and exponent mod (alpha)
  • Glow Map : texture's local luminance texture, RGB additive blended texture that entirely ignores shading
  • Light Vector : vector of light direction (either calculated for realtime light or got from deluxemap lightmap component)
  • Eye Vector : being computed for each pixel, this vector is used for specular calculation.

Attenuation

Dynamic lights in Darkplaces engine are omnidirectional, using linear falloff.

 Spotlights and projected dynamic lights could be simulated with cubemap filters.

Static lights that is used for lightmap calculations are opposite. They have a variety of options for controlling attenuation (this options is only used in Q3map2 LIGHT stage):

  • target and radius : simulating spot lights with cone falloff
  • _sun flag - infinite distance lights, constant direction
  • _deviance and _samples - non-point lights

Shading

Shading is done by using dotproduct of light vector and pixel normal. Some ambient lighting could be added for a more smooth result.

Important: Lightmaps by default dont have shading since they lack light direction data. In order to make lightmaps to use whole shading cycle, map compiler tool should be configured to export deluxemaps (second lightmap set which store per-pixel light directions)

Rough shading algorithm explanation:

// Surface's vertex normals are always supplied, texture normalmap is forced to default RGB '128 128 255' if not found
PixelNormal = Surface.VertexNormal + Texture.NormalMap;
// LightSource are only defined for dynamic lights
// LightmapGlobal.AmbientLight is r_ambient cvar
// Material.AmbientLight is set by dprtlightambient matrial keyword and only applicable to dynamic lights
AmbientLight = LightSource.AmbientLight + LightmapGlobal.AmbientLight + Material.AmbientLight;
// Since LightSource are only defined for dynamic lights, for all static lighting it defaults to 1
DiffuseLight = LightSource.DiffuseLight;
Shading = dotproduct(PixelNormal, LightVector) * DiffuseLight + AmbientLightAmount;
 r_shadow_usenormalmap : Enables use of normalmap texture for lighting. Setting this to to will make only vertex normals to be used.
 r_shadow_bumpscale_basetexture : Forces normalmap to be automatically calculated from color texture by using it as bumpmap, value controls magnitude. Requires r_restart.
 r_shadow_bumpscale_bumpmap : Normalmap can be supplied as _bump texture, in this case engine converts it to normalmap on load, values is magnitude. Requires r_restart.
 r_glsl_deluxemapping : Use full shading on lightmapped surfaces. A value of 2 forces deluxemap shading even if surface have no one.
 r_ambient : Amount of ambient light to be added to all surfaces. Makes level brighter.

Specular

Specular are optional and could be tweaked per-material.

Specular offers two parameters to mess with:

  • Specular exponent : intensity of specular effect, this could be very high or very low. Basically its just a modifier to gloss texture.
  • Specular power : how 'sharp' gloss is, high values are used to make texture to be plastic-like, while lower ones are suitable for matte surfaces. Basically its just a modifier to gloss texture's alpha channel (which is forced to 1 if not supplied).

Gloss may be forced (see r_shadow_gloss 2 below), in this case texture, if missing its own gloss map, gets a white image for gloss map and parameters from a cvars.

Rough specular algorithm explanation:

// Global.GlossIntensity is controlled by r_shadow_glossintensity or r_shadow_glossintensity2 if gloss is forced
// Material.GlossIntensityMod is set by dpglossintensitymod material keyword
SpecularColor = Texture.GlossMap * Global.GlossIntensity * Material.GlossIntensityMod;
// Global.GlossExponent is controlled by r_shadow_glossexponent or r_shadow_glossexponent2 if gloss is forced
// Material.GlossExponentModis set by dpglossexponentmod material keyword
SpecularExponent = Texture.GlossMap.Alpha * Global.GlossExponent * Material.GlossExponentMod;
// this is rough specular calculation
// optionally, engine can use real reflection map to get specular normal (see r_shadow_glossexact below)
SpecularNormal = PixelNormal + EyeVector;
Specular = SpecularColor * power(dotproduct(PixelNormal, SpecularNormal), SpecularExponent)
 r_shadow_glossintensity : Global intensity for specular calculations, default is 1.
 r_shadow_gloss2intensity : Global intensity for specular calculations applied for forced-gloss surfaces, default is 1.
 r_shadow_glossexponent : Global gloss exponent used as a base in shader calculations.
 r_shadow_gloss2exponent : Same one used for forced-gloss surfaces.
 r_shadow_glossexact : Use real reflection math for gloss calculation. This is slower and little more correct.

Shadows

Shadows are most valuable part of realtime lighting. They are increasing scene depth so it looks more realistic. Like with materials, power has a price: shadows are quite complex render task, many lights casting many shadows may decrease rendering speed significantly.

Important: Map designer should plan his map with this limitation in mind - there should be no situation of many lights being seen from a certain point, or user will experience a game slowdown.

Darkplaces supports two realtime shadowing techniques.

Stencil shadows

Stencil shadow volumes is a base shadow rendering method Darkplaces.

This technique is well known for it's shadows not having penumbra. Many other restrictions (high fillrate hit, bad scalability) make this method to be used only on a few games (such as Doom 3).

 r_shadow_polygonfactor : how much to enlarge shadow volume polygons when rendering (should be 0!)
 r_shadow_polygonoffset : how much to push shadow volumes into the distance when rendering, to reduce chances of zfighting artifacts (should not be less than 0)
 r_shadow_frontsidecasting : whether to cast shadows from illuminated triangles (front side of model) or unlit triangles (back side of model)
 r_showshadows : Show areas covered by shadow volumes. Useful for finding out why some areas of the map render slowly (bright blue = lots of passes, slow). Only matters if using shadow volumes.

Shadowmapping

Since 2010 shadow mapping was implemented by Eihrul.

Shadowmapping have a number of advantages over shadow volume rendering and is considered to replace it:

  • Penumbra
  • Fast to render (especially on complex area maps)
  • Takes less CPU time (as construction of shadow volumes is not required)
  • Distance-based LOD (far lights rendered with lower shadowmap resolution)
  • Shadow edges are not sharp

Other light models

Darkplaces includes other lighting models which are used eventually:

Fake light

A developer-only mode which is forced on non-lit maps (ones which was compiled and didnt get LIGHT phase). This is infinite realtime light that is cast from eye position.

Cel shading

Altered shading for default lighting model.

Lightmap

Lightmap with no deluxemap applied (just an old lightmap with no per-pixel lighting effects)

Fullbright

No lighting applied (all textures at their full brightness)

Light methods

There is 4 lighting methods used in Darkplaces:

  • Vertex lighting - static lighting, aimed at big counts of simple surfaces
  • Lightmaps - static lighting, aimed at surfaces that receives shadows from static objects
  • Lightgrid - static lighting, aimed at moving entities
  • Dynamic lighting - full realtime dynamic lighting (each light is a separate pass), aimed at switchable and moving lightsources that lights moving entities

Comparison of different lighting methods

Task Vertex
lighting
Lightmap Lightgrid Realtime lighting
Details Low Medium Low High
Render speed Fastest Fast Fastest Slow
Precomputation time Short Long Medium N/A
RAM usage Low High Low Low
Shadows No Yes No Yes
Penumbra N/A Yes N/A Partial
Number of lights Large Large Large Small
Surface-based effects
Bumpmapping Yes Yes Yes Yes
Specular Yes Yes Yes Yes
Cubemap filters No Partial No Yes
Per-light diffuse/ambient/specular scale No No No Yes
Non-point 'area' lights Yes Yes Yes No
Light styles No No No Yes
Moving lights No No No Yes
Global illumination
Precomputation time Long Very long Long N/A
Rendering speed N/A N/A N/A Slow
Quality High High High Low
Used to light
Map surfaces Yes Yes No Yes
Static BModels Yes Yes Optional Yes
Moving/rotating BModels No No Optional Yes
Animated models No No Yes Yes

Light effects

Darkplaces supports a number of special lighting effects.

Light styles

Stub!

Light coronas

Coronas aimed to simulate glow around dynamic lights, which looks good on small and medium size lights. Coronas are customised per-light (size and brightness) an also can be placed without lights.

 r_coronas : Brightness of corona effects. 0 disables coronas.
 r_coronas_occlusionquery : Fades coronas according to visibility. Bad perormance (synchoronus rendering), even worse on multi-GPU.
 r_coronas_occlusionquerysize : Size of lightsource for corona occlusion checksum. Usial value is 0.1

Light cubemap filtering

A technique for modeling non-uniform light distribution according to direction, for example a lantern may use a cubemap to describe the light emission pattern of the cage around the lantern (as well as soot buildup discoloring the light in certain areas), often also used for softened grate shadows and light shining through a stained glass window (done crudely by texturing the lighting with a cubemap), another good example would be a discolight.

Any dynamic lightsource can have cubemap attached.

Planar shadows

Simplified global shadows which are cast from entities, not from lights (so planar shadows are just filters, they dont do any lighting math).

Planar shadows are either stencil or shadowmapped if shadowmapping is on.

Blood Omicide using planar shadows to simulate sunlight in outdoor locations.

Customized modellight

Lightgrid sampling (diffuse, ambient and light vector components) can be overriden by Client Side QuakeC. Allows various lighting effects on models (strobing, using different positions for sampling etc.)

Fog

Fog are global. Optionally, height plane and height texture can be defined which will make fog to fade with height.

Fog have the following components:

  • density - how much fog to add per distance, this is virtual value. 1 means very strong fog.
  • red - red component of fog color
  • green - green component of fog color
  • blue - blue component of fog color
  • alpha - fog effect opacity (default is 1)
  • mindist - distance to start applying fog at
  • maxdist - maximal distance apply fog at
  • top - origin of height plane at worldspace (game units)
  • height - fog height fade in game units
  • fadetexture - horizontal texture that resembles fading, left pixel if top bright, right is top dark. Can be used for non-linear fading.

Fog are set by console commands:

 fog <density> <red> <green> <blue> [<alpha> <mindist> <maxdist> <top> <height>] : Sets the global fog
 fog_heighttexture <density> <red> <green> <blue> <alpha> <mindist> <maxdist> <top> <height> <fadetexture> : Sets the global fog with customized fade texture

Tweaking

Darkplaces lighting renderer have a bunch of misc options to tweak.

Optimizations

For best performance, all optimisations should be on.

 r_shadow_scissor : Use scissor optimization of light rendering (restricts rendering to the portion of the screen affected by the light)
 r_shadow_sortsurfaces : Improve performance by sorting illuminated surfaces by texture
 r_shadow_usebihculling : Use Bounding Interval Hierarchy for culling lit surfaces instead of Binary Space Partitioning

Light attenuation

This console variables change attenuation for all dynamic lights.

 r_shadow_lightattenuationdividebias : Controls the speed of light fading, 1 is default linear fade.
 r_shadow_lightattenuationlinearscale : Linear scale applied during attenuation, larger values will make lesser half-light zones
 r_shadow_lightintensityscale : Renders all lights brighter or darker
 r_shadow_lightradiusscale : Renders all world lights larger or smaller

Getting lights on the map

Engine supports two ways to get lights on the map.

World lights

Worlds lights are loaded from external .rtlights file supplied with a map (foo.bsp will try to load foo.rtlights). If there are not .rtlights file, engine tries to load lights from a map "light" entities, which often is grude and terrible slow (as "lights" are maked for map compiler LIGHT stage raytracer, not for reatime rendering). So producing a good .rtlights folr is very first step in a process of map creation.

World lights are static, meaning they canot be moved, rotated, altered during a game.

Tip: Blood Omnicide is using world lights to place lights for a Q3map2 LIGHT phase. So unlike Quake, which should have both "light" entities and .rtlights, Blood Omnicide .rtlights containins all map static lights

Each world light can have this parameters:

  • origin : position
  • angles : rotation
  • color : RGB light color
  • radius : radius of light in game units
  • corona : corona intensity (0 to disable)
  • coronasize : size of corona (this is multiplier to light radius)
  • style : lights style number (see lightstyles above)
  • shadows: whether to cast shadows from light
  • cubemap : a path to cubemap filter texture
  • ambient : ambient light intensity (ignores shading, makes lighting to be more 'flat')
  • diffuse : shading light intensity (default is 1)
  • specular : specular intensity (default is 1)
  • normalmode : if this flag is set, light will be draws if cvar r_shadow_realtime_world is 0
  • realtimemode : if this flag is set, light will be draws if cvar r_shadow_realtime_world is 1

Blood Omnicide tips:

Tip: A combination of normalmode = 0, realtimemode = 0 to mark lights which are only appear on lightmap
Tip: Light style 1 will make a dynamic lights that will not appear on lightmap
Tip: Cubemap-filtered lights dont appear on lightmap

Console variables:

 r_shadow_realtime_world : Enables rendering of full world lighting (whether loaded from the map, or a .rtlights file, or a .ent file, or a .lights file produced by hlight)
 r_shadow_realtime_world_lightmaps : Brightness to render lightmaps when using full world lighting
 r_shadow_realtime_world_shadows : Enables rendering of shadows from world lights
 r_shadow_realtime_world_compile : Enables compilation of world lights for higher performance rendering (shadow volumes only)
 r_shadow_realtime_world_compileportalculling : Enables portal-based culling optimization during compilation (overrides compilesvbsp)
 r_shadow_realtime_world_compileshadow : Enables compilation of shadows from world lights for higher performance rendering (shadow volumes only)
 r_shadow_realtime_world_compilesvbsp : Enables svbsp optimization during compilation (slower than compileportalculling but more exact)
Tip: In Blood Omnicide, this console varisables are hardcoded since its using a combination of full realtime lightning and lightmaps. Tweak this settings only for debugging purposes or if you want to break something.

Dynamic lights

Dynamic lights are cast from entities. This could be both server-side entities such as rockets or client-side entities such as explosions.

 r_shadow_realtime_dlight : Enables rendering of dynamic lights such as explosions and rocket light
 r_shadow_realtime_dlight_portalculling : Enables portal optimization on dynamic lights
 r_shadow_realtime_dlight_shadows : Enables rendering of shadows from dynamic lights
 r_shadow_realtime_dlight_svbspculling : Enables svbsp optimization on dynamic lights

Galleries

Per-pixel lighting

Personal tools
Namespaces

Variants
Actions
Navigation
Toolbox