ShaderLab syntax: Texturing
Reference Manual > ShaderLab Reference > ShaderLab syntax: Shader > ShaderLab syntax: SubShader > ShaderLab syntax: Pass > ShaderLab syntax: Texturing

ShaderLab syntax: Texturing

After the basic vertex lighting has been calculated, textures are applied. In ShaderLab this is done using SetTexture command.

SetTexture commands have no effect when fragment programs are used; as in that case pixel operations are completely described in the shader.

Texturing is the place to do old-style combiner effects. You can have multiple SetTexture commands inside a pass - all textures are applied in sequence, like layers in a painting program. SetTexture commands must be placed at the end of a Pass.

Syntax

SetTexture [TexturePropertyName] { Texture Block }
Assigns a texture. TextureName must be defined as a texture property. How to apply the texture is defined inside the TextureBlock.

Texture Block

The texture block controls how the texture is applied.

combine src1 * src2
Multiplies src1 and src2 together. The result will be darker than either input.
combine src1 + src2
Adds src1 and src2 together. The result will be lighter than either input.
combine src1 - src2
Subtracts src2 from src1.
combine src1 +- src2
Adds src1 to src2, then subtracts 0.5 (a signed add).
combine src1 lerp (src2) src3
Interpolates between src1 and src3, using the alpha of src2.
combine src1 * src2 + src3
Multiplies src1 with the alpha component of src2, then adds src3.
combine src1 * src2 +- src3
Multiplies src1 with the alpha component of src2, then does a signed add with src3.
combine src1 * src2 - src3
Multiplies src1 with the alpha component of src2, then subtracts src3.

All the src properties can be either one of previous, constant, primary or texture.

Modifiers

The formulas specified above can optionally be followed by the keywords Double or Quad to make the resulting color 2x or 4x as bright. All the src properties, except lerp argument, can optionally be preceded by one - to make the resulting color negated.

ConstantColor color
Defines a constant color that can be used in the values above.

Details

Older graphics cards use a layered approach to textures. The textures are applied one after each other, modifying the color that will be written to the screen. For each texture, the texture is typically combined with the result of the previous operation.

Separate Alpha & Color blending

By default, the combiner formula is used for calculating both the RGB and alpha component of the color settexture. Optionally, you can specify a separate formula for the alpha calculation. This looks like this:

SetTexture [_MainTex] { combine previous * texture, previous + texture }

Here, we multiply the RGB colors and add the alpha.

Specular highlights

By default the primary color is the sum of the diffuse, ambient and specular colors (as defined in the Lighting calculation). If you specify SeparateSpecular On in the pass options, the specular color will be added in after the combiner calculation, rather than before. This is the default behavior of the built-in VertexLit shader.

Graphics hardware support

Some old graphics cards might not support some texture combine modes, and different cards have different number of SetTexture stages available. The shader author should write separate SubShaders for the cards he or she wants to support.

Graphics cards with pixel shader 1.1 support (NVIDIA GeForce 3 and up, ATI Radeon 8500 and up, Intel 9xx) support all combiner modes and have at least 4 texture stages available. The following table summarizes the hardware support:

CardStage countCombiner modes not supported
NVIDIA GeForce 3/4Ti and up4In OpenGL on Windows, src1*src2-src3 is not supported
NVIDIA TNT2, GeForce 256, GeForce 2, GeForce 4MX2In OpenGL on Windows, src1*src2-src3 is not supported
ATI Radeon 9500 and up4-88 in OpenGL, 4 in D3D9
ATI Radeon 8500-92504-66 in OpenGL, 4 in D3D9
ATI Radeon 75003 
ATI Rage2src1*src2+src3
src1*src2+-src3
src1*src2-src3

Examples

Alpha Blending Two Textures

This small examples takes two textures. First it sets the first combiner to just take the _MainTex, then is uses the alpha channel of _BlendTex to fade in the RGB colors of _BlendTex

Shader "Examples/2 Alpha Blended Textures" {
    Properties {
        _MainTex ("Base (RGB)", 2D) = "white" {}
        _BlendTex ("Alpha Blended (RGBA) ", 2D) = "white" {}
    }
    SubShader {
        Pass {
            // Apply base texture
            SetTexture [_MainTex] {
                combine texture
            }
            // Blend in the alpha texture using the lerp operator
            SetTexture [_BlendTex] {
                combine texture lerp (texture) previous
            }
        }
    }
} 

Alpha Controlled Self-illumination

This shader uses the alpha component of the _MainTex to decide where to apply lighting. It does this by applying the texture to two stages; In the first stage, the alpha value of the texture is used to blend between the vertex color and solid white. In the second stage, the RGB values of the texture are multiplied in.

Shader "Examples/Self-Illumination" {
    Properties {
        _MainTex ("Base (RGB) Self-Illumination (A)", 2D) = "white" {}
    }
    SubShader {
        Pass {
            // Set up basic white vertex lighting
            Material {
                Diffuse (1,1,1,1)
                Ambient (1,1,1,1)
            }
            Lighting On

            // Use texture alpha to blend up to white (= full illumination)
            SetTexture [_MainTex] {
                constantColor (1,1,1,1)
                combine constant lerp(texture) previous
            }
            // Multiply in texture
            SetTexture [_MainTex] {
                combine previous * texture
            }
        }
    }
} 

We can do something else for free here, though; instead of blending to solid white, we can add a self-illumination color and blend to that. Note the use of ConstantColor to get a _SolidColor from the properties into the texture blending.

Shader "Examples/Self-Illumination 2" {
    Properties {
        _IlluminCol ("Self-Illumination color (RGB)", Color) = (1,1,1,1)
        _MainTex ("Base (RGB) Self-Illumination (A)", 2D) = "white" {}
    }
    SubShader {
        Pass {
            // Set up basic white vertex lighting
            Material {
                Diffuse (1,1,1,1)
                Ambient (1,1,1,1)
            }
            Lighting On

            // Use texture alpha to blend up to white (= full illumination)
            SetTexture [_MainTex] {
                // Pull the color property into this blender
                constantColor [_IlluminCol]
                // And use the texture's alpha to blend between it and
                // vertex color
                combine constant lerp(texture) previous
            }
            // Multiply in texture
            SetTexture [_MainTex] {
                combine previous * texture
            }
        }
    }
} 

And finally, we take all the lighting properties of the vertexlit shader and pull that in:

Shader "Examples/Self-Illumination 3" {
    Properties {
        _IlluminCol ("Self-Illumination color (RGB)", Color) = (1,1,1,1)
        _Color ("Main Color", Color) = (1,1,1,0)
        _SpecColor ("Spec Color", Color) = (1,1,1,1)
        _Emission ("Emmisive Color", Color) = (0,0,0,0)
        _Shininess ("Shininess", Range (0.01, 1)) = 0.7
        _MainTex ("Base (RGB)", 2D) = "white" {}
    }

    SubShader {
        Pass {
            // Set up basic vertex lighting
            Material {
                Diffuse [_Color]
                Ambient [_Color]
                Shininess [_Shininess]
                Specular [_SpecColor]
                Emission [_Emission]
            }
            Lighting On

            // Use texture alpha to blend up to white (= full illumination)
            SetTexture [_MainTex] {
                constantColor [_IlluminCol]
                combine constant lerp(texture) previous
            }
            // Multiply in texture
            SetTexture [_MainTex] {
                combine previous * texture
            }
        }
    }
}