Shader Manual

Based on the Quake III Arena Shader Manual by Paul Jaquays and Brian Hook and Xreal shader manual by Robert Beckebans (adapted by 0xA5EA)

Preface: Making Your Own Shaders/Materials

The Manual for the GtkRadiant editor program contains a section called Creating New Assets that has the necessary information for setting up the files to create your own custom KingpinQ3 shaders. It is recommended that you study the scripts in this document and in the individual shader scripts. Pay careful attention to syntax and punctuation. This is where you are most likely to make mistakes.

Introduction

The graphic engine for KingpinQ3 has taken a step forward by putting much more direct control over the surface qualities of textures into the hands of designers and artists. In writing this manual, we have tried to define the concepts and tools that are used to modify textures in a way that, it is hoped, will be graspable by users who already have basic knowledge of computer graphics but are not necessarily computer programmers. It is not a tutorial, nor was it intended to be one.

What is a Shader?

Shaders are short text scripts that define the properties of a surface as it appears and functions in a game world (or compatible editing tool). By convention, the documents that contain these scripts usually has the same name as the texture set which contains the textures being modified (e.g; Kpq3_bricks, Misc_metal, Kpq3_probs, etc,). Several specific script documents have also been created to handle special cases, like liquids, sky and special effects.

For KingpinQ3, Shader scripts are located in KingpinQ3/basekpq3/materials.

A KingpinQ3 shader file consists of a series of surface attribute and rendering instructions formatted within braces ("{" and "}"). Below you can see a simple example of syntax and format for a single process, including the kmap2 keywords or "Surface Parameters", which follow the first bracket and a single bracketed "stage":

textures/Kpq3_liquids/lava
{
  deformVertexes wave sin 0 3 0 0.1
  tessSize 64
  {
     map textures/Kpq3_liquids/lava.png
  }
}

Shader Name and File Conventions

The first line is the shader name. Shader names can be up to 63 characters long. The names are often a mirror of a pathname to a .png file without the extension or basedir (KingpinQ3/basekpq3 in our case), but they do not need to be.

Shaders that are only going to be referenced by the game code, not modeling tools, often are just a single world, like "projectionShadow" or "viewBlood".

Shaders that are used on characters or other polygon models need to mirror a .png file, which allows the modelers to build with normal textures, then have the special effects show up when the model is loaded into the game.

Shaders that are placed on surfaces in the map editor commonly mirror a .png file, but the "qer_editorimage" shader parameter can force the editor to use an arbitrary image for display.

Shader pathnames have a case sensitivity issue - on windows, they aren't case sensitive, but on unix they are. Try to always use lowercase for filenames, and always use forward slashes "/" for directory separators.

Shader Types

The keywords that affect shaders are divided into two classes. The first class of keywords are global parameters. Some global parameters ( "surfaceparms." And all "kmap_" keywords) are processed by kmap2, and change physical attributes of the surface that uses the shader. These attributes can affect the player. To see changes in these parameters one must re-bsp the map.

The remaining global keywords, and all Stage Specific Keywords are processed by the renderer. They are appearance changes only and have no effect on game play or game mechanics. Changes to any of these attributes will take effect as soon as the game goes to another level or vid_restarts (type command vid_restart in the game console).

Shader keywords are not case sensitive.

NOTE: some of the shader commands may be order dependent, so it's good practice to place all global shader commands (keywords defined in this section) at the very beginning of the shader and to place shader stages at the end (see various examples).

Key Concepts

Ideally, a designer or artist who is manipulating textures with shader files has a basic understanding of wave forms and knows about mixing colored light (high school physics sort of stuff). If not, there are some concepts you need to have a grasp on to make shaders work for you.

Surface Effects vs. Content Effects vs. Deformation Effects

Shaders not only modify the visible aspect of textures on a geometry brush, curve, patch or mesh model, but they can also have an effect on both the content, "shape," and apparent movement of those things. A surface effect does nothing to modify the shape or content of the brush. Surface effects include glows, transparencies and rgb (red, green, blue) value changes. Content shaders affect the way the brush operates in the game world. Examples include water, fog, nonsolid, and structural. Deformation effects change the actual shape of the affected brush or curve, and may make it appear to move.

Normalization: a Scale of 0 to 1

The mathematics in KingpinQ3 use a scale of 0.0 to 1.0 instead of 0 to 255. Most computer art programs that can express RGB values as numbers use the 0 to 255 scale. To convert numbers, divide each of the art program's values for the component colors by 255. The resulting three values are your Quake III Arena formula for that color component. The same holds true for texture coordinates.

Math and Logic

Materials in KingpinQ3 can contain mathematical and logical expressions. These expressions are evaluated for each material every frame, and are what cause normally boring surfaces to come alive. This is a replacement for the rather limited shader commands in Quake 3 such as tcMod scroll, rgbGen, etc.

Let's take a look at a material to see these features in use:

models/weapons/gauntlet/gauntlet3fx
{
  translucent
  noShadows
  {
    if ( parm7 > 3 )
    blend add
    map models/weapons/gauntlet/soulcube3fx
    rgb scTable[ time * .5 ]
  }
}

In KingpinQ3, certain stages of the material can be selectively turned on and off. The 'if' command in this example means "only draw this material if parm7 is greater than 3." There are a few places where parm7 can get set, one of them is in the editor with the 'shaderParm0' to 'shaderParm11' keys. Another place is in the script file (such as with weapons). Of course, it can also get set in the code.

Notice the use of a lookup table in this material. Here we are using 'time' (which is a floating point number that increases forever) to look up a value in 'scTable' (which was defined using a 'table' decl earlier).

