Darkplaces lighting
m |
|||
Line 38: | Line 38: | ||
===Shading=== | ===Shading=== | ||
Shading is done by using dotproduct of light vector and pixel normal. Some ambient lighting could be added for a more smooth result. | Shading is done by using dotproduct of light vector and pixel normal. Some ambient lighting could be added for a more smooth result. | ||
+ | |||
+ | {{important|[[lightmap|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: | Rough shading algorithm explanation: | ||
Line 53: | Line 55: | ||
{{cvar|r_shadow_bumpscale_basetexture|Forces normalmap to be automatically calculated from color texture by using it as bumpmap, value controls magnitude. Requires r_restart.}} | {{cvar|r_shadow_bumpscale_basetexture|Forces normalmap to be automatically calculated from color texture by using it as bumpmap, value controls magnitude. Requires r_restart.}} | ||
{{cvar|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.}} | {{cvar|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.}} | ||
+ | {{cvar|r_glsl_deluxemapping|Use full shading on lightmapped surfaces. A value of 2 forces deluxemap shading even if surface have no one.}} | ||
{{cvar|r_ambient|Amount of ambient light to be added to all surfaces. Makes level brighter.}} | {{cvar|r_ambient|Amount of ambient light to be added to all surfaces. Makes level brighter.}} | ||
Revision as of 23:20, 5 August 2012
Darkplaces engine uses combined lighting model. Several lighting methods are implemented to give best results at cases they are aimed for.
Contents |
Lighting model
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:
- Base pass (lightmap/lightgrid/vertex lighting)
- Dynamic light 1
- Dynamic light 2
- ...
- Dynamic light X
- Photon Mapping (optional)
- 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.
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.
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;
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)
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.
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).
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.
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:
Tweaking
Darkplaces lighting renderer have a bunch of misc options to tweak.
Optimizations
For best performance, all optimisations should be on.
Light attenuation
This console variables change attenuation for all dynamic lights.
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.
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:
Console variables:
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.