Based on the Quake III Arena Shader Manual by Paul Jaquays and Brian Hook (rewritten by RobertBeckebans)

Sommaire

  1. Preface: Making Your Own Shaders/Materials
  2. Introduction
    1. What is a Shader?
    2. Shader Name & File Conventions
    3. Shader Types
    4. Key Concepts
      1. Surface Effects vs. Content Effects vs. Deformation Effects
      2. Normalization: a Scale of 0 to 1
      3. Math and Logic
      4. Parameter Keys
      5. Tables
  3. General Shader Keywords
    1. skyParms <farbox> <cloudheight> <nearbox>
    2. cull <side>
      1. cull front, backSided
      2. cull back
      3. cull disable, cull none, twoSided
    3. deformVertexes
      1. deformVertexes wave <div> <func> <base> <amplitude> <phase> <freq>
      2. deformVertexes normal <div> <func> <base> <amplitude ~0.1-~0.5> <frequency ~1.0-~4.0>
      3. deformVertexes bulge <bulgeWidth> <bulgeHeight> <bulgeSpeed>
      4. deformVertexes move <x> <y> <z> <func> <base> <amplitude> <phase> <freq>
      5. DeformVertexes autosprite
      6. DeformVertexes autosprite2
    4. nopicmip
    5. nomipmaps
    6. polygonOffset
    7. portal
    8. sort <value>
    9. diffuseMap <map>
    10. bumpMap <map>, normalMap <map>
    11. specularMap <map>
    12. DECAL_MACRO>
  4. XMAP Specific Shader Keywords
    1. tessSize <amount>
    2. xmap_backshader <shadername>
    3. xmap_globaltexture
    4. Surface Parameters
      1. areaportal
      2. clusterportal
      3. donotenter
      4. flesh
      5. lava
      6. metalsteps
      7. nodamage
      8. nodlight
      9. nodraw
      10. nodrop
      11. noimpact
      12. nomarks
      13. nosteps
      14. nonsolid
      15. origin
      16. playerclip
      17. slick
      18. slime
      19. structural
      20. trans, translucent
      21. water
  5. Editor Specific Shader Keywords
    1. qer_editorimage < texture path/texturename>
    2. qer_nocarve
    3. qer_trans <value>
  6. Stage Specific Keywords
    1. Texture map specification
      1. map <map>
      2. cubeMap <map>
      3. videoMap <map>
      4. Image Program Functions
        1. heightmap(<map>, <float>)
        2. addnormals(<map>, <map>)
        3. displaceMap(<map>, <map>)
        4. scale(<map>, <float> [,float] [,float] [,float])
        5. invertAlpha(<map>)
        6. invertColor(<map>)
        7. makeIntensity(<map>)
        8. makeAlpha(<map>)
      5. clamp
      6. edgeClamp
      7. zeroClamp
      8. alphaZeroClamp
      9. linear
      10. nearest
    2. Blend Functions
      1. Simplified blend functions:
        1. blend add
        2. blend filter
        3. blend blend
      2. Explicit blend functions:
        1. Source Blend <srcBlend>
          1. Destination Blend <dstBlend>
      3. Default Blend Function
      4. Technical Information/Limitations Regarding Blend Modes:
    3. Color Functions
      1. rgbGen identityLighting
      2. rgbGen identity
      3. rgbGen wave <func> <base> <amp> <phase> <freq>
      4. rgbGen entity
      5. rgbGen oneMinusEntity
      6. red <exp>
      7. green <exp>
      8. blue <exp>
      9. alpha <exp>
      10. rgb <exp>
      11. rgba <exp>
      12. color <redExp>, <greenExp>, <blueExp>, <alphaExp>
      13. colored
      14. vertexColor
      15. inverseVertexColor
    4. Texture Matrix Functions
      1. rotate <exp>
      2. scale <sScale>, <tScale>
      3. scroll <sSpeedExp>, <tSpeedExp>
      4. translate <sSpeedExp>, <tSpeedExp>
      5. centerScale <sExp>, <tExp>
      6. shear <sExp>, <tExp>
    5. depthFunc <func>
    6. depthWrite
    7. maskDepth
    8. maskRed
    9. maskGreen
    10. maskBlue
    11. maskAlpha
    12. maskColor
    13. alphaFunc <func>
    14. alphaTest <float>
    15. refractionIndex <exp>
    16. fresnelPower <exp>
    17. fresnelScale <exp>
    18. fresnelBias <exp>
    19. deformMagnitude <exp>
    20. stage <type>
      1. stage colorMap
      2. stage diffuseMap
      3. stage normalMap or stage bumpMap
        1. Normal maps
        2. Height maps
        3. Normal maps vs. Height maps
      4. stage specularMap
      5. stage reflectionMap
      6. stage refractionMap
      7. stage dispersionMap
      8. stage skyBoxMap
      9. stage heatHazeMap
      10. stage liquidMap
      11. stage attenuationMapXY
      12. stage attenuationMapZ
  7. Troubleshooting Shaders

1. 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 XreaL 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.

2. Introduction

The graphic engine for XreaL 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.

2.1. 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; base, hell, castle, etc,). Several specific script documents have also been created to handle special cases, like liquids, sky and special effects.

For XreaL, Shader scripts are located in XreaL/base/materials.

A XreaL 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 XMAP keywords or "Surface Parameters", which follow the first bracket and a single bracketed "stage":

textures/liquids/lava
{

      deformVertexes wave sin 0 3 0 0.1
      tessSize 64
      {
         map textures/common/lava.tga
      }

}

2.2. Shader Name & 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 .tga file without the extension or basedir (/XreaL/base 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 .tga 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 .tga 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.

2.3. 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 "xmap_" keywords) are processed by XMAP, 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).

2.4. 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.

2.4.1. 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.

2.4.2. Normalization: a Scale of 0 to 1

The mathematics in XreaL 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.

2.4.3. Math and Logic

Materials in XreaL 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 XreaL, 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 <, >, <=, >=, ==, !=, &&, 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:

2.4.4. Parameter Keys

These are keywords used in this document to differenciate between different input types. Every parameter is a key of a certain type:

2.4.5. 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 XreaL, 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

Anchor(general_keywords)

3. 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 XMap.

3.1. 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.tga", "env/test_lf.tga", "env/test_ft.tga", "env/test_bk.tga", "env/test_up.tga", "env/test_dn.tga" 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:

Example: Sky script

textures/skies/xtoxicsky_dm9
{

      qer_editorimage textures/skies/toxicsky.tga
      surfaceparm noimpact
      surfaceparm nolightmap
      xmap_globaltexture
      xmap_lightsubdivide 256
      xmap_surfacelight 400
      surfaceparm sky
      xmap_sun1 1 0.5 15030 60
      skyparms full 512 -
      {
            map textures/skies/inteldimclouds.tga
            scroll time * 0.1, time * 0.1
            scale 3, 2
      }
      {
            map textures/skies/intelredclouds.tga
            blend add
            scroll time *0.05, time * 0.05
            scale 3, 3
      }

}

3.2. 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.

3.2.1. 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

3.2.2. cull back

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

3.2.3. 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.

3.3. 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.

3.3.1. deformVertexes wave <div> <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) .

3.3.2. deformVertexes normal <div> <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.

3.3.3. 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: <div> 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.

3.3.4. 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.

3.3.5. 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.

3.3.6. 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.

3.4. 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.

3.5. 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.

3.6. 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.

3.7. 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.

3.8. 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):

3.9. diffuseMap <map>

This keyword is a shortcut for:

{
  stage diffuseMap
  map <map>
}

3.10. bumpMap <map>, normalMap <map>

This keyword is a shortcut for:

{
  stage bumpMap
  map <map>
}

3.11. specularMap <map>

This keyword is a shortcut for:

{
  stage specularMap
  map <map>
}

3.12. DECAL_MACRO>

This keyword is a shortcut for:

polygonOffset 1
discrete
sort decal
noShadows

4. XMAP 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.

4.1. tessSize <amount>

For consistency's sake, this really should have been called xmap_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 xmap 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.

4.2. xmap_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.

4.3. xmap_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.

4.4. Surface Parameters

These keywords generate surface properties that can influence the game.

4.4.1. areaportal

A brush marked with this keyword functions as an area portal, a break in the XMAP 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.

4.4.2. 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.

4.4.3. 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.

4.4.4. flesh

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

4.4.5. lava

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

4.4.6. 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.

4.4.7. nodamage

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

4.4.8. 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.

4.4.9. 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.

4.4.10. 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.

4.4.11. 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.

4.4.12. 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.

4.4.13. nosteps

The player makes no sound when walking on this texture.

4.4.14. 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.

4.4.15. 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.

4.4.16. 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.

4.4.17. slick

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

4.4.18. slime

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

4.4.19. structural

This surface attribute causes a brush to be seen by the XMAP 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.

4.4.20. trans, translucent

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

4.4.21. water

Assigns to the texture the game properties for water.

5. 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.

5.1. qer_editorimage < texture path/texturename>

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

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/eerie/lavahell.tga
      
      // 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
      xmap_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/eerie/lavahell.tga

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

            //the turbulence is scrolled
            tcMod scroll 0.1 0.1
      }

}

5.2. 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.

5.3. 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.

6. 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. XMAP 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.

6.1. Texture map specification

6.1.1. 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.

6.1.2. 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.

6.1.3. videoMap <map>

This stage uses a video stream as an image map. /!\ NOTE: this is only supported by colormap stage types.

6.1.4. 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.

6.1.4.1. heightmap(<map>, <float>)

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

Example:

textures/eX/eXmetal_plate01 
{
        qer_editorimage textures/eX/eXmetal_plate01_d

        bumpmap         heightmap ( textures/eX/eXmetal_plate01_h, 1 )
        diffusemap      textures/eX/eXmetal_plate01_d
        specularmap     textures/eX/eXmetal_plate01_s
}

6.1.4.2. addnormals(<map>, <map>)

Adds two normal maps together. Result is normalized.

Example:

textures/eX/eXmetalBase06rust
{

        qer_EditorImage         textures/eX/eXmetalBase06rust_d.tga
        
        bumpMap addnormals (textures/eX/eXmetalBase01_local.tga, heightmap ( textures/eX/eXmetalBase01_h.tga,1 ) )
        diffuseMap                      textures/eX/eXmetalBase06rust_d.tga
        specularMap                     textures/eX/eX_cretefloor_01_s.tga
}

6.1.4.3. 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

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

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

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

6.1.4.5. invertAlpha(<map>)

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

6.1.4.6. invertColor(<map>)

Inverts the R, G, and B channels.

6.1.4.7. makeIntensity(<map>)

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

6.1.4.8. makeAlpha(<map>)

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

6.1.5. 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 XreaL 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.

6.1.6. edgeClamp

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

6.1.7. zeroClamp

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

6.1.8. alphaZeroClamp

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

6.1.9. linear

This overrides the global material texture filtering to GL_LINEAR for this stage. This is more or less a stage specific nomipmap.

6.1.10. nearest

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

6.2. Blend Functions

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

6.2.1. 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.

6.2.1.1. blend add

This is a shorthand command for:

blend GL_ONE, GL_ONE

Effects like fire and energy are additive.

6.2.1.2. 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.

6.2.1.3. 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.

6.2.2. 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.

6.2.2.1. Source Blend <srcBlend>

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

GL_ONE

GL_ZERO

GL_DST_COLOR

GL_ONE_MINUS_DST_COLOR

GL_SRC_ALPHA

GL_ONE_MINUS_SRC_ALPHA

6.2.2.1.1. Destination Blend <dstBlend>

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

GL_ONE

GL_ZERO

GL_SRC_COLOR

GL_ONE_MINUS_SRC_COLOR

GL_SRC_ALPHA

GL_ONE_MINUS_SRC_ALPHA

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.

6.2.3. 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.

6.2.4. Technical Information/Limitations Regarding Blend Modes:

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

6.3. 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.

6.3.1. 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.

6.3.2. 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.

6.3.3. 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:

<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.

6.3.4. 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.

6.3.5. 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.

6.3.6. red <exp>

Set the red vertex color

6.3.7. green <exp>

Set the green vertex color

6.3.8. blue <exp>

Set the blue vertex color

6.3.9. alpha <exp>

Set the alpha vertex color

6.3.10. rgb <exp>

This is a shortcut command for:

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

6.3.11. rgba <exp>

This is a shortcut command for:

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

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

This is a shortcut command for:

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

6.3.13. 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.

6.3.14. 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 XreaL world.

6.3.15. inverseVertexColor

As vertexColor, but inverted. Useful for terrain blending.

6.4. 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.

6.4.1. 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).

6.4.2. 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)

6.4.3. 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.

6.4.4. translate <sSpeedExp>, <tSpeedExp>

Same as scroll.

6.4.5. centerScale <sExp>, <tExp>

Subtracts 0.5, then scales, then adds 0.5.

6.4.6. shear <sExp>, <tExp>

Subtracts 0.5, then shears, then adds 0.5.

6.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).

6.6. 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.

6.7. maskDepth

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

6.8. maskRed

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

6.9. maskGreen

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

6.10. maskBlue

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

6.11. maskAlpha

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

6.12. maskColor

This is a shortcut keyword for:

maskRed
maskGreen
maskBlue

6.13. 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.

6.14. alphaTest <float>

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

6.15. 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

6.16. fresnelPower <exp>

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

6.17. fresnelScale <exp>

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

6.18. fresnelBias <exp>

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

6.19. deformMagnitude <exp>

This is used by distortion effect stages like heatHaze. A range from 0.1 - 2.0 is recommend.

6.20. 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 XreaL we have special stages with a different meaning.

6.20.1. stage colorMap

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

6.20.2. stage diffuseMap

eX_trim_baseboard_d.png

Diffuse maps in XreaL 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.

6.20.3. 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 XreaL engine: Normal and height maps.

6.20.3.1. Normal maps

eX_trim_baseboard_local.png

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.

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

6.20.3.2. Height maps

eX_trim_baseboard_h.png

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 XreaL 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.

6.20.3.3. Normal maps vs. Height maps

The XreaL 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 XreaL 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.

6.20.4. stage specularMap

eX_trim_baseboard_s.png

Specular maps in XreaL 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.

6.20.5. stage reflectionMap

Requires a cubemap for reflection mapping.

/!\ TODO explain

6.20.6. stage refractionMap

Requires a cubemap for refraction mapping.

/!\ TODO explain

6.20.7. stage dispersionMap

Requires a cubemap for chromatic dispersion mapping.

6.20.8. stage skyBoxMap

Requires a cubemap for simple skybox rendering on arbitrary polygons.

/!\ TODO explain

6.20.9. 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
      }
}

Anchor(liquidmap)

6.20.10. 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.

XreaL 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/tr3b_water/mirror
{
        qer_editorimage textures/common/qer_mirror.tga
        
        translucent
        noshadows
        water
        mirror
        sort postProcess
        tessSize 16
        
        {
                stage liquidMap
                map             textures/tr3b_water/watertest_local.tga
                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
                
                /*
                // optional to tweak the water color but not necessary
                blend blend
                
                // give it a blue tint
                red             0.7
                green   0.7
                blue    1.0
                alpha   1.0
                */
        }
}

6.20.11. stage attenuationMapXY

Attenuate light with this texture in X and Y directions.

6.20.12. 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.tga
                colored
                zeroClamp
        }
}

7. 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 numerical value in a parameter that wants a word?

Are the path names to your textures correct?

Are your texture names correct? There is a chance that the texture name is too long or too complex. Try renaming a texture with a shorter, simpler name.

AttachInfo AttachList

ShaderManual (dernière édition le 2008-07-29 20:54:56 par RobertBeckebans)

SourceForge.net Logo