The mathematical operators you can use in a material are , /, *, -, and . You can also use the boolean operators <, >, <=, >=, ==, !=, &x%x, and ||. The meaning of the symbols is the same as in C/C+, Java, PHP, etc. Mathematical expressions should be enclosed in parenthesis (there are cases where they don't have to be, such as when they are used as an index to a lookup table, but it never hurts to have too many. For the operands, you can use a lookup table, any numerical constant, and any of the following variables:

  • time: Forever increasing floating point value that returns the current time in seconds
  • parm0-parm11: Parameters that can be set a number of ways (discussed above)
  • global0-global7: Not used right now
  • fragmentShaders: Constant that is 1 if ARB fragment programs are available. This is mostly used for disabling a stage by specifying "if ( fragmentPrograms == 1 )"
  • sound: The current sound amplitude of the entity using this material. This is used to create light materials that pulse with the sound.

Parameter Keys

These are keywords used in this document to differenciate between different input types.

Every parameter is a key of a certain type:

  • <float>: Any number
  • <int>: Any number without a fractional part
  • <string>: Any value enclosed in quotes
  • <index>: An integer number that is an index into an array
  • <map>: An image map, which may include image programs (below)
  • <exp>: An expression that is evaluated every frame.

Tables

In Quake3, you could do all kinds of neat things with sin waves, saw tooth waves, square waves and other types of waves, but you were pretty much screwed if you wanted any kind of non standard wave form. In KingpinQ3, you can define arbitrary data lookup tables, then reference them in your materials.

The format of a table definiton is:

table <tablename> { [snap] [clamp] { <data>, <data>, ... } }

Where [snap] is an optional key word which means "jump directly from one value to the other (don't blend between values)" and [clamp] is an optional key word which means "don't wrap around if the index is outside the range of table elements, (return the first value if less or the last value if it's more)". Both keywords are optional, and can be used together.

Now, armed with this knowledge, we can easily construct a square wave lookup table:

table squarewave { snap { 0, 1 } }

The sin table is a bit harder, but lucky for you, it's already defined gfx.mtr

General Shader Keywords

Important Note: Once again, be aware that some of the shader commands may be order dependent, so it's good practice to place all global shader commands (keywords defined in this section) at the very beginning of the shader and to place shader stages at the end (see various examples).

These Keywords are global to a shader and affect all stages. They are also ignored by kmap2.

skyParms <farbox> <cloudheight> <nearbox>

Specifies how to use the surface as a sky, including an optional far box (stars, moon, etc), optional cloud layers with any shader attributes, and an optional near box (mountains in front of the clouds, etc).

<Farbox> Specifies a set of files to use as an environment box behind all cloud layers. Specify "-" for no farbox, or a file base name. A base name of "env/test" would look for files "env/test_rt.png", "env/test_lf.png", "env/test_ft.png", "env/test_bk.png", "env/test_up.png", "env/test_dn.png" to use as the right / left / front / back / up / down sides.

<cloudheight> controls apparent curvature of the cloud layers - lower numbers mean more curvature (and thus more distortion at the horizons). Higher height values create "flatter" skies with less horizon distortion. Think of height as the radius of a sphere on which the clouds are mapped. Good ranges are 64 to 256. The default value is 128.

<nearbox> Specified as farbox, to be alpha blended on top of the clouds. This has not been tested in a long time, so it probably doesn't actually work. Set to "-" to ignore.

Design Notes:
  • If you are making a map where the sky is seen by looking up most of the time, use a lower cloudheight value. Under those circumstances the tighter curve looks more dynamic. If you are making a map where the sky is seen by looking out windows most of the time or has a map area that is open to the sky on one or more sides, use a higher height to make the clouds seem more natural.
  • It is possible to create a sky with up to 8 cloud layers, but that also means 8 processing passes and a potentially large processing hit.
  • Be aware that the skybox does not wrap around the entire world. The "floor" or bottom face of the skybox is not drawn by the game. If a player in the game can see that face, they will see the "hall of mirrors" effect.

Example: Sky script

textures/skies/gaja
{
  qer_editorimage cubemaps/zihaben/painted2_ny.png
  noFragment
  noshadows
  forceOpaque                
  noimpact
  sky
  nolightmap
  kmap_sun  .9 .4 .0   50 700 45
  //kmap_skylight 700 3
  //kmap_surfacelight 100 // 160
  //kmap_lightimage cubemaps/zihaben/painted2_pz.png //textures/zih_gaja/00mesh_light.png
  {
    stage skyboxMap
    noPicMip
    cubeMap    cubemaps/zihaben/painted2
  }
}

cull <side>

Every surface of a polygon has two sides, a front and a back. Typically, we only see the front or "out" side. For example, a solid block you only show the front side. In many applications we see both. For example, in water, you can see both front and a back. The same is true for things like grates and screens.

To "cull" means to remove. The value parameter determines the type of face culling to apply. The default value is cull front if this keyword is not specified. However for items that should be inverted then the value back should be used. To disable culling, the value disable or none should be used. Only one cull instruction can be set for the shader.

cull front, backSided

The front or "outside" of the polygon is not drawn in the world. This is the default value. It is used if the keyword "cull" appears in the content instructions without a <side> value or if the keyword cull does not appear at all in the shader.

This also implies noShadows

cull back

Cull back removes the back or "inside" of a polygon from being drawn in the world.

cull disable, cull none, twoSided

Neither side of the polygon is removed. Both sides are drawn in the game. Very useful for making panels or barriers that have no depth, such as grates, screens, metal wire fences and so on and for liquid volumes that the player can see from within. Also used for energy fields, sprites, and weapon effects (e.g.; plasma).

Design Notes: For things like grates and screens, put the texture with the cull none property on one face only. On the other faces, use a non-drawing texture.

deformVertexes

This function performs a general deformation on the surface's vertexes, changing the actual shape of the surface before drawing the shader passes. You can stack multiple deformVertexes commands to modify positions in more complex ways, making an object move in two dimensions, for instance.

deformVertexes wave
<func> <base> <amplitude> <phase> <freq>

Designed for water surfaces, modifying the values differently at each point. It accepts the standard wave functions of the type sin, triangle, square, sawtooth or inversesawtooth. The "div" parameter is used to control the wave "spread" - a value equal to the tessSize of the surface is a good default value (tessSize is subdivision size, in game units, used for the shader when seen in the game world) .

deformVertexes normal
<func> <base> <amplitude ~0.1-~0.5> <frequency ~1.0-~4.0>

This deformation affects the normals of a vertex without actually moving it, which will effect later shader options like lighting and especially environment mapping. If the shader stages don't use normals in any of their calculations, there will be no visible effect.

Design Notes: Putting values of 0.1 t o 0.5 in Amplitude and 1.0 to 4.0 in the Frequency can produce some satisfying results. Some things that have been done with it: A small fluttering bat, falling leaves, rain, flags.

deformVertexes bulge <bulgeWidth> <bulgeHeight> <bulgeSpeed>

This forces a bulge to move along the given s and t directions. Designed for use on curved pipes.

Specific parameter definitions for deform keywords:

This is roughly defined as the size of the waves that occur. It is measured in game units. Smaller values create a greater density of smaller wave forms occurring in a given area. Larger values create a lesser density of waves, or otherwise put, the appearance of larger waves. To look correct this value should closely correspond to the value (in pixels) set for tessSize (tessellation size) of the texture. A value of 100.0 is a good default value (which means your tessSize should be close to that for things to look "wavelike").

<func> This is the type of wave form being created. Sin stands for sine wave, a regular smoothly flowing wave. Triangle is a wave with a sharp ascent and a sharp decay. It will make a choppy looking wave forms. A square wave is simply on or off for the period of the frequency with no in between. The sawtooth wave has the ascent of a triangle wave, but has the decay cut off sharply like a square wave. An inversesawtooth wave reverses this.

<base> This is the distance, in game units that the apparent surface of the texture is displaced from the actual surface of the brush as placed in the editor. A positive value appears above the brush surface. A negative value appears below the brush surface. An example of this is the Quad effect, which essentially is a shell with a positive base value to stand it away from the model surface and a 0 (zero) value for amplitude.

<amplitude> The distance that the deformation moves away from the base value. See Wave Forms in the introduction for a description of amplitude.

<phase> See Wave Forms in the introduction for a description of phase)

<frequency> See Wave Forms in the introduction for a description of frequency)

Design Note: The div and amplitude parameters, when used in conjunction with liquid volumes like water should take into consideration how much the water will be moving. A large ocean area would have have massive swells (big div values) that rose and fell dramatically (big amplitude values). While a small, quiet pool may move very little.

deformVertexes move <x> <y> <z> <func> <base> <amplitude> <phase> <freq>

This keyword is used to make a brush, curve patch or md3 model appear to move together as a unit. The <x> <y> and <z> values are the distance and direction in game units the object appears to move relative to it's point of origin in the map.

The <func> <base> <amplitude> <phase> and <freq> values are the same as found in other wave form manipulations.

The product of the function modifies the values x, y, and z. Therefore, if you have an amplitude of 5 and an x value of 2, the object will travel 10 units from its point of origin along the x axis. This results in a total of 20 units of motion along the x axis, since the amplitude is the variation both above and below the base.

It must be noted that an object made with this shader does not actually change position, it only appears to.

Design Note: If an object is made up of surfaces with different shaders, all must have matching deformVertexes move values or the object will appear to tear itself apart.

DeformVertexes autosprite

This function can be used to make any given triangle quad (pair of triangles that form a square rectangle) automatically behave like a sprite without having to make it a separate entity. This means that the "sprite" on which the texture is placed will rotate to always appear at right angles to the player's view as a sprite would. Any four-sided brush side, flat patch, or pair of triangles in an .md3 model can have the autosprite effect on it. The brush face containing a texture with this shader keyword must be square.

Design Note: This is best used on objects that would appear the same regardless of viewing angle. An example might be a glowing light flare.

DeformVertexes autosprite2

Is a slightly modified "sprite" that only rotates around the middle of its longest axis. This allows you to make a pillar of fire that you can walk around, or an energy beam stretched across the room.

nopicmip

This causes the texture to ignore user-set values for the r_picmip cvar command. The image will always be high resolution. Example: Used to keep images and text in the heads up display from blurring when user optimizes the game graphics.

nomipmaps

This implies nopicmip, but also prevents the generation of any lower resolution mipmaps for use by the 3d card. This will cause the texture to alias when it gets smaller, but there are some cases where you would rather have this than a blurry image. Sometimes thin slivers of triangles force things to very low mipmap levels, which leave a few constant pixels on otherwise scrolling special effects.

This sets the texture filtering for all stages to GL_LINEAR.

polygonOffset

Surfaces rendered with the polygonOffset keyword are rendered slightly off the polygon's surface. This is typically used for wall markings and "decals." The distance between the offset and the polygon is fixed. It is not a variable in Quake III Arena.

portal

Specifies that this texture is the surface for a portal or mirror. In the game map, a portal entity must be placed directly in front of the texture (within 64 game units). All this does is set "sort portal", so it isn't needed if you specify that explicitly.

sort <value>

Use this keyword to fine-tune the depth sorting of shaders as they are compared against other shaders in the game world. The basic concept is that if there is a question or a problem with shaders drawing in the wrong order against each other, this allows the designer to create a hierarchy of which shader draws in what order.

The default behavior is to put all blended shaders in sort "additive" and all other shaders in sort "opaque", so you only need to specify this when you are trying to work around a sorting problem with multiple transparent surfaces in a scene.

The value here can be either a numerical value or one of the keywords in the following list (listed in order of ascending priority):

  • portal (1): This surface is a portal, it draws over every other shader seen inside the portal, but before anything in the main view.
  • sky (2): Typically, the sky is the farthest surface in the game world. Drawing this after other opaque surfaces can be an optimization on some cards. This currently has the wrong value for this purpose, so it doesn't do much of anything.
  • opaque (3): This surface is opaque (rarely needed since this is the default with no blendfunc)
  • banner (6) : Transparent, but very close to walls.
  • underwater (8): Draw behind normal transparent surfaces.
  • additive (9): normal transparent surface (default for shaders with blendfuncs)
  • nearest (16): this shader should always sort closest to the viewer, e.g. muzzle flashes and blend blobs
  • postProcess (17): Image manipulation, requires the scene to be rendered.

diffuseMap <map>

This keyword is a shortcut for:

{
  stage diffuseMap
  map <map>
}

bumpMap <map>, normalMap <map>

This keyword is a shortcut for:

{
  stage bumpMap
  map <map>
}

specularMap <map>

This keyword is a shortcut for:


{
  stage specularMap
  map <map>
}

DECAL_MACRO

This keyword is a shortcut for:

polygonOffset 1
discrete
sort decal
noShadows

Kmap2 Specific Shader Keywords

These keywords change the physical nature of the textures and the brushes that are marked with them. Changing any of these values will require the map to be re-compiled. These are global and affect the entire shader.

tessSize <amount>

For consistency's sake, this really should have been called kmap_tessSize. But it wasn't. The tessSize shader controls the tessellation size (how finely a surface is chopped up in to triangles), in game units, of the surface. This is only applicable to solid brushes, not curves, and is generally only used on surfaces that are flagged with the deformVertexes keyword. Abuse of this can create a huge number of triangles. This happens during kmap processing, so maps must be reprocessed for changes to take effect.

Design Note: It can also be used on tesselating surfaces to make sure that tesselations are large, and thus, less costly in terms of triangles created.

kmap_backshader <shadername>

This allows a brush to use a different shader when you are inside it looking out. By way of example, this would allow a water brush (or other) surfaces to have a different sort order (see sort above) or appearance when seen from the inside.

kmap_globaltexture

Use this shader in the global keyword commands whenever the tcMod scale function is used in one of the later render stages. Many problems with getting shader effects to work across multiple adjacent brushes are a result of the way q3map optimizes texture precision. This option resolves that, but at the expense of some precision of the textures when they are far away from the origin of the map.

Surface Parameters

These keywords generate surface properties that can influence the game.

surfaceparm areaportal

A brush marked with this keyword functions as an area portal, a break in the KMAP tree. It is typically placed on a very thin brush placed inside a door entity (but is not a part of that entity). The intent is to block the game from processing surface triangles located behind it when the door is closed. It is also used by the BSPC (bot area file creation compiler) in the same manner as a cluster portal. The brush must touch all the structural brushes surrounding the areaportal.

surfaceparm clusterportal

A brush marked with this keyword function creates a subdivision of the area file (.aas) used by the bots for navigation. It is typically placed in locations that are natural breaks in a map, such as entrances to halls, doors, tunnels, etc. The intent is keep the bot from having to process the entire map at once. As with the the areaportal parameter, the affected brush must touch all the structural brushes surrounding the areaportal.

surfaceparm donotenter

Read as "do not enter." Like clusterportal, this is a bot-only property. A brush marked with donotenter will not affect non-bot players, but bots will not enter it. It should be used only when bots appear to have difficulty navigating around some map features.

surfaceparm lava

Assigns to the texture the game properties set for lava. This affects both the surface and the content of a brush.

surfaceparm metalsteps

The player sounds as if he is walking on clanging metal steps or gratings. Other than specifiying flesh, metalsteps, nosteps, or default (i.e.; specify nothing) it is currently not possible for a designer to create or assign a specific sound routine to a texture. Note: If no sound is set for a texture, then the default footsteps sound routines are heard.

surfaceparm flesh

This will cue different sounds (in a similar manner to metalsteps ) and cause blood to appear instead of bullet impact flashes.

surfaceparm nodamage

The player takes no damage if he falls onto a texture with this surfaceparm

surfaceparm nodlight

Read as "No Dee Light". A texture containing this parameter will not be affected or lit by dynamic lights, such as weapon effects. And example in Quake III Arena would be solid lava.

surfaceparm nodraw

A texture marked with nodraw will not visually appear in the game world. Most often used for triggers, clip brushes, origin brushes, and so on.

surfaceparm nodrop

When a player dies inside a volume (brush) marked nodrop, no weapon is dropped. The intend use is for "Pits of Death." Have a kill trigger inside a nodrop volume, and when the players die here, they won't drop their weapons. The intent is to prevent unnecessary polygon pileups on the floors of pits.

surfaceparm noimpact

World entities will not impact on this texture. No explosions occur when projectiles strike this surface and no marks will be left on it. Sky textures are usually marked with this texture so those projectiles will not hit the sky and leave marks.

surfaceparm nomarks

Projectiles will explode upon contact with this surface, but will not leave marks. Blood will also not mark this surface. This is useful to keep lights from being temporarily obscured by battle damage.

Design Note: Use this on any surface with a deformVertexes keyword. Otherwise, the marks will appear on the unmodified surface location of the texture with the surface wriggles and squirms through the marks.

surfaceparm nosteps

The player makes no sound when walking on this texture.

surfaceparm nonsolid

This attribute indicates a brush, which does not block the movement of entities in the game world. It applied to triggers, hint brushes and similar brushes. This affects the content of a brush.

surfaceparm origin

Used on the "origin" texture. Rotating entities need to contain an origin brush in their construction. The brush must be rectangular (or square). The origin point is the exact center of the origin brush.

surfaceparm playerclip

Blocks player movement through a nonsolid texture. Other game world entities can pass through a brush marked playerclip. The intended use for this is to block the player but not block projectiles like rockets.

surfaceparm slick

This surfaceparm included in a texture should give it significantly reduced friction.

surfaceparm slime

Assigns to the texture the game properties for slime. This affects both the surface and the content of a brush.

surfaceparm structural

This surface attribute causes a brush to be seen by the KMAP process as a possible break-point in a BSP tree. It is used as a part of the shader for the "hint" texture. Generally speaking, any opaque texture not marked as "detail" is by default, structural, so you shouldn't need to specify this.

surfaceparm trans, surfaceparm translucent

Tells KMAP that pre-computed visibility should not be blocked by this surface. Generally, any shaders that have blendfuncs should be marked as surfaceparm trans.

surfaceparm water

Assigns to the texture the game properties for water.

Editor Specific Shader Keywords

These instructions only affect the texture when it is seen in the Q3Radiant editor. They should be grouped with the surface parameters but ahead of them in sequence.

qer_editorimage < texture path/texturename>

This keyword creates a shader name in memory, but in the editor, it displays the PNG art image specified in qer_editorimage (in the example below this is textures/Kpq3_liquids/lavahell.png).

The editor maps a texture using the size attributes of the TGA file used for the editor image. When that editor image represents a shader, any texture used in any of the shader stages will be scaled up or down to the dimensions of the editor image. If a 128x128 pixel image is used to represent the shader in the editor, then a 256x256 image used in a later stage will be shrunk to fit. A 64x64 image would be stretched to fit. Be sure to check this on bouncy, acceleration, and power-up pads placed on surfaces other than 256 x 256. Use tcMod scale to change the size of the stretched texture. Remember that tcMod scale 0.5 0.5 will double your image, while tcMod scale 2 2 will halve it.

Design Notes: The base_light and gothic_light shaders contain numerous uses of this. It can be very useful for making different light styles (mostly to change the light brightnesses) without having to create a new piece of TGA art for each new shader.

textures/liquids/lavahell2 //path and name of new texture
{
  // based on this
  qer_editorimage textures/Kpq3_liquids/lavahell.png

  // cannot be cut by CSG subtract
  qer_nocarve

  // projectiles do not hit it
  surfaceparm noimpact

  // has the game properties of lava
  surfaceparm lava

  // environment lighting does not affect
  surfaceparm nolightmap

  // light is emitted
  kmap_surfacelight 3000

  // relatively large triangles
  tessSize 256

  // no sides are removed
  cull disable

  deformVertexes wave 100 sin 5 5 .5 0.02
  fogparms 0.8519142 0.309723 0.0 128 128
  {
    // base texture artwork
    map textures/liquids/lavahell.png

    //texture is subjected to turbulence
    tcMod turb .25 0.2 1 0.02

    //the turbulence is scrolled
    tcMod scroll 0.1 0.1
  }
}

qer_nocarve

A brush marked with this instruction will not be affected by CSG subtract functions. It is especially useful for water and fog textures.

qer_trans <value>

This parameter defines the percentage of transparency that a brush will have when seen in the editor (no effect on game rendering at all). It can have a positive value between 0 and 1. The higher the value, the less transparent the texture. Example: qer_trans 0.2 means the brush is 20% opaque and nearly invisible.

Stage Specific Keywords

Stage specifications only affect rendering. Changing any keywords or values within a stage will usually take effect as soon as a vid_restart is executed. KMAP ignores stage specific keywords entirely.

A stage can specify a texture map, a color function, an alpha function, a texture coordinate function, a blend function, and a few other rasterization options.

Texture map specification

map <map>

Specifies the source texture map (a 24 or 32-bit TGA file) used for this stage. The texture may or may not contain alpha channel information. The special keywords _lightmap, _white, _black or _flat may be substituted in lieu of an actual texture map name. In those cases, the texture named in the first line of the shader becomes the texture that supplies the light mapping data for the process.

cubeMap <map>

This stage uses a cube map as the image map.

Looks for _px, _py, _pz, _nx, _ny, _nz for the positive x, y, z, and negative x, y, z sides.

videoMap <map>

This stage uses a video stream as an image map.

NOTE: this is only supported by colormap stage types.

Image Program Functions

These can be used anywhere that accepts <map> and can be nested.

NOTE: this is only supported by 2D images for the map command and not cubeMap or videoMap.

heightmap(<map>, <float>)

Turns a grayscale height map into a normal map. <float> varies the bumpines.

Example:

textures/Misc_metal/metal2
{
  qer_editorimage textures/Misc_metal/metal2_d.tga
  diffusemap  textures/Misc_metal/metal2_d.tga
  specularmap textures/Misc_metal/metal2_s.tga
  bumpmap  heightmap(textures/Misc_metal/metal2_h.tga, 2)
}

addnormals(<map>, <map>)

Adds two normal maps together. Result is normalized.

Example:

textures/Kpq3_props/bl_rc_c03_d
{  
  qer_editorimage textures/Kpq3_props/bl_rc_c03_d.png
  diffusemap      textures/Kpq3_props/bl_rc_c03_d.png
  specularmap     textures/Kpq3_props/bl_rc_c03_s.png
  bumpmap addnormals(textures/Kpq3_props/bl_rc_c03_local.png, heightmap(textures/Kpq3_props/bl_rc_c03_h.png, 1))
}

displaceMap(<map>, <map>)

Sets the alpha channel to an average of the second image's RGB channels.

This is handy when we want to store a displacement map for virtual displacement mapping

into the alpha channel of a normalmap.

Example:

textures/eX/eX_rplates_01
{ 
  qer_editorimage textures/eX/eX_rplates_01_d.png
  {
    stage diffusemap
    map textures/eX/eX_rplates_01_d.png
    depthScale 0.03
  }
  bumpmap displacemap(addnormals(textures/eX/eX_rplates_01_local.png, heightmap(textures/eX/eX_rplates_01_h.png, 1)), textures/eX/eX_rplates_01_disp.png)
  specularmap textures/eX/eX_rplates_01_s.png
}

scale(<map>, <float> [,float] [,float] [,float])

Scales the RGBA by the specified factors. Defaults to 0.

invertAlpha(<map>)

Inverts the alpha channel (0 becomes 1, 1 becomes 0).

invertColor(<map>)

Inverts the R, G, and B channels.

makeIntensity(<map>)

Copies the red channel to the G, B, and A channels.

makeAlpha(<map>)

Sets the alpha channel to an average of the RGB channels. Sets the RGB channels to white.

clamp

Dictates that this stage should clamp texture coordinates instead of wrapping them. During a stretch function, the area, which the texture must cover during a wave cycle, enlarges and decreases. Instead of repeating a texture multiple times during enlargement (or seeing only a portion of the texture during shrinking) the texture dimensions increase or contract accordingly. This is only relevant when using something like deformTexCoordParms to stretch/compress texture coordinates for a specific special effect. Remember that the KingpinQ3 engine normalizes all texture coordinates (regardless of actual texture size) into a scale of 0.0 to 1.0.

Proper Alignment: When using clampTexCoords be make sure the texture is properly aligned on the brush. The clampTexCoords function keeps the image from tiling. However, the editor doesn't represent this properly and shows a tiled image. Therefore, what appears to be the correct position may be offset. This is very apparent on anything with a tcMod rotate and clampTexCoords function.

Avoiding Distortion: When seen at a given distance (which can vary, depending on hardware and the size of the texture), the compression phase of a stretch function will cause a "cross"-like visual artifact to form on the modified texture due to the way that textures are reduced. This occurs because the texture undergoing modification lacks sufficient "empty space" around the displayed (non-black) part of the texture (see figure 2a). To compensate for this, make the non-zero portion of the texture substantially smaller (50% of maximum stretched size -- see figure 2b) than the dimensions of the texture. Then, write a scaling function (tcScale) into the appropriate shader phase, to enlarge the image to the desired proportion.

edgeClamp

This is similar to clamp but it uses GL_CLAMP_TO_EDGE instead of GL_CLAMP.

zeroClamp

This is similar to clamp but it uses GL_CLAMP_TO_BORDER with the border color RGBA=(0,0,0,1).

alphaZeroClamp

This is similar to clamp but it uses GL_CLAMP_TO_BORDER with the border color RGBA=(0,0,0,0).

linear

This overrides the global material texture filtering to GL_LINEAR for this stage.

This is more or less a stage specific nomipmap.

nearest

This overrides the global material texture filtering to GL_NEAREST for this stage.

Blend Functions

Blend functions are the keyword commands that tell the KingpinQ3 graphic engine's renderer how graphic layers are to be mixed together.

Simplified blend functions:

The most common blend functions are set up here as simple commands, and should be used unless you really know what you are doing.

blend add

This is a shorthand command for:

blend GL_ONE, GL_ONE

Effects like fire and energy are additive.

blend filter

This is a shorthand command that can be substituted for either:

blend GL_DST_COLOR , GL_ZERO

or

blend GL_ZERO , GL_SRC_COLOR

A filter will always result in darker pixels than what is behind it, but it can also remove color selectively. Lightmaps are filters.

blend blend

This is a shorthand command for:

blend GL_SRC_ALPHA , GL_ONE_MINUS_SRC_ALPHA

This is conventional transparency, where part of the background is mixed with part of the texture.

Explicit blend functions:

Getting a handle on this concept is absolutely key to understanding all shader manipulation of graphics. Blend or "Blend Function" is the equation at the core of processing shader graphics. The formula reads as follows:

[Source * <srcBlend>] + [Destination * <dstBlend>]

Source is usually the RGB color data in a texture TGA file (remember it's all numbers) modified by any rgbgen and alphagen. In the shader, the source is generally identified by command MAP, followed by the name of the image.

Destination is the color data currently existing in the frame buffer.

Rather than think of the entire texture as a whole, it may be easier to think of the number values that correspond to a single pixel, because that is essentially what the computer is processing ... one pixel of the bit map at a time.

The process for calculating the final look of a texture in place in the game world begins with the precalculated lightmap for the area where the texture will be located. This data is in the frame buffer. That is to say, it is the initial data in the Destination. In an unmanipulated texture (i.e.; one without a special shader script), color information from the texture is combined with the lightmap. In a shader-modified texture, the $lightmap stage must be present for the lightmap to be included in the calculation of the final texture appearance.

Each pass or "stage" of blending is combined (in a cumulative manner) with the color data passed onto it by the previous stage. How that data combines together depends on the values chosen for the Source Blends and Destination Blends at each stage. Remember it's numbers that are being mathematically combined together that are ultimately interpreted as colors.

A general rule is that any Source Blend other than GL_ONE (or GL_SRC_ALPHA where the alpha channel is entirely white) will cause the Source to become darker.

Source Blend <srcBlend>

The following values are valid for the Source Blend part of the equation.

GL_ONE

  • This is the value 1. When multiplied by the Source, the value stays the same the value of the color information does not change.

GL_ZERO

  • This is the value 0. When multiplied by the Source, all RGB data in the Source becomes Zero (essentially black).

GL_DST_COLOR

  • This is the value of color data currently in the Destination (frame buffer). The value of that information depends on the information supplied by previous stages.

GL_ONE_MINUS_DST_COLOR

  • This is nearly the same as GL_DST_COLOR except that the value for each component color is inverted by subtracting it from one. (,i.e.; R = 1.0 - DST.R, G = 1.0 - DST.G, B = 1.0 - DST.B, etc.)

GL_SRC_ALPHA

  • The TGA file being used for the Source data must have an alpha channel in addition to its RGB channels (for a total of four channels). The alpha channel is an 8-bit black and white only channel. An entirely white alpha channel will not darken the Source.

GL_ONE_MINUS_SRC_ALPHA

  • This is the same as GL_SRC_ALPHA except that the value in the alpha channel is inverted by subtracting it from one. (i.e.; A=1.0 - SRC.A)
Destination Blend <dstBlend>

The following values are valid for the Destination Blend part of the equation.

GL_ONE

  • This is the value 1. When multiplied by the Destination, the value stays the same the value of the color information does not change.

GL_ZERO

  • This is the value 0. When multiplied by the Destination, all RGB data in the Destination becomes Zero (essentially black).

GL_SRC_COLOR

  • This is the value of color data currently in the Source (which is the texture being manipulated here).

GL_ONE_MINUS_SRC_COLOR

  • This is the value of color data currently in Source, but subtracted from one (i.e.; inverted).

GL_SRC_ALPHA

  • The PNG file being used for the Source data must have an alpha channel in addition to its RGB channels (four a total of four channels). The alpha channel is an 8-bit black and white only channel. An entirely white alpha channel will not darken the Source.

GL_ONE_MINUS_SRC_ALPHA

  • This is the same as GL_SRC_ALPHA except that the value in the alpha channel is inverted by subtracting it from one. (i.e.; A=1.0 - SRC.A).

Doing the Math: The Final Result

The product of the Source side of the equation is added to the product of the Destination side of the equation. The sum is then placed into the frame buffer to become the Destination information for the next stage. Ultimately, the equation creates a modified color value that is used by other functions to define what happens in the texture when it is displayed in the game world.

Default Blend Function

If no blend function is specified then no blending will take place. A warning is generated if any stage after the first stage does not have a blend specified.

Technical Information/Limitations Regarding Blend Modes:

Cards running in 16 bit color cannot use any GL_DST_ALPHA blends.

Color Functions

There are two color sources for any given shader, the texture file and the vertex colors. Output at any given time will be equal to TEXTURE multiplied by VERTEXCOLOR. Most of the time VERTEXCOLOR will default to white (which is a normalized value of 1.0), so output will be TEXTURE (this usually lands in the Source side of the shader equation). Sometimes you do the opposite and use TEXTURE = WHITE, but this is only commonly used when doing specular lighting on entities (i.e.; shaders that level designers will probably never create

The most common reason to use rgbGen is to pulsate something. This means that the VERTEXCOLOR will oscillate between two values, and that value will be multiplied (darkening) the texture.

If no rgbGen is specified, either "identityLighting" or "identity" will be selected, depending on which blend modes are used.

rgbGen identityLighting

Colors will be (1.0,1.0,1.0) if running without overbright bits (NT, linux, windowed modes), or (0.5, 0.5, 0.5) if running with overbright. Overbright allows a greater color range at the expense of a loss of precision. Additive and blended stages will get this by default.

rgbGen identity

Colors are assumed to be all white (1.0,1.0,1.0). All filters stages (lightmaps, etc) will get this by default.

rgbGen wave <func> <base> <amp> <phase> <freq>

Colors are generated using the specified waveform. An affected texture with become darker and lighter, but will not change hue. Hue stays constant. Note that the rgb values for color will not go below 0 (black) or above 1 (white). Valid waveforms are sin, triangle, square, sawtooth and inversesawtooth.

<func> Wave forms and their effects:

  • Sin: color flows smoothly through changes.
  • Triangle: color changes at a constant rate and spends no appreciable time at peaks and valleys.
  • Square: color alternates instantly between its peak and valley values.
  • Sawtooth: With a positive frequency value, the color changes at a constant rate to the peak then instantly drops to its valley value.
  • Inversesawtooth: An inverse sawtooth wave will reverse this, making the ascent immediate (like a square wave) and the decay fall off like a triangle wave.

<base> Baseline value. The initial RGB formula of a color (normalilzed.

<amp> Amplitude. This is the degree of change from the baseline value. In some cases you will want values outside the 0.0 to 1.0 range, but it will induce clamping (holding at the maximum or minimum value for a time period) instead of continuous change.

<phase> See the explanation for phase under the waveforms heading of Key Concepts.

<freq> Frequency. This is a value (NOT normalized) that indicates peaks per second.

rgbGen entity

Colors are grabbed from the entity's modulate field. This is used for things like explosions.

Design Note: This keyword would probably not be used by a level designer.

rgbGen oneMinusEntity

Colors are grabbed from 1.0 minus the entity's modulate field.

Design Note: This keyword would probably not be used by a level designer.

red <exp>

Set the red vertex color

green <exp>

Set the green vertex color

blue <exp>

Set the blue vertex color

alpha <exp>

Set the alpha vertex color

rgb <exp>

This is a shortcut command for:

red <exp>
green <exp>
blue <exp>

rgba <exp>

This is a shortcut command for:

red <exp>
green <exp>
blue <exp>
alpha <exp>

color <redExp>, <greenExp>, <blueExp>, <alphaExp>

This is a shortcut command for:

red <redExp>
green <greenExp>
blue <blueExp>
alpha <alphaExp>

colored

This is a shortcut command for:

color parm0, parm1, parm2, parm3

and equivalent to the old Syntax:

rgbGen entity
alphaGen entity

Colors are grabbed from the entity's modulate field.

  • parm0: red
  • parm1: green
  • parm2: blue
  • parm3: alpha

vertexColor

Colors are filled in directly by the data from the map or model files.

Design Note: vertexColor should be used when you want the RGB values to be computed

for a static model (i.e. mapobject) in the world using vertex painting.

This would be used on things like the rocks, the portal frame,

skulls, and other decorative custom models (.ase,.md3,.lwo) put into the KingpinQ3 world.

inverseVertexColor

As vertexColor, but inverted. Useful for terrain blending.

Texture Matrix Functions

Specifies how texture coordinates are modified after they are generated. The valid functions for tcMod are rotate, scale, scroll, stretch and transform. Transform is a function generally reserved for use by programmers who suggest that designers leave it alone. When using multiple tcMod functions during a stage, place the scroll command last in order, because it performs a mod operation to save precision, and that can disturb other operations. Texture coordinates are modified in the order in which tcMods are specified. In other words, if you see:

scale 0.5, 0.5
scroll time * 1, time * 1

Then the texture coordinates will be scaled then scrolled.

rotate <exp>

This keyword causes the texture coordinates to rotate. A positive value means clockwise rotation. A negative value means counterclockwise rotation. For example "rotate time * 5" would rotate texture coordinates 5 degrees each second in a clockwise direction. The texture rotates around the center point of the texture map, so you are rotating a texture with a single repetition, be careful to center it on the brush (unless off-center rotation is desired).

scale <sScale>, <tScale>

Resizes (enlarges or shrinks) the texture coordinates by multiplying them against the given factors of <sScale> and <tScale). The values "s" and "t" conform to the "x" and "y" values (respectively) as they are found in the original texture TGA. The values for sScale and tScale are NOT normalized. This means that a value greater than 1.0 will increase the size of the texture. A positive value less than one will reduce the texture to a fraction of its size and cause it to repeat within the same area as the original texture.

Example:

scale time * 0.5, time * 2

would cause the texture to repeat twice along its width, but expand to twice its height (in which case half of the texture would be seen in the same area as the original)

scroll <sSpeedExp>, <tSpeedExp>

Scrolls the texture coordinates with the given speeds. ). The values "s" and "t" conform to the "x" and "y" values (respectively) as they are found in the original texture TGA, The scroll speed is measured in "textures" per second. A "texture" is the dimension of the texture being modified and includes any previous shader modifications to the original TGA). A negative s value would scroll the texture to the left. A negative t value would scroll the texture down.

Example:

scroll time * 0.5, time * -0.5

moves the texture down and right (relative to the TGA files original coordinates) at the rate of a half texture each second of travel.

translate <sSpeedExp>, <tSpeedExp>

Same as scroll.

centerScale <sExp>, <tExp>

Subtracts 0.5, then scales, then adds 0.5.

shear <sExp>, <tExp>

Subtracts 0.5, then shears, then adds 0.5.

depthFunc <func>

This controls the depth comparison function used while rendering. The default is "lequal" (Less than or equal to) where any surface that is at the same depth or closer of an existing surface is drawn. This is used for textures with transparency or translucency. Under some circumstances you may wish to use "equal", e.g. for lightmapped grates that are alpha tested (it is also used for mirrors).

depthWrite

By default, writes to the depth buffer when depthFunc passes will happen for opaque surfaces and not for translucent surfaces. Blended surfaces can have the depth writes forced with this function.

maskDepth

This is merely the opposite of depthWrite. Don't write to the depth buffer.

maskRed

Don't write to the red channel of the color buffer.

maskGreen

Don't write to the green channel of the color buffer.

maskBlue

Don't write to the blue channel of the color buffer.

maskAlpha

Don't write to the alpha channel of the color buffer.

maskColor

This is a shortcut keyword for:

maskRed
maskGreen
maskBlue

alphaFunc <func>

Determines the alpha test function used when rendering this map. Valid values are GT0, LT128, and GE128. These correspond to "GREATER THAN 0", "LESS THAN 128", and "GREATER THAN OR EQUAL TO 128". This function is used when determining if a pixel should be written to the framebuffer. For example, if GT0 is specified, the only the portions of the texture map with corresponding alpha values greater than zero will be written to the framebuffer. By default alpha testing is disabled.

Both alpha testing and normal alpha blending can be used to get textures that have see-through parts. The difference is that alphaFunc is an all-or-nothing test, while blending smoothly blends between opaque and translucent at pixel edges. Alpha test can also be used with depthwrite, allowing other effects to be conditionally layered on top of just the opaque pixels by setting depthFunc to equal.

alphaTest <float>

This is the same as alphaFunc except it allows to specify a number in the range from 0.0 to 1.0.

refractionIndex <exp>

This parameter is used by liquid stages. You can specify the refractive index according to Snell's Law.

Different types of translucent materials have different indices of refraction.

Some samples values:

refractionIndex 1.0 // Vacuum
//Air          1.0003
//Water        1.3333
//Glass        1.5
//Plastic      1.5
//Diamond      2.417

fresnelPower <exp>

See [#liquidmap stage liquidMap]. The default value of fresnelPower is 2.0.

fresnelScale <exp>

See [#liquidmap stage liquidMap]. The default value of fresnelScale is 2.0.

fresnelBias <exp>

See [#liquidmap stage liquidMap]. The default value of fresnelBias is 1.0.

deformMagnitude <exp>

This is used by distortion effect stages like heatHaze.

A range from 0.1 - 2.0 is recommend.

stage <type>

The stage type determines the semantic meaning of a stage. In Quake3 all stages were simple color stages that could be used for color blending.

In KingpinQ3 we have special stages with a different meaning.

stage colorMap

This is the default and behaves like in Quake3. It supports simple color blending.

stage diffuseMap

Diffuse maps in KingpinQ3 represent the diffuse reflection and color of a surface. In other words they define the color and intensity of light reflected back when it strikes a surface.

The goal when creating a diffuse map is to draw a color map and darken areas where light would be absorbed. For instance, the cracks in a brick wall absorb more light than they reflect back.

No surface reflects light back at the same intensity it's recieved. In that respect, it's a good idea to darken your diffuse maps appropriately. Generally, the smoother a surface is the less light is diffused and the brighter your diffuse map can be.

As convention it's recommended that you add "_d" to the end of the texture's filename.

stage normalMap or stage bumpMap

Bump mapping adds an illusion of depth and texture to images. It doesn't actually alter geometry but rather affects the shading over a surface. There are two different kinds of bump maps useable in the KingpinQ3 engine: Normal and height maps.

Normal maps

Normal maps define the slope or normals of a surface. In other words, they alter the direction a surface appears to be facing.

The normal for each pixel is defined by storing spacial X,Y,Z transformation data in the R,G,B channels. The example to the right demonstrates this.

There are two methods to create normal maps.

  • Render a normal map from 3D geometry
  • Convert a height map into a normal map

As convention it's recommended that you add "_local" to the end of the texture's filename.

Height maps

Heightmap fl_rc_v4_h

Height maps are greyscale images that define the height of the indivdual pixels of a surface. They adjust the visual depth of a texture.

The height of each pixel is defined by the brightness of the image. A white pixel is as high, a black pixel is as low as it gets. grey levels in between represent different heights.

Heightmaps are usually painted in an image manipulation program. There is usually no need to render those. Note that height maps are converted to normalmaps by the KingpinQ3 engine when loaded. The use of height maps is only to allow for an easier workflow.

Height bump maps are added to a material by use of the Heightmap function. As convention it's recommended that you add "_h" to the end of the texture's filename.

Normal maps vs. Height maps

The KingpinQ3 engine is able to combine both a normal map and a height map into one combined bump map.

Usually this is done when it's more practical to paint fine details into a height map than it is to model the same details and render them into the corresponding normal map.

Normal and height bump maps can be combined in a material by using Addnormals function.

Note: Height maps by default do not visually displace a surface in the KingpinQ3 engine. They only serve as a means to compute surface normals for use with dynamic lighting.

What this means is that essentially, a height map is converted into a normal map. And because the only way to compute slope when dealing with height is to compare each pixel value to that of it's neighbors, a height map can never be as detailed as a normal map of the same resolution.

More evidence to back up this claim is that height maps do not make efficient use of multiple color channels as a height map saved in RGB color space is still black and white. Because the data in each color channel is redundant, you are limited to only 256 levels of intensity.

Compare this to normal maps where each channel can be unique and it's clear that normal maps are more efficient at defining slope.

stage specularMap

Specular maps in KingpinQ3 represent the specular intensity and color of highlights on a surface. In other words they define the "shinyness" and color of specular reflections.

The brighter a specular map is, the more shine is applied to the final material.

The goal when creating a specular map is to fill the image with a solid value to represent the general specularity of the surface and then darken areas where weathering would occur.

Again, the example to the right demonstrates this as the face of a brick would recieve more wear and tear than the edges and therefore be duller. Note that the cracks themselves have little to no specularity at all.

Color applied to a specular map tints the color of highlights. Bricks are made out of a sand like material and as such would reflect slightly variable tints. This too is present in the example to the right.

As convention it's recommended that you add "_s" to the end of the texture's filename.

stage reflectionMap

Requires a cubemap for reflection mapping.

stage refractionMap

Requires a cubemap for refraction mapping.

stage dispersionMap

Requires a cubemap for chromatic dispersion mapping.

stage skyBoxMap

Requires a cubemap for simple skybox rendering on arbitrary polygons.

stage heatHazeMap

This is a post process effect where you can distort the _currentRender color framebuffer with a normalmap.

The parameter deformMagnitude is a factor how much the normal/distorsionmap influences the current screen.

railDisc
{
  twoSided
  //deformVertexes wave 100 sin 0 .5 0 2.4
  translucent
  sort postProcess
  {
    stage heathazemap
    map     gfx/misc/raildisc_mono2_n.tga
    clamp
    deformMagnitude 1
    centerScale 0.6 + time * 2.3 * (1 - parm0) , 0.6 + time * 2.3 * (1 - parm0)
    blend GL_ONE, GL_ZERO
    alphaTest 0.5
  }
}

stage liquidMap

This is a post process effect that uses the Fresnel term to calculate the reflection.

In general, when light reaches an interface between two materials, some light reflects off the surface at the interface, and some refracts through the surface. This phenomenon is known as the Fresnel effect (pronounced "freh-'nell").

The fresnel equation describe how much light is reflected and how much is refracted. If you have ever wondered why you can see fish in a pond only when you're looking practically straight down, it's because of the Fresnel effect. At shallow angles, there is a lot of reflection and almost no refraction, so it is hard to see through the water's surface.

KingpinQ3 uses an approximation of the Fresnel equation and fresnelPower, fresnelScale and fresnelBias variables provide a way to shape the function that we use to approximate the Fresnel equation.

From the GPU shader:

  // compute incident ray
  vec3 I = normalize(u_ViewOrigin - var_Vertex);
  // compute normal
  vec3 N = normalize(var_Normal);
  // compute fresnel term
  float fresnel = clamp(u_FresnelBias + pow(1.0 - dot(I, N), u_FresnelPower) * u_FresnelScale, 0.0, 1.0);
  // compute final pixel color, lerp between refraction and reflection
  color = (1.0 - fresnel) * refractColor + reflectColor * fresnel;

Sample material:

textures/Kpq3_liquids/water1
{
  qer_editorimage textures/Kpq3_liquids/water1.png
  translucent
  noshadows
  water
  mirror
  sort postProcess
  tessSize 16
  {
    stage liquidMap
    map textures/tr3b_water/water1_local.png
    scroll    time * 0.1 , time * 0.1
    scale    0.5, 0.5
    refractionIndex 1.3 // water
    fresnelPower 2.0
    fresnelScale 0.85    // + sinTable[time * 0.4] * 0.25
    fresnelBias  0.05
    blend blend
    // give it a blue tint
    red        0.7
    green    0.7
    blue    1.0
    alpha    1.0
  }
}

stage attenuationMapXY

Attenuate light with this texture in X and Y directions.

stage attenuationMapZ

Attenuate light with this texture in Z direction.

This is the same as the first light material stage in Doom3.

Example Shader for default lighting:

lights/defaultDynamicLight
{
  {
    stage attenuationMapZ
    map makeintensity(lights/squarelight1a.tga)
    edgeClamp
  }
  {
    stage attenuationMapXY
    forceHighQuality
    map lights/round.png
    colored
    zeroClamp
  }
}

Troubleshooting Shaders

If a shader is not working, look first for syntax errors.

Are the brackets correctly set?

Do you have too many parameter values on a line?

Are you using a word in a parameter that wants a numerical value?

Are you using a numer

fl_rc_v4_h.png - Heightmap fl_rc_v4_h (275.6 kB) 0xA5EA, 01/24/2010 01:45 am

b_cp_v13_d2.png (59.7 kB) 0xA5EA, 01/24/2010 01:49 am

b_cp_v13_d2_local.png (77.5 kB) 0xA5EA, 01/24/2010 01:52 am

b_cp_v13_d2_s.png (28.7 kB) 0xA5EA, 01/24/2010 01:53 am