Appendix D. Shaders and Cg/HLSL Programming

This appendix presents a brief overview of the structure of surface shaders and Cg/HLSL programming.

Shaders in Unity can be written in one of the following three different ways:

  • Surface shaders will probably be your best bet. Write your shader as a surface shader if it needs to interact properly with lighting, shadows, projectors, and so on. Surface shaders also make it easy to write complex shaders in a compact way—it's a higher level of abstraction. Lighting for most surface shaders can be calculated in a deferred manner (except for some custom lighting models), which allows your shader to efficiently interact with many real-time lights. You write surface shaders in a couple of lines of Cg/HLSL and a lot more code gets autogenerated from that.
  • Vertex and fragment shaders will be required, if you need some very exotic effects that the surface shaders can't handle, if your shader doesn't need to interact with lighting, or if it's an image effect. Shader programs written this way are the most flexible way to create the effect you need (even surface shaders are automatically converted to a bunch of vertex and fragment shaders), but that comes at a price—you have to write more code and it's harder to make it interact with lighting. These shaders are written in Cg/HLSL as well.
  • Fixed function shaders need to be written for old hardware that doesn't support programmable shaders. You will probably want to write fixed function shaders as an nth fallback to your fancy fragment or surface shaders, to make sure your game still renders something sensible when run on old hardware or simpler mobile platforms. Fixed function shaders are entirely written in a language called ShaderLab, which is similar to Microsoft's .FX files or NVIDIA's CgFX.

Regardless of which type you choose, the actual meat of the shader code will always be wrapped in ShaderLab, which is used to organize the shader structure. It looks similar to the following code:

Shader "MyShader" {     
  Properties {         
    // All properties go here
     _MyTexture ("My Texture", 2D) = "white" { } 
}
SubShader {         
   //  Choose your written style        
   //  - surface shader or         
   //  - vertex and fragment shader or         
   //  - fixed function shader    
} 
    
SubShader {         
   // Optional - A simpler version of the SubShader above that can run on older graphics cards   
} 
}

However, we will only talk about the surface shaders, which we used in Project 3, The Hero/Heroine Part I—Models and Shaders.

ShaderLab properties

From the preceding example code, in the Properties block, we can define the type of properties, as shown in the following table:

Type

Description

name ("display name", Range (min, max)) = number

Defines a float property, represented as a slider from min to max in the Inspector view.

name ("display name", Color) = (number,number,number,number)

Defines a float property, represented as a slider from min to max in the Inspector view.

name ("display name", Color) = (number,number,number,number)

Defines a color property.

name ("display name", 2D) = "name" { options }

Defines a 2D texture property.

name ("display name", Rect) = "name" { options }

Defines a rectangle (non power of 2) texture property.

name ("display name", Cube) = "name" { options }

Defines a cubemap texture property.

name ("display name", Float) = number

Defines a float property.

name ("display name", Vector) = (number,number,number,number)

Defines a four-component vector property.

Each property inside the shader is referenced by name (in Unity, it's common to start shader property names with underscore). The property will show up in material inspector as Display name. For each property a default value is given after the equals sign:

  • For Range and Float properties: It's just a single number
  • For Color and Vector properties: It's four numbers in parentheses
  • For texture (2D, Rect, Cube): The default value is either an empty string, or one of the built-in default textures—white, black, gray, or bump.

Example

Properties { 
  _MainTex ("Texture ", 2D) = "white" {} // textures    

  _SpecColor ("Specular color", Color) = (0.30, 0.85, 0.90, 1.0) // color    

  _Gloss ("Shininess", Range (1.0,512)) = 80.0 // sliders    
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.189.171.125