zoukankan      html  css  js  c++  java
  • WikiBooks/Cg Programming

    https://en.wikibooks.org/wiki/Cg_Programming

    Basics

    Minimal Shader(about shaders, materials, and game objects)

     1 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
     2 
     3 Shader "Custom/Cg basic shader" {    //defines the name of the shader    
     4     SubShader {    //unity chooses the subshader that fits the GPU best
     5         Pass {    //some shaders require multiple passes
     6             CGPROGRAM //here begins the part in Unity's Cg
     7 
     8             #pragma vertex vert    //this specifies the vert function as the vertex shader
     9             #pragma fragment frag    //this specifies the frag function as the fragment shader
    10 
    11             float4 vert(float4 vertexPos:POSITION) : SV_POSITION {    //vertex shader
    12                 //this line transforms the vertex input parameter
    13                 //vertexPos with the built-in matrix UNITY_MATRIX_MVP
    14                 //and return it as a nameless vertex output parameter                
    15                 return UnityObjectToClipPos(vertexPos);    //mul(UNITY_MATRIX_MVP,vertexPos)
    16             }
    17 
    18             float4 frag():COLOR    { //fragment shader
    19                 //this fragment shader returns a nameless fragment
    20                 //output parameter (with semantic COLOR) that is set to
    21                 //opaque red(red = 1,green = 0,blue = 0, alpha = 1)
    22                 return float4(1.0,0.0,0.0,1.0);
    23             }
    24 
    25             ENDCG    //here ends the part in Cg
    26         }
    27     }
    28 }
    Basic Shader

    RGB Cube(about vertex output parameters)

     1 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
     2 
     3 Shader "Custom/Cg shader for RGB Cube"{
     4     SubShader{
     5         Pass{
     6             CGPROGRAM
     7 
     8             #pragma vertex vert    //vert function is the vertex shader
     9             #pragma fragment frag    //frag function is the fragment shader
    10 
    11             //for multiple vertex output parameters an ouput structure is defined
    12             struct vertexOutput{
    13                 float4 pos:SV_POSITION;
    14                 float4 col:TEXCOORD0;
    15                 //nointerpolation float4 col:TEXCOORD0;
    16             };
    17 
    18             //vertext shader
    19             vertexOutput vert(float4 vertexPos:POSITION){
    20                 vertexOutput output;    //we don't need to type 'struct' here
    21 
    22                 output.pos = UnityObjectToClipPos(vertexPos);
    23                 output.col = vertexPos+float4(0.5,0.5,0.5,0.0);
    24 
    25                 //here the vertex shader writes output data to the output structure.
    26                 //we add 0.5 to the x,y,z coordinates,because the coordinates of the cube are between -0.5 and 0.5
    27                 //but we need them between 0.0 and 1.0
    28                 return output;
    29             }
    30 
    31             //fragment shader
    32             float4 frag(vertexOutput input):COLOR {
    33                 //here the fragment shader returns the "col" input parameter with semantic TEXCOORD0 as nameless
    34                 //output parameter with semantic COLOR
    35                 return input.col;
    36             }
    37 
    38             ENDCG
    39         }
    40     }
    41 }
    Shader for RGB Cube
     1 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
     2 
     3 Shader "Custom/Cg shader for RGB Cube"{
     4     SubShader{
     5         Pass{
     6             CGPROGRAM
     7 
     8             #pragma vertex vert    //vert function is the vertex shader
     9             #pragma fragment frag    //frag function is the fragment shader
    10 
    11             void vert(float4 vertexPos:POSITION,out float4 pos:SV_POSITION,out float4 col:TEXCOORD0){
    12                 pos = UnityObjectToClipPos(vertexPos);
    13                 col = vertexPos+float4(0.5,0.5,0.5,0.0);
    14                 return;
    15             }
    16 
    17             float4 frag(float4 pos:SV_POSITION,float4 col:TEXCOORD0):COLOR{
    18                 return col;
    19             }
    20 
    21             ENDCG
    22         }
    23     }
    24 }
    Shader for RGB Cube

    Debugging of shaders(about vertex input parameters)

     1 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
     2 
     3 Shader "Custom/Cg shader with all built-in vertex input parameters" {
     4     SubShader {
     5         Pass{
     6             CGPROGRAM
     7 
     8             #pragma vertex vert
     9             #pragma fragment frag
    10 
    11             struct vertexInput{
    12                 float4 vertex:POSITION;        //position(in object coordinates,i.e. local or model coordinates)
    13                 float4 tangent:TANGENT;        //vector orthogonal to the surface normal
    14                 float3 normal:NORMAL;        //surface normal vector(in object coordinates;usually normalized to unit length)
    15                 float4 texcoord:TEXCOORD0;    //0th set of texture,coordinates(a.k.a "UV";between 0 and 1)
    16                 float4 texcoord1:TEXCOORD1;    //1st set of tex.coors.
    17                 float4 texcoord2:TEXCOORD2;    //2nd set of tex.coors.
    18                 float4 texcoord3:TEXCOORD3;    //3rd set of tex.coors.
    19                 fixed4 color:COLOR;            //color(usually constant)
    20             };
    21 
    22             struct vertexOutput{
    23                 float4 pos:SV_POSITION;
    24                 float4 col:TEXCOOORD0;
    25             };
    26 
    27             vertexOutput vert(vertexInput input){
    28                 vertexOutput output;
    29                 output.pos = UnityObjectToClipPos(input.vertex);
    30                 //output.col = input.texcoord;    //set the output color
    31 
    32                 //other possibilities to play with:
    33 
    34                 //output.col = input.vertex;
    35                 //output.col = input.tangent;
    36                 //output.col = float4(input.normal,1.0);
    37                 //output.col = input.texcoord;
    38                 //output.col = input.texcoord1;
    39                 //output.col = input.texcoord2;
    40                 //output.col = input.texcoord3;
    41                 output.col = input.color;
    42 
    43                 return output;
    44             }
    45 
    46             float4 frag(vertexOutput input):COLOR{
    47                 return input.col;
    48             }
    49 
    50             ENDCG
    51         }
    52     }
    53 }
    Shader with all built-in vertex input parameters
     1 //struct appdata_base {
     2 //    float4 vertex : POSITION;
     3 //    float3 normal : NORMAL;
     4 //    float4 texcoord : TEXCOORD0;
     5 //};
     6 //struct appdata_tan {
     7 //    float4 vertex : POSITION;
     8 //    float4 tangent : TANGENT;
     9 //    float3 normal : NORMAL;
    10 //    float4 texcoord : TEXCOORD0;
    11 //};
    12 //struct appdata_full {
    13 //    float4 vertex : POSITION;
    14 //    float4 tangent : TANGENT;
    15 //    float3 normal : NORMAL;
    16 //    float4 texcoord : TEXCOORD0;
    17 //    float4 texcoord1 : TEXCOORD1;
    18 //    float4 texcoord2 : TEXCOORD2;
    19 //    float4 texcoord3 : TEXCOORD3;
    20 //    fixed4 color : COLOR;
    21 //    // and additional texture coordinates only on XBOX360
    22 //};
    23 //struct appdata_img {
    24 //    float4 vertex : POSITION;
    25 //    half2 texcoord : TEXCOORD0;
    26 //};
    27 
    28 Shader "Custom/Cg shader with all built-in vertex input parameters" {
    29     SubShader {
    30         Pass{
    31             CGPROGRAM
    32 
    33             #pragma vertex vert
    34             #pragma fragment frag
    35             #include "UnityCG.cginc"
    36 
    37             struct vertexOutput{
    38                 float4 pos:SV_POSITION;
    39                 float4 col:TEXCOOORD0;
    40             };
    41 
    42             vertexOutput vert(appdata_full input){
    43                 vertexOutput output;
    44 
    45                 output.pos = UnityObjectToClipPos(input.vertex);
    46                 output.col = input.texcoord;
    47 
    48                 return output;
    49             }
    50 
    51             float4 frag(vertexOutput input):COLOR{
    52                 return input.col;
    53             }
    54 
    55             ENDCG
    56         }
    57     }
    58 }
    Shader with all built-in vertex input parameters

    Shading in World Space(about uniforms)

     1 // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
     2 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
     3 
     4 Shader "Custom/Cg shading in world space" {
     5     SubShader{
     6         Pass{
     7             CGPROGRAM
     8 
     9             #pragma vertex vert
    10             #pragma fragment frag
    11 
    12             //uniform float4x4 _Object2World;
    13             //automatic definition of a Unity-specific uniform parameter
    14             struct vertexInput{
    15                 float4 vertex:POSITION;
    16             };
    17 
    18             struct vertexOutput{
    19                 float4 pos:SV_POSITION;
    20                 float4 position_in_world_space:TEXCOORD0;
    21             };
    22 
    23             vertexOutput vert(vertexInput input){
    24                 vertexOutput output;
    25 
    26                 output.pos = UnityObjectToClipPos(input.vertex);
    27                 //transformation of input.vertex from object coordinates to world coordinates;
    28                 output.position_in_world_space = mul(unity_ObjectToWorld,input.vertex);
    29 
    30                 return output;
    31             }
    32 
    33             float4 frag(vertexOutput input):COLOR{
    34                 //computes the distance between the fragment position and the origin(the 4th coordinates should always be 1 for points)
    35                 float dist = distance(input.position_in_world_space,float4(0.0,0.0,0.0,1.0));
    36 
    37                 if(dist < 1){
    38                     return float4(0.0,1.0,0.0,1.0);
    39                 } else {
    40                     return float4(0.1,0.1,0.1,1.0);
    41                 }
    42             }
    43 
    44             ENDCG
    45         }
    46     }
    47 }
    Shading in World Space
     1 uniform float4 _Time,_SinTime,_CosTime;    //time values
     2 uniform float4 _ProjectionParams;    //x = 1 or -1 (-1 if projection is flipped) y = near plane; z = far plane; w = 1/far plane
     3 uniform float4 _ScreenParams;    //x = width;y = height; z = 1 + 1/width; w = 1+1/height
     4 uniform float3 _WorldSpaceCameraPos;
     5 uniform float4x4 _Object2World;    //model(local)matrix
     6 uniform float4x4 _World2Object;    //inverse model matrix
     7 uniform float4 _WorldSpaceLightPos();    //position or direction of light source for forward rendering
     8 uniform float4x4 UNITY_MATRIX_MVP;    //model view projection matrix
     9 uniform float4x4 UNITY_MATRIX_MV;    //model view matrix
    10 uniform float4x4 UNITY_MATRIX_V;    //view matrix
    11 uniform float4x4 UNITY_MATRIX_P;    //projection matrix
    12 uniform float4x4 UNITY_MATRIX_VP;    //view projection matrix
    13 uniform float4x4 UNITY_MATRIX_T_MV;    //transpose of model view matrix
    14 uniform float4x4 UNITY_MATRIX_IT_MV;//transpose of the inverse model view matrix
    15 uniform float4 UNITY_LIGHTMODEL_AMBIENT;    //ambient color
    More Unity-Specific Uniforms

    Transparent Surfaces

    Cutaways(about discarding fragments and triangle-face culling)

     1 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
     2 
     3 Shader "Custom/Cg shader using discard" {
     4     SubShader{
     5         Pass{
     6             //turn off triangle culling,alternatives are:
     7             //Cull Back(or nothing):cull only back faces
     8             //Cull Front:cull only front faces
     9             Cull off    
    10 
    11             CGPROGRAM
    12 
    13             #pragma vertex vert
    14             #pragma fragment frag
    15 
    16             struct vertexInput{
    17                 float4 vertex:POSITION;
    18             };
    19 
    20             struct vertexOutput{
    21                 float4 pos:SV_POSITION;
    22                 float4 posInObjectCoords:TEXCOORD0;
    23             };
    24 
    25             vertexOutput vert(vertexInput input){
    26                 vertexOutput output;
    27                 
    28                 output.pos = UnityObjectToClipPos(input.vertex);
    29                 output.posInObjectCoords = input.vertex;
    30 
    31                 return output;
    32             }
    33 
    34             float4 frag(vertexOutput input):COLOR{
    35                 if(input.posInObjectCoords.y > 0.0){
    36                     //return float4(1.0,0.0,0.0,1.0);
    37                     discard;    //drop the fragment if y coordinate > 0
    38                 }
    39                 return float4(0.0,1.0,0.0,1.0);    //green
    40             }
    41 
    42             ENDCG
    43         }
    44     }
    45 }
    Shader using discard

     

     1 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
     2 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
     3 
     4 Shader "Custom/Cg shader with two passes using discard" {
     5     SubShader{
     6         // first pass (is executed before the second pass)
     7         Pass{
     8             Cull Front    // cull only front faces
     9 
    10             CGPROGRAM
    11 
    12             #pragma vertex vert
    13             #pragma fragment frag
    14 
    15             struct vertexInput{
    16                 float4 vertex:POSITION;
    17             };
    18 
    19             struct vertexOutput{
    20                 float4 pos:SV_POSITION;
    21                 float4 posInObjectCoords:TEXCOORD0;
    22             };
    23 
    24             vertexOutput vert(vertexInput input){
    25                 vertexOutput output;
    26 
    27                 output.pos = UnityObjectToClipPos(input.vertex);
    28                 output.posInObjectCoords = input.vertex;
    29                 
    30                 return output;
    31             }
    32 
    33             float4 frag(vertexOutput input):COLOR{
    34                 if(input.posInObjectCoords.y > 0.0){
    35                     discard;// drop the fragment  if y coordinate > 0
    36                 }
    37                 return float4(1.0,0.0,0.0,1.0);    // red
    38             }
    39 
    40             ENDCG
    41         }
    42         // second pass (is executed after the first pass)
    43         Pass{
    44             Cull Back // cull only back faces
    45 
    46             CGPROGRAM
    47 
    48             #pragma vertex vert
    49             #pragma fragment frag
    50 
    51             struct vertexInput{
    52                 float4 vertex:POSITION;
    53             };
    54 
    55             struct vertexOutput{
    56                 float4 pos:SV_POSITION;
    57                 float4 posInObjectCoords:TEXCOORD0;
    58             };
    59 
    60             vertexOutput vert(vertexInput input){
    61                 vertexOutput output;
    62 
    63                 output.pos = UnityObjectToClipPos(input.vertex);
    64                 output.posInObjectCoords = input.vertex;
    65 
    66                 return output;
    67             }
    68 
    69             float4 frag(vertexOutput input):COLOR{
    70                 if(input.posInObjectCoords.y > 0.0){
    71                     discard; // drop the fragment if y coordinate > 0
    72                 }
    73                 return float4(0.0,1.0,0.0,1.0);    // green
    74             }
    75 
    76             ENDCG
    77         }
    78     }
    79 }
    Shader with two passes using discard

    Transparency(about blending)

     1 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
     2 
     3 Shader "Custom/Cg shader using blending" {
     4     SubShader{
     5         Tags { "Queue" = "Transparent" } // draw after all opaque geometry has been drawn
     6         Pass{
     7             ZWrite Off // don't write to depth buffer in order not to occlude other objects
     8 
     9             Blend SrcAlpha OneMinusSrcAlpha // use alpha blending
    10 
    11             CGPROGRAM
    12 
    13             #pragma vertex vert
    14             #pragma fragment frag
    15 
    16             float4 vert(float4 vertexInput:POSITION):SV_POSITION{
    17                 
    18                 return UnityObjectToClipPos(vertexInput);
    19             }
    20 
    21             float4 frag():COLOR{
    22                 // the fourth components(alpha) is important: this is semitransparent green
    23                 return float4(0.0,1.0,0.0,0.3);
    24             }
    25 
    26             ENDCG
    27         }
    28     }
    29 }
    Shader using blending

     1 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
     2 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
     3 
     4 Shader "Cg shader using blending" {
     5     Subshader{
     6         // draw after all opaque geometry has been drawn
     7         Tags { "Queue" = "Transparent" }
     8         Pass {        
     9             Cull Front // first pass renders only back faces (the "inside")
    10             ZWrite Off // don't write to depth buffer in order not to occlude other objects
    11             Blend SrcAlpha OneMinusSrcAlpha // use alpha blending
    12 
    13             CGPROGRAM
    14 
    15             #pragma vertex vert
    16             #pragma fragment frag
    17 
    18             float4 vert(float4 vertexPos:POSITION):SV_POSITION{
    19                 return UnityObjectToClipPos(vertexPos);
    20             }
    21 
    22             float4 frag():COLOR{
    23                 // the fourth component(alpha) is important:this is semitransparent red
    24                 return float4(1.0,0.0,0.0,0.3);
    25             }
    26 
    27             ENDCG
    28         }
    29 
    30         Pass {
    31             Cull Back // second pass renders only front faces (the "outside")
    32             ZWrite Off // don't write to depth buffer in order not to occlude other objects
    33             Blend SrcAlpha OneMinusSrcAlpha // use alpha blending
    34 
    35             CGPROGRAM
    36 
    37             #pragma vertex vert
    38             #pragma fragment frag
    39 
    40             float4 vert(float4 vertexPos:POSITION):SV_POSITION{
    41                 return UnityObjectToClipPos(vertexPos);
    42             }
    43 
    44             float4 frag():COLOR{
    45                 // the fourth component(alpha) is important:this is semitransparent green;
    46                 return float4(0.0,1.0,0.0,0.3);
    47             }
    48 
    49             ENDCG
    50         }
    51     }
    52 }
    Shader using blending

    Order-Independent Transparency(about order-independent blending)

     1 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
     2 
     3 Shader "Custom/Cg shader using additive blending" {
     4     SubShader{
     5         Tags { "Queue" = "Transparent" }    // draw after all opaque geometry has been drawn
     6         Pass{
     7             Cull Off // draw front and back faces
     8             ZWrite Off // don't write to depth buffer in order not to occlude other objects
     9             Blend SrcAlpha One // additive blending
    10 
    11             CGPROGRAM
    12 
    13             #pragma vertex vert
    14             #pragma fragment frag
    15 
    16             float4 vert(float4 vertexPos:POSITION):SV_POSITION{
    17                 return UnityObjectToClipPos(vertexPos);
    18             }
    19             
    20             float4 frag():COLOR{
    21                 return float4(1.0,0.0,0.0,0.2);
    22             }
    23 
    24             ENDCG
    25         }
    26     }
    27 }
    Shader using additive blending

     1 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
     2 
     3 Shader "Custom/Cg shader using multiplicative blending" {
     4    SubShader {
     5       Tags { "Queue" = "Transparent" } // draw after all opaque geometry has been drawn
     6       Pass { 
     7          Cull Off // draw front and back faces
     8          ZWrite Off // don't write to depth buffer in order not to occlude other objects
     9          Blend Zero OneMinusSrcAlpha // multiplicative blending for attenuation by the fragment's alpha
    10 
    11          CGPROGRAM 
    12  
    13          #pragma vertex vert 
    14          #pragma fragment frag
    15  
    16          float4 vert(float4 vertexPos : POSITION) : SV_POSITION 
    17          {
    18             return UnityObjectToClipPos(vertexPos);
    19          }
    20  
    21          float4 frag(void) : COLOR 
    22          {
    23             return float4(1.0, 0.0, 0.0, 0.2); 
    24          }
    25  
    26          ENDCG  
    27       }
    28    }
    29 }
    Shader using multiplicative blending

     1 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
     2 
     3 Shader "Custom/Cg Shader using order-independent blending" {
     4     SubShader{
     5         Tags { "Queue" = "Transparent" }    // draw after all opaque geometry has been drawn
     6         Pass{
     7             Cull Off // draw front and back faces
     8             ZWrite Off // don't write to depth buffer in order not to occlude other objects
     9             Blend Zero OneMinusSrcAlpha // multiplicative blending for attenuation by fragment's alpha
    10 
    11             CGPROGRAM
    12 
    13             #pragma vertex vert
    14             #pragma fragment frag
    15 
    16             float4 vert(float4 vertexPos:POSITION):SV_POSITION{
    17                 return UnityObjectToClipPos(vertexPos);
    18             }
    19 
    20             float4 frag():COLOR{
    21                 return float4(1.0,0.0,0.0,0.2);
    22             }
    23 
    24             ENDCG
    25         }
    26 
    27         Pass{
    28             Cull Off // draw front and back faces
    29             ZWrite Off // don't write to depth buffer in order not to occlude other objects
    30             Blend SrcAlpha One // additive blending to add colors
    31 
    32             CGPROGRAM
    33 
    34             #pragma vertex vert
    35             #pragma fragment frag
    36 
    37             float4 vert(float4 vertexPos:POSITION):SV_POSITION{
    38                 return UnityObjectToClipPos(vertexPos);
    39             }
    40 
    41             float4 frag():COLOR{
    42                 return float4(1.0,0.0,0.0,0.2);
    43             }
    44 
    45             ENDCG
    46         }
    47     }
    48 }
    Shader using order-independent blending

    Silhouette Enhancement(about transforming normal vectors)

     1 // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
     2 // Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
     3 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
     4 
     5 Shader "Custom/Cg silhouette enhancement" {
     6    Properties {
     7       _Color ("Color", Color) = (1, 1, 1, 0.5) // user-specified RGBA color including opacity         
     8    }
     9    SubShader {
    10       Tags { "Queue" = "Transparent" } // draw after all opaque geometry has been drawn         
    11       Pass { 
    12          ZWrite Off // don't occlude other objects
    13          Blend SrcAlpha OneMinusSrcAlpha // standard alpha blending
    14  
    15          CGPROGRAM 
    16  
    17          #pragma vertex vert  
    18          #pragma fragment frag 
    19  
    20          #include "UnityCG.cginc"
    21  
    22          uniform float4 _Color; // define shader property for shaders
    23  
    24          struct vertexInput {
    25             float4 vertex : POSITION;
    26             float3 normal : NORMAL;
    27          };
    28          struct vertexOutput {
    29             float4 pos : SV_POSITION;
    30             float3 normal : TEXCOORD;
    31             float3 viewDir : TEXCOORD1;
    32          };
    33  
    34          vertexOutput vert(vertexInput input) 
    35          {
    36             vertexOutput output;
    37  
    38             float4x4 modelMatrix = unity_ObjectToWorld;
    39             float4x4 modelMatrixInverse = unity_WorldToObject; 
    40  
    41             output.normal = normalize(mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
    42             output.viewDir = normalize(_WorldSpaceCameraPos - mul(modelMatrix, input.vertex).xyz);
    43  
    44             output.pos = UnityObjectToClipPos(input.vertex);
    45             return output;
    46          }
    47  
    48          float4 frag(vertexOutput input) : COLOR
    49          {
    50             float3 normalDirection = normalize(input.normal);
    51             float3 viewDirection = normalize(input.viewDir);
    52  
    53             float newOpacity = min(1.0, _Color.a / abs(dot(viewDirection, normalDirection)));
    54             return float4(_Color.rgb, newOpacity);
    55          }
    56  
    57          ENDCG
    58       }
    59    }
    60 }
    Silhouette Enhancement

    Basic Lighting

    Diffuse Reflection(about per-vertex diffuse lighting and multiple light sources of different kinds)

     1 // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
     2 // Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
     3 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
     4 
     5 Shader "Custom/Cg per-vertex diffuse lighting" {
     6     Properties {
     7         _Color ("Diffuse Material Color",Color) = (1,1,1,1)
     8     }
     9 
    10     SubShader{
    11         Pass{
    12             Tags { "LightMode" = "ForwardBase" }    // make sure that all uniforms are correctly set
    13 
    14             CGPROGRAM
    15 
    16             #pragma vertex vert
    17             #pragma fragment frag
    18 
    19             #include "UnityCG.cginc"
    20 
    21             uniform float4 _LightColor0;    // color of light source(from "Lighting.cginc")
    22             uniform float4 _Color;    // define shader property for shaders
    23 
    24             struct vertexInput{
    25                 float4 vertex:POSITION;
    26                 float3 normal:NORMAL;
    27             };
    28 
    29             struct vertexOutput{
    30                 float4 pos:SV_POSITION;
    31                 float4 col:COLOR;
    32             };
    33 
    34             vertexOutput vert(vertexInput input){
    35                 vertexOutput output;
    36 
    37                 float4x4 modelMatrix = unity_ObjectToWorld;
    38                 float4x4 modelMatrixInverse = unity_WorldToObject;
    39 
    40                 float3 normalDirection = normalize(mul(float4(input.normal,0.0),modelMatrixInverse).xyz);
    41                 float3 lightDirection = normalize(_WorldSpaceLightPos0.xyz);
    42 
    43                 float3 diffuseReflection = _LightColor0.rgb * _Color.rgb * max(0.0,dot(normalDirection,lightDirection));
    44 
    45                 output.col = float4(diffuseReflection,1.0);
    46                 output.pos = UnityObjectToClipPos(input.vertex);
    47                 return output;
    48             }
    49 
    50             float4 frag(vertexOutput input):COLOR{
    51                 return input.col;
    52             }
    53 
    54             ENDCG
    55         }
    56     }
    57 
    58     Fallback "Diffuse"
    59 }
    Per-vertex diffuse lighting
      1 // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
      2 // Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
      3 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
      4 
      5 Shader "Cg per-vertex diffuse lighting" {
      6     Properties {
      7         _Color ("Diffuse Material Color",Color) = (1,1,1,1)
      8     }
      9     SubShader {
     10         //Pass for first light source
     11         Pass{
     12             Tags { "LightMode" = "ForwardBase" }
     13 
     14             CGPROGRAM
     15 
     16             #pragma vertex vert
     17             #pragma fragment frag
     18 
     19             #include "UnityCG.cginc"
     20             
     21             uniform float4 _LightColor0; //color of light source (from "Lighting.cginc")
     22             uniform float4 _Color; //define shader property for shader
     23 
     24             struct vertexInput{
     25                 float4 vertex:POSITION;
     26                 float3 normal:NORMAL;
     27             };
     28 
     29             struct vertexOutput{
     30                 float4 pos:SV_POSITION;
     31                 float4 col:COLOR;
     32             };
     33 
     34             vertexOutput vert(vertexInput input){
     35                 vertexOutput output;
     36 
     37                 float4x4 modelMatrix = unity_ObjectToWorld;
     38                 float4x4 modelMatrixInverse = unity_WorldToObject;
     39 
     40                 float3 normalDirection = normalize(mul(float4(input.normal,0.0),modelMatrixInverse).xyz);
     41                 float3 lightDirection = normalize(_WorldSpaceLightPos0.xyz);
     42 
     43                 float3 diffuseReflection = _LightColor0.rgb * _Color.rgb * max(0.0,dot(normalDirection,lightDirection));
     44 
     45                 output.col = float4(diffuseReflection,1.0);
     46                 output.pos = UnityObjectToClipPos(input.vertex);
     47 
     48                 return output;
     49             }
     50 
     51             float4 frag(vertexOutput input):COLOR{
     52                 return input.col;
     53             }
     54 
     55             ENDCG
     56         }
     57 
     58         Pass {
     59             // pass for additional light source
     60             Tags { "LightMode" = "ForwardAdd" }
     61 
     62             // additional blending
     63             Blend One One
     64 
     65             CGPROGRAM
     66 
     67             #pragma vertex vert
     68             #pragma fragment frag
     69 
     70             #include "UnityCG.cginc"
     71 
     72             // color of light source (from "Lighting.cginc")
     73             uniform float4 _LightColor0;
     74             // define shader property for shaders
     75             uniform float4 _Color;
     76 
     77             struct vertexInput{
     78                 float4 vertex:POSITION;
     79                 float3 normal:NORMAL;
     80             };
     81 
     82             struct vertexOutput{
     83                 float4 pos:SV_POSITION;
     84                 float4 col:COLOR;
     85             };
     86 
     87             vertexOutput vert(vertexInput input){
     88                 vertexOutput output;
     89 
     90                 float4x4 modelMatrix = unity_ObjectToWorld;
     91                 float4x4 modelMatrixInverse = unity_WorldToObject;
     92 
     93                 float3 normalDirection = normalize(mul(float4(input.normal,0.0),modelMatrixInverse).xyz);
     94                 float3 lightDirection = normalize(_WorldSpaceLightPos0.xyz);
     95 
     96                 float3 diffuseReflection = _LightColor0.rgb * _Color.rgb * max(0.0,dot(normalDirection,lightDirection));
     97 
     98                 output.col = float4(diffuseReflection,1.0);
     99                 output.pos = UnityObjectToClipPos(input.vertex);
    100                 return output;
    101             }
    102 
    103             float4 frag(vertexOutput input):COLOR{
    104                 return input.col;
    105             }
    106 
    107             ENDCG
    108         }
    109     }
    110 
    111     Fallback "Diffuse"
    112 }
    Per-vertex diffuse lighting
      1 // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
      2 // Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
      3 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
      4 
      5 Shader "Custom/Cg per-vertex diffuse lighting" {
      6     Properties {
      7         _Color ("Diffuse Material Color",Color) = (1,1,1,1)
      8     }
      9     SubShader{
     10         Pass{
     11             // pass for first light source
     12             Tags { "LightMode" = "ForwardBase" }
     13 
     14             CGPROGRAM
     15 
     16             #pragma vertex vert
     17             #pragma fragment frag
     18 
     19             #include "UnityCG.cginc"
     20 
     21             // color of light source(from "Lighting.cginc")
     22             uniform float4 _LightColor0;
     23             // define shader property for shaders
     24             uniform float4 _Color;
     25 
     26             struct vertexInput{
     27                 float4 vertex:POSITION;
     28                 float3 normal:NORMAL;
     29             };
     30             struct vertexOutput{
     31                 float4 pos:SV_POSITION;
     32                 float4 col:COLOR;
     33             };
     34 
     35             vertexOutput vert(vertexInput input){
     36                 vertexOutput output;
     37 
     38                 float4x4 modelMatrix = unity_ObjectToWorld;
     39                 float4x4 modelMatrixInverse = unity_WorldToObject;
     40 
     41                 float3 normalDirection = normalize(mul(float4(input.normal,0.0),modelMatrixInverse).xyz);
     42                 float3 lightDirection;
     43                 float attenuation;
     44 
     45                 if(_WorldSpaceLightPos0.w == 0.0){ // directional light
     46                     attenuation = 1.0;    // no attenuation
     47                     lightDirection = normalize(_WorldSpaceLightPos0.xyz);
     48                 } else {    // point or spot light
     49                     float3 vertexToLightSource = _WorldSpaceLightPos0.xyz - mul(modelMatrix,input.vertex).xyz;
     50                     float distance = length(vertexToLightSource);
     51                     attenuation = 1.0 / distance;    // linear attenuation
     52                     lightDirection = normalize(vertexToLightSource);
     53                 }
     54 
     55                 float3 diffuseReflection = attenuation * _LightColor0.rgb * _Color.rgb * max(0.0,dot(normalDirection,lightDirection));
     56 
     57                 output.col = float4(diffuseReflection,1.0);
     58                 output.pos = UnityObjectToClipPos(input.vertex);
     59                 return output;
     60             }
     61 
     62             float4 frag(vertexOutput input):COLOR{
     63                 return input.col;
     64             }
     65 
     66             ENDCG
     67         }
     68 
     69         Pass {
     70             // pass for addtional light source
     71             Tags { "LightMode" = "ForwardAdd" }
     72 
     73             Blend One One // additive blending
     74 
     75             CGPROGRAM
     76 
     77             #pragma vertex vert
     78             #pragma fragment frag
     79 
     80             #include "UnityCG.cginc"
     81 
     82             // color of light source(from "Lighting.cginc")
     83             uniform float4 _LightColor0;
     84             // define shader property for shaders
     85             uniform float4 _Color;
     86 
     87             struct vertexInput{
     88                 float4 vertex:POSITION;
     89                 float3 normal:NORMAL;
     90             };
     91             struct vertexOutput{
     92                 float4 pos:SV_POSITION;
     93                 float4 col:COLOR;
     94             };
     95 
     96             vertexOutput vert(vertexInput input){
     97                 vertexOutput output;
     98 
     99                 float4x4 modelMatrix = unity_ObjectToWorld;
    100                 float4x4 modelMatrixInverse = unity_WorldToObject;
    101 
    102                 float3 normalDirection = normalize(mul(float4(input.normal,0.0),modelMatrixInverse).xyz);
    103                 float3 lightDirection;
    104                 float attenuation;
    105 
    106                 if(_WorldSpaceLightPos0.w == 0.0){    // directional light
    107                     attenuation = 1.0;    // no attenuation
    108                     lightDirection = normalize(_WorldSpaceLightPos0.xyz);
    109                 } else {    // point or spot light
    110                     float3 vertexToLightSource = _WorldSpaceLightPos0.xyz - mul(modelMatrix,input.vertex).xyz;
    111                     float distance = length(vertexToLightSource);
    112                     attenuation = 1.0 / distance;// linear attenuation
    113                     lightDirection = normalize(vertexToLightSource);
    114                 }
    115 
    116                 float3 diffuseReflection = attenuation * _LightColor0.rgb * _Color.rgb * max(0.0,dot(normalDirection,lightDirection));
    117 
    118                 output.col = float4(diffuseReflection,1.0);
    119                 output.pos = UnityObjectToClipPos(input.vertex);
    120                 
    121                 return output;
    122             }
    123 
    124             float4 frag(vertexOutput input):COLOR{
    125                 return input.col;
    126             }
    127 
    128             ENDCG
    129         }
    130     }
    131 
    132     Fallback "Diffuse"
    133 }
    Per-vertex diffuse lighting

    Specular Highlights(about per-vertex lighting)

      1 // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
      2 // Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
      3 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
      4 
      5 Shader "Custom/Cg per-vertex lighting" {
      6    Properties {
      7       _Color ("Diffuse Material Color", Color) = (1,1,1,1) 
      8       _SpecColor ("Specular Material Color", Color) = (1,1,1,1) 
      9       _Shininess ("Shininess", Float) = 10
     10    }
     11    SubShader {
     12       Pass {    
     13          Tags { "LightMode" = "ForwardBase" } 
     14             // pass for ambient light and first light source
     15  
     16          CGPROGRAM
     17  
     18          #pragma vertex vert  
     19          #pragma fragment frag 
     20  
     21          #include "UnityCG.cginc"
     22          uniform float4 _LightColor0; 
     23             // color of light source (from "Lighting.cginc")
     24  
     25          // User-specified properties
     26          uniform float4 _Color; 
     27          uniform float4 _SpecColor; 
     28          uniform float _Shininess;
     29  
     30          struct vertexInput {
     31             float4 vertex : POSITION;
     32             float3 normal : NORMAL;
     33          };
     34          struct vertexOutput {
     35             float4 pos : SV_POSITION;
     36             float4 col : COLOR;
     37          };
     38  
     39          vertexOutput vert(vertexInput input) 
     40          {
     41             vertexOutput output;
     42  
     43             float4x4 modelMatrix = unity_ObjectToWorld;
     44             float3x3 modelMatrixInverse = unity_WorldToObject;
     45             float3 normalDirection = normalize(
     46                mul(input.normal, modelMatrixInverse));
     47             float3 viewDirection = normalize(_WorldSpaceCameraPos 
     48                - mul(modelMatrix, input.vertex).xyz);
     49             float3 lightDirection;
     50             float attenuation;
     51  
     52             if (0.0 == _WorldSpaceLightPos0.w) // directional light?
     53             {
     54                attenuation = 1.0; // no attenuation
     55                lightDirection = normalize(_WorldSpaceLightPos0.xyz);
     56             } 
     57             else // point or spot light
     58             {
     59                float3 vertexToLightSource = _WorldSpaceLightPos0.xyz
     60                   - mul(modelMatrix, input.vertex).xyz;
     61                float distance = length(vertexToLightSource);
     62                attenuation = 1.0 / distance; // linear attenuation 
     63                lightDirection = normalize(vertexToLightSource);
     64             }
     65  
     66             float3 ambientLighting = 
     67                UNITY_LIGHTMODEL_AMBIENT.rgb * _Color.rgb;
     68  
     69             float3 diffuseReflection = 
     70                attenuation * _LightColor0.rgb * _Color.rgb
     71                * max(0.0, dot(normalDirection, lightDirection));
     72  
     73             float3 specularReflection;
     74             if (dot(normalDirection, lightDirection) < 0.0) 
     75                // light source on the wrong side?
     76             {
     77                specularReflection = float3(0.0, 0.0, 0.0); 
     78                   // no specular reflection
     79             }
     80             else // light source on the right side
     81             {
     82                specularReflection = attenuation * _LightColor0.rgb 
     83                   * _SpecColor.rgb * pow(max(0.0, dot(
     84                   reflect(-lightDirection, normalDirection), 
     85                   viewDirection)), _Shininess);
     86             }
     87  
     88             output.col = float4(ambientLighting + diffuseReflection 
     89                + specularReflection, 1.0);
     90             output.pos = UnityObjectToClipPos(input.vertex);
     91             return output;
     92          }
     93  
     94          float4 frag(vertexOutput input) : COLOR
     95          {
     96             return input.col;
     97          }
     98  
     99          ENDCG
    100       }
    101  
    102       Pass {    
    103          Tags { "LightMode" = "ForwardAdd" } 
    104             // pass for additional light sources
    105          Blend One One // additive blending 
    106  
    107          CGPROGRAM
    108  
    109          #pragma vertex vert  
    110          #pragma fragment frag 
    111  
    112          #include "UnityCG.cginc"
    113          uniform float4 _LightColor0; 
    114             // color of light source (from "Lighting.cginc")
    115  
    116          // User-specified properties
    117          uniform float4 _Color; 
    118          uniform float4 _SpecColor; 
    119          uniform float _Shininess;
    120  
    121          struct vertexInput {
    122             float4 vertex : POSITION;
    123             float3 normal : NORMAL;
    124          };
    125          struct vertexOutput {
    126             float4 pos : SV_POSITION;
    127             float4 col : COLOR;
    128          };
    129  
    130          vertexOutput vert(vertexInput input) 
    131          {
    132             vertexOutput output;
    133  
    134             float4x4 modelMatrix = unity_ObjectToWorld;
    135             float3x3 modelMatrixInverse = unity_WorldToObject;
    136             float3 normalDirection = normalize(
    137                mul(input.normal, modelMatrixInverse));
    138             float3 viewDirection = normalize(_WorldSpaceCameraPos 
    139                - mul(modelMatrix, input.vertex).xyz);
    140             float3 lightDirection;
    141             float attenuation;
    142  
    143             if (0.0 == _WorldSpaceLightPos0.w) // directional light?
    144             {
    145                attenuation = 1.0; // no attenuation
    146                lightDirection = normalize(_WorldSpaceLightPos0.xyz);
    147             } 
    148             else // point or spot light
    149             {
    150                float3 vertexToLightSource = _WorldSpaceLightPos0.xyz
    151                   - mul(modelMatrix, input.vertex).xyz;
    152                float distance = length(vertexToLightSource);
    153                attenuation = 1.0 / distance; // linear attenuation 
    154                lightDirection = normalize(vertexToLightSource);
    155             }
    156  
    157             float3 diffuseReflection = 
    158                attenuation * _LightColor0.rgb * _Color.rgb
    159                * max(0.0, dot(normalDirection, lightDirection));
    160  
    161             float3 specularReflection;
    162             if (dot(normalDirection, lightDirection) < 0.0) 
    163                // light source on the wrong side?
    164             {
    165                specularReflection = float3(0.0, 0.0, 0.0); 
    166                   // no specular reflection
    167             }
    168             else // light source on the right side
    169             {
    170                specularReflection = attenuation * _LightColor0.rgb 
    171                   * _SpecColor.rgb * pow(max(0.0, dot(
    172                   reflect(-lightDirection, normalDirection), 
    173                   viewDirection)), _Shininess);
    174             }
    175  
    176             output.col = float4(diffuseReflection 
    177                + specularReflection, 1.0);
    178                // no ambient contribution in this pass
    179             output.pos = UnityObjectToClipPos(input.vertex);
    180             return output;
    181          }
    182  
    183          float4 frag(vertexOutput input) : COLOR
    184          {
    185             return input.col;
    186          }
    187  
    188          ENDCG
    189       }
    190    }
    191    Fallback "Specular"
    192 }
    Per-vertex lighting

    Two-Sided Surfaces (about two-sided per-vertex lighting)

      1 Shader "Custom/Cg two-sided per-vertex lighting" {
      2    Properties {
      3       _Color ("Front Material Diffuse Color", Color) = (1,1,1,1) 
      4       _SpecColor ("Front Material Specular Color", Color) = (1,1,1,1) 
      5       _Shininess ("Front Material Shininess", Float) = 10
      6       _BackColor ("Back Material Diffuse Color", Color) = (1,1,1,1) 
      7       _BackSpecColor ("Back Material Specular Color", Color) 
      8          = (1,1,1,1) 
      9       _BackShininess ("Back Material Shininess", Float) = 10
     10    }
     11    SubShader {
     12       Pass {    
     13          Tags { "LightMode" = "ForwardBase" } 
     14             // pass for ambient light and first light source 
     15          Cull Back // render only front faces
     16  
     17          CGPROGRAM
     18  
     19          #pragma vertex vert  
     20          #pragma fragment frag 
     21  
     22          #include "UnityCG.cginc"
     23          uniform float4 _LightColor0; 
     24             // color of light source (from "Lighting.cginc")
     25  
     26          // User-specified properties
     27          uniform float4 _Color; 
     28          uniform float4 _SpecColor; 
     29          uniform float _Shininess;
     30          uniform float4 _BackColor; 
     31          uniform float4 _BackSpecColor; 
     32          uniform float _BackShininess;
     33  
     34          struct vertexInput {
     35             float4 vertex : POSITION;
     36             float3 normal : NORMAL;
     37          };
     38          struct vertexOutput {
     39             float4 pos : SV_POSITION;
     40             float4 col : COLOR;
     41          };
     42  
     43          vertexOutput vert(vertexInput input) 
     44          {
     45             vertexOutput output;
     46  
     47             float4x4 modelMatrix = _Object2World;
     48             float4x4 modelMatrixInverse = _World2Object; 
     49  
     50             float3 normalDirection = normalize(
     51                mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
     52             float3 viewDirection = normalize(_WorldSpaceCameraPos 
     53                - mul(modelMatrix, input.vertex).xyz);
     54             float3 lightDirection;
     55             float attenuation;
     56  
     57             if (0.0 == _WorldSpaceLightPos0.w) // directional light?
     58             {
     59                attenuation = 1.0; // no attenuation
     60                lightDirection = normalize(_WorldSpaceLightPos0.xyz);
     61             } 
     62             else // point or spot light
     63             {
     64                float3 vertexToLightSource = _WorldSpaceLightPos0.xyz
     65                   - mul(modelMatrix, input.vertex).xyz;
     66                float distance = length(vertexToLightSource);
     67                attenuation = 1.0 / distance; // linear attenuation 
     68                lightDirection = normalize(vertexToLightSource);
     69             }
     70  
     71             float3 ambientLighting = 
     72                UNITY_LIGHTMODEL_AMBIENT.rgb * _Color.rgb;
     73  
     74             float3 diffuseReflection = 
     75                attenuation * _LightColor0.rgb * _Color.rgb
     76                * max(0.0, dot(normalDirection, lightDirection));
     77  
     78             float3 specularReflection;
     79             if (dot(normalDirection, lightDirection) < 0.0) 
     80                // light source on the wrong side?
     81             {
     82                specularReflection = float3(0.0, 0.0, 0.0); 
     83                   // no specular reflection
     84             }
     85             else // light source on the right side
     86             {
     87                specularReflection = attenuation * _LightColor0.rgb 
     88                   * _SpecColor.rgb * pow(max(0.0, dot(
     89                   reflect(-lightDirection, normalDirection), 
     90                   viewDirection)), _Shininess);
     91             }
     92  
     93             output.col = float4(ambientLighting + diffuseReflection 
     94                + specularReflection, 1.0);
     95             output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
     96             return output;
     97          }
     98  
     99          float4 frag(vertexOutput input) : COLOR
    100          {
    101             return input.col;
    102          }
    103  
    104          ENDCG
    105       }
    106  
    107       Pass {    
    108          Tags { "LightMode" = "ForwardAdd" } 
    109             // pass for additional light sources
    110          Blend One One // additive blending 
    111          Cull Back // render only front faces
    112  
    113          CGPROGRAM
    114  
    115          #pragma vertex vert  
    116          #pragma fragment frag 
    117  
    118          #include "UnityCG.cginc"
    119          uniform float4 _LightColor0; 
    120             // color of light source (from "Lighting.cginc")
    121  
    122         // User-specified properties
    123          uniform float4 _Color; 
    124          uniform float4 _SpecColor; 
    125          uniform float _Shininess;
    126          uniform float4 _BackColor; 
    127          uniform float4 _BackSpecColor; 
    128          uniform float _BackShininess;
    129  
    130          struct vertexInput {
    131             float4 vertex : POSITION;
    132             float3 normal : NORMAL;
    133          };
    134          struct vertexOutput {
    135             float4 pos : SV_POSITION;
    136             float4 col : COLOR;
    137          };
    138  
    139          vertexOutput vert(vertexInput input) 
    140          {
    141             vertexOutput output;
    142  
    143             float4x4 modelMatrix = _Object2World;
    144             float4x4 modelMatrixInverse = _World2Object; 
    145  
    146             float3 normalDirection = normalize(
    147                mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
    148             float3 viewDirection = normalize(_WorldSpaceCameraPos 
    149                - mul(modelMatrix, input.vertex).xyz);
    150             float3 lightDirection;
    151             float attenuation;
    152  
    153             if (0.0 == _WorldSpaceLightPos0.w) // directional light?
    154             {
    155                attenuation = 1.0; // no attenuation
    156                lightDirection = normalize(_WorldSpaceLightPos0.xyz);
    157             } 
    158             else // point or spot light
    159             {
    160                float3 vertexToLightSource = _WorldSpaceLightPos0.xyz
    161                   - mul(modelMatrix, input.vertex).xyz;
    162                float distance = length(vertexToLightSource);
    163                attenuation = 1.0 / distance; // linear attenuation 
    164                lightDirection = normalize(vertexToLightSource);
    165             }
    166  
    167             float3 diffuseReflection = 
    168                attenuation * _LightColor0.rgb * _Color.rgb
    169                * max(0.0, dot(normalDirection, lightDirection));
    170  
    171             float3 specularReflection;
    172             if (dot(normalDirection, lightDirection) < 0.0) 
    173                // light source on the wrong side?
    174             {
    175                specularReflection = float3(0.0, 0.0, 0.0); 
    176                   // no specular reflection
    177             }
    178             else // light source on the right side
    179             {
    180                specularReflection = attenuation * _LightColor0.rgb 
    181                   * _SpecColor.rgb * pow(max(0.0, dot(
    182                   reflect(-lightDirection, normalDirection), 
    183                   viewDirection)), _Shininess);
    184             }
    185  
    186             output.col = float4(diffuseReflection 
    187                + specularReflection, 1.0);
    188                // no ambient contribution in this pass
    189             output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
    190             return output;
    191          }
    192  
    193          float4 frag(vertexOutput input) : COLOR
    194          {
    195             return input.col;
    196          }
    197  
    198          ENDCG
    199       }
    200  
    201       Pass {    
    202          Tags { "LightMode" = "ForwardBase" } 
    203             // pass for ambient light and first light source 
    204          Cull Front// render only back faces
    205  
    206          CGPROGRAM
    207  
    208          #pragma vertex vert  
    209          #pragma fragment frag 
    210  
    211          #include "UnityCG.cginc"
    212          uniform float4 _LightColor0; 
    213             // color of light source (from "Lighting.cginc")
    214  
    215          // User-specified properties
    216          uniform float4 _Color; 
    217          uniform float4 _SpecColor; 
    218          uniform float _Shininess;
    219          uniform float4 _BackColor; 
    220          uniform float4 _BackSpecColor; 
    221          uniform float _BackShininess;
    222  
    223          struct vertexInput {
    224             float4 vertex : POSITION;
    225             float3 normal : NORMAL;
    226          };
    227          struct vertexOutput {
    228             float4 pos : SV_POSITION;
    229             float4 col : COLOR;
    230          };
    231  
    232          vertexOutput vert(vertexInput input) 
    233          {
    234             vertexOutput output;
    235  
    236             float4x4 modelMatrix = _Object2World;
    237             float4x4 modelMatrixInverse = _World2Object; 
    238  
    239             float3 normalDirection = normalize(
    240                mul(float4(-input.normal, 0.0), modelMatrixInverse).xyz);
    241             float3 viewDirection = normalize(_WorldSpaceCameraPos 
    242                - mul(modelMatrix, input.vertex).xyz);
    243             float3 lightDirection;
    244             float attenuation;
    245  
    246             if (0.0 == _WorldSpaceLightPos0.w) // directional light?
    247             {
    248                attenuation = 1.0; // no attenuation
    249                lightDirection = normalize(_WorldSpaceLightPos0.xyz);
    250             } 
    251             else // point or spot light
    252             {
    253                float3 vertexToLightSource = _WorldSpaceLightPos0.xyz
    254                   - mul(modelMatrix, input.vertex).xyz;
    255                float distance = length(vertexToLightSource);
    256                attenuation = 1.0 / distance; // linear attenuation 
    257                lightDirection = normalize(vertexToLightSource);
    258             }
    259  
    260             float3 ambientLighting = 
    261                UNITY_LIGHTMODEL_AMBIENT.rgb * _BackColor.rgb;
    262  
    263             float3 diffuseReflection = 
    264                attenuation * _LightColor0.rgb * _BackColor.rgb
    265                * max(0.0, dot(normalDirection, lightDirection));
    266  
    267             float3 specularReflection;
    268             if (dot(normalDirection, lightDirection) < 0.0) 
    269                // light source on the wrong side?
    270             {
    271                specularReflection = float3(0.0, 0.0, 0.0); 
    272                   // no specular reflection
    273             }
    274             else // light source on the right side
    275             {
    276                specularReflection = attenuation * _LightColor0.rgb 
    277                   * _BackSpecColor.rgb * pow(max(0.0, dot(
    278                   reflect(-lightDirection, normalDirection), 
    279                   viewDirection)), _BackShininess);
    280             }
    281  
    282             output.col = float4(ambientLighting + diffuseReflection 
    283                + specularReflection, 1.0);
    284             output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
    285             return output;
    286          }
    287  
    288          float4 frag(vertexOutput input) : COLOR
    289          {
    290             return input.col;
    291          }
    292  
    293          ENDCG
    294       }
    295  
    296       Pass {    
    297          Tags { "LightMode" = "ForwardAdd" } 
    298             // pass for additional light sources
    299          Blend One One // additive blending 
    300          Cull Front // render only back faces
    301  
    302          CGPROGRAM
    303  
    304          #pragma vertex vert  
    305          #pragma fragment frag 
    306  
    307          #include "UnityCG.cginc"
    308          uniform float4 _LightColor0; 
    309             // color of light source (from "Lighting.cginc")
    310  
    311         // User-specified properties
    312          uniform float4 _Color; 
    313          uniform float4 _SpecColor; 
    314          uniform float _Shininess;
    315          uniform float4 _BackColor; 
    316          uniform float4 _BackSpecColor; 
    317          uniform float _BackShininess;
    318  
    319          struct vertexInput {
    320             float4 vertex : POSITION;
    321             float3 normal : NORMAL;
    322          };
    323          struct vertexOutput {
    324             float4 pos : SV_POSITION;
    325             float4 col : COLOR;
    326          };
    327  
    328          vertexOutput vert(vertexInput input) 
    329          {
    330             vertexOutput output;
    331  
    332             float4x4 modelMatrix = _Object2World;
    333             float4x4 modelMatrixInverse = _World2Object; 
    334  
    335             float3 normalDirection = normalize(
    336                mul(float4(-input.normal, 0.0), modelMatrixInverse).xyz);
    337             float3 viewDirection = normalize(_WorldSpaceCameraPos 
    338                - mul(modelMatrix, input.vertex).xyz);
    339             float3 lightDirection;
    340             float attenuation;
    341  
    342             if (0.0 == _WorldSpaceLightPos0.w) // directional light?
    343             {
    344                attenuation = 1.0; // no attenuation
    345                lightDirection = normalize(_WorldSpaceLightPos0.xyz);
    346             } 
    347             else // point or spot light
    348             {
    349                float3 vertexToLightSource = _WorldSpaceLightPos0.xyz
    350                   - mul(modelMatrix, input.vertex).xyz;
    351                float distance = length(vertexToLightSource);
    352                attenuation = 1.0 / distance; // linear attenuation 
    353                lightDirection = normalize(vertexToLightSource);
    354             }
    355  
    356             float3 diffuseReflection = 
    357                attenuation * _LightColor0.rgb * _BackColor.rgb
    358                * max(0.0, dot(normalDirection, lightDirection));
    359  
    360             float3 specularReflection;
    361             if (dot(normalDirection, lightDirection) < 0.0) 
    362                // light source on the wrong side?
    363             {
    364                specularReflection = float3(0.0, 0.0, 0.0); 
    365                   // no specular reflection
    366             }
    367             else // light source on the right side
    368             {
    369                specularReflection = attenuation * _LightColor0.rgb 
    370                   * _BackSpecColor.rgb * pow(max(0.0, dot(
    371                   reflect(-lightDirection, normalDirection), 
    372                   viewDirection)), _BackShininess);
    373             }
    374  
    375             output.col = float4(diffuseReflection 
    376                + specularReflection, 1.0);
    377                // no ambient contribution in this pass
    378             output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
    379             return output;
    380          }
    381  
    382          float4 frag(vertexOutput input) : COLOR
    383          {
    384             return input.col;
    385          }
    386  
    387          ENDCG
    388       }
    389  
    390    }
    391    Fallback "Specular"
    392 }
    Two-sided per-vertex lighting

    Smooth Specular Highlights(about per-pixel lighting)

      1 // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
      2 // Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
      3 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
      4 
      5 // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
      6 // Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
      7 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
      8 
      9 Shader "Custom/Cg per-pixel lighting" {
     10     Properties {
     11         _Color("Diffuse Material Color",Color) = (1,1,1,1)
     12         _SpecColor("Specular Material Color",Color) = (1,1,1,1)
     13         _Shininess("Shininess",Float) = 10
     14     }
     15     SubShader {
     16         // pass for ambient light and first light source
     17         Pass {
     18             Tags { "LihgtMode" = "ForwardBase" }
     19 
     20             CGPROGRAM
     21 
     22             #pragma vertex vert
     23             #pragma fragment frag
     24 
     25             #include "UnityCG.cginc"
     26             
     27             uniform float4 _LightColor0;    // color of light source(from "Lighting.cginc")
     28 
     29             // User-specified Properties
     30             uniform float4 _Color;
     31             uniform float4 _SpecColor;
     32             uniform float _Shininess;
     33 
     34             struct vertexInput{
     35                 float4 vertex:POSITION;
     36                 float3 normal:NORMAL;
     37             };
     38             struct vertexOutput{
     39                 float4 pos:SV_POSITION;
     40                 float4 posWorld:TEXCOORD0;
     41                 float3 normalDir:TEXCOORD1;
     42             };
     43 
     44             vertexOutput vert(vertexInput input){
     45                 vertexOutput output;
     46 
     47                 float4x4 modelMatrix = unity_ObjectToWorld;
     48                 float4x4 modelMatrixInverse = unity_WorldToObject;
     49 
     50                 output.posWorld = mul(modelMatrix,input.vertex);
     51                 output.normalDir = normalize(mul(float4(input.normal,0.0),modelMatrixInverse).xyz);
     52                 output.pos = UnityObjectToClipPos(input.vertex);
     53 
     54                 return output;
     55             }
     56 
     57             float4 frag(vertexOutput input):COLOR{
     58                 float3 normalDirection = normalize(input.normalDir);
     59 
     60                 float3 viewDirection = normalize(_WorldSpaceCameraPos - input.posWorld.xyz);
     61                 float3 lightDirection;
     62                 float attenuation;
     63 
     64                 if(_WorldSpaceLightPos0.w == 0.0) { // directional light
     65                     attenuation = 1.0;    // no attenuation;
     66                     lightDirection = normalize(_WorldSpaceLightPos0.xyz);
     67                 } else { // point on spot light
     68                     float3 vertexToLightSource = _WorldSpaceLightPos0.xyz - input.posWorld.xyz;
     69                     float distance = length(vertexToLightSource);
     70                     attenuation = 1.0/distance;    // linear attenuation;
     71                     lightDirection = normalize(vertexToLightSource);
     72                 }
     73 
     74                 float3 ambientLighting = UNITY_LIGHTMODEL_AMBIENT.rgb * _Color.rgb;
     75 
     76                 float3 diffuseReflection = attenuation * _LightColor0.rgb * _Color.rgb * max(0.0,dot(normalDirection,lightDirection));
     77 
     78                 float3 specularReflection;
     79                 if(dot(normalDirection,lightDirection) < 0.0){    // light source on the wrong side?
     80                     // no specular reflection
     81                     specularReflection = float3(0.0,0.0,0.0);
     82                 } else {    // light source on the right side
     83                     specularReflection = attenuation * _LightColor0.rgb * _SpecColor.rgb * pow(max(0.0,dot(reflect(-lightDirection,normalDirection),viewDirection)),_Shininess);
     84                 }
     85 
     86                 return float4(ambientLighting + diffuseReflection + specularReflection,1.0);
     87             }
     88 
     89             ENDCG
     90         }
     91         // pass for additional light source
     92         Pass {
     93             Tags { "LightMode" = "ForwardAdd" }
     94 
     95             Blend One One // additive blending
     96 
     97             CGPROGRAM
     98 
     99             #pragma vertex vert
    100             #pragma fragment frag
    101 
    102             #include "UnityCG.cginc"
    103             uniform float4 _LightColor0;    // color of light source(from "Lighting.cginc")
    104 
    105             // User-specified properties
    106             uniform float4 _Color;
    107             uniform float4 _SpecColor;
    108             uniform float _Shininess;
    109 
    110             struct vertexInput {
    111                 float4 vertex:POSITION;
    112                 float3 normal:NORMAL;
    113             };
    114             struct vertexOutput {
    115                 float4 pos:SV_POSITION;
    116                 float4 posWorld:TEXCOORD0;
    117                 float3 normalDir:TEXCOORD1;
    118             };
    119 
    120             vertexOutput vert(vertexInput input){
    121                 vertexOutput output;
    122 
    123                 float4x4 modelMatrix = unity_ObjectToWorld;
    124                 float4x4 modelMatrixInverse = unity_WorldToObject;
    125 
    126                 output.posWorld = mul(modelMatrix,input.vertex);
    127                 output.normalDir = normalize(mul(float4(input.normal,0.0),modelMatrixInverse).xyz);
    128                 output.pos = UnityObjectToClipPos(input.vertex);
    129                 return output;
    130             }
    131 
    132             float4 frag(vertexOutput input):COLOR{
    133                 float3 normalDirection = normalize(input.normalDir);
    134 
    135                 float3 viewDirection = normalize(_WorldSpaceCameraPos - input.posWorld.xyz);
    136                 float3 lightDirection;
    137                 float attenuation;
    138 
    139                 if(_WorldSpaceLightPos0.w == 0.0){    // directional light
    140                     attenuation = 1.0;    // no attenuation
    141                     lightDirection = normalize(_WorldSpaceLightPos0.xyz);
    142                 } else {    // point or spot light
    143                     float3 vertexToLightSource = _WorldSpaceLightPos0.xyz - input.posWorld.xyz;
    144                     float distance = length(vertexToLightSource);
    145                     attenuation = 1.0 / distance;    // linear attenuation
    146                     lightDirection = normalize(vertexToLightSource);
    147                 }
    148 
    149                 float3 diffuseReflection = attenuation * _LightColor0.rgb * _Color.rgb * max(0.0,dot(normalDirection,lightDirection));
    150 
    151                 float3 specularReflection;
    152                 if(dot(normalDirection,lightDirection) < 0.0){    // light source on the wrong side?
    153                     // no specular reflection
    154                     specularReflection = float3(0.0,0.0,0.0);
    155                 } else { // light source on the right side
    156                     specularReflection = attenuation * _LightColor0.rgb * _SpecColor.rgb * pow(max(0.0,dot(reflect(-lightDirection,normalDirection),viewDirection)),_Shininess);
    157                 }
    158                 //no ambient lighting in this pass
    159                 return float4(diffuseReflection + specularReflection,1.0);
    160             }
    161 
    162             ENDCG
    163         }
    164     }
    165 
    166     Fallback "Diffuse"
    167 }
    Per-pixel Lighting

    Two-Sided Smooth Surfaces (about two-sided per-pixel lighting)

      1 // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
      2 // Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
      3 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
      4 
      5 Shader "Custom/Cg two-sided per-pixel lighting" {
      6    Properties {
      7       _Color ("Diffuse Material Color", Color) = (1,1,1,1) 
      8       _SpecColor ("Specular Material Color", Color) = (1,1,1,1) 
      9       _Shininess ("Shininess", Float) = 10
     10       _BackColor ("Back Material Diffuse Color", Color) = (1,1,1,1) 
     11       _BackSpecColor ("Back Material Specular Color", Color) 
     12          = (1,1,1,1) 
     13       _BackShininess ("Back Material Shininess", Float) = 10
     14    }
     15    SubShader {
     16       Pass {    
     17          Tags { "LightMode" = "ForwardBase" } 
     18             // pass for ambient light and first light source
     19          Cull Back // render only front faces
     20  
     21          CGPROGRAM
     22  
     23          #pragma vertex vert  
     24          #pragma fragment frag 
     25  
     26          #include "UnityCG.cginc"
     27          uniform float4 _LightColor0; 
     28             // color of light source (from "Lighting.cginc")
     29  
     30          // User-specified properties
     31          uniform float4 _Color; 
     32          uniform float4 _SpecColor; 
     33          uniform float _Shininess;
     34          uniform float4 _BackColor; 
     35          uniform float4 _BackSpecColor; 
     36          uniform float _BackShininess;
     37  
     38          struct vertexInput {
     39             float4 vertex : POSITION;
     40             float3 normal : NORMAL;
     41          };
     42          struct vertexOutput {
     43             float4 pos : SV_POSITION;
     44             float4 posWorld : TEXCOORD0;
     45             float3 normalDir : TEXCOORD1;
     46          };
     47  
     48          vertexOutput vert(vertexInput input) 
     49          {
     50             vertexOutput output;
     51  
     52             float4x4 modelMatrix = unity_ObjectToWorld;
     53             float4x4 modelMatrixInverse = unity_WorldToObject; 
     54  
     55             output.posWorld = mul(modelMatrix, input.vertex);
     56             output.normalDir = normalize(
     57                mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
     58             output.pos = UnityObjectToClipPos(input.vertex);
     59             return output;
     60          }
     61  
     62          float4 frag(vertexOutput input) : COLOR
     63          {
     64             float3 normalDirection = normalize(input.normalDir);
     65  
     66             float3 viewDirection = normalize(
     67                _WorldSpaceCameraPos - input.posWorld.xyz);
     68             float3 lightDirection;
     69             float attenuation;
     70  
     71             if (0.0 == _WorldSpaceLightPos0.w) // directional light?
     72             {
     73                attenuation = 1.0; // no attenuation
     74                lightDirection = normalize(_WorldSpaceLightPos0.xyz);
     75             } 
     76             else // point or spot light
     77             {
     78                float3 vertexToLightSource = 
     79                   _WorldSpaceLightPos0.xyz - input.posWorld.xyz;
     80                float distance = length(vertexToLightSource);
     81                attenuation = 1.0 / distance; // linear attenuation 
     82                lightDirection = normalize(vertexToLightSource);
     83             }
     84  
     85             float3 ambientLighting = 
     86                UNITY_LIGHTMODEL_AMBIENT.rgb * _Color.rgb;
     87  
     88             float3 diffuseReflection = 
     89                attenuation * _LightColor0.rgb * _Color.rgb
     90                * max(0.0, dot(normalDirection, lightDirection));
     91  
     92             float3 specularReflection;
     93             if (dot(normalDirection, lightDirection) < 0.0) 
     94                // light source on the wrong side?
     95             {
     96                specularReflection = float3(0.0, 0.0, 0.0); 
     97                   // no specular reflection
     98             }
     99             else // light source on the right side
    100             {
    101                specularReflection = attenuation * _LightColor0.rgb 
    102                   * _SpecColor.rgb * pow(max(0.0, dot(
    103                   reflect(-lightDirection, normalDirection), 
    104                   viewDirection)), _Shininess);
    105             }
    106  
    107             return float4(ambientLighting + diffuseReflection 
    108                + specularReflection, 1.0);
    109          }
    110  
    111          ENDCG
    112       }
    113  
    114       Pass {    
    115          Tags { "LightMode" = "ForwardAdd" } 
    116             // pass for additional light sources
    117          Blend One One // additive blending 
    118          Cull Back // render only front faces
    119  
    120          CGPROGRAM
    121  
    122          #pragma vertex vert  
    123          #pragma fragment frag 
    124  
    125          #include "UnityCG.cginc"
    126          uniform float4 _LightColor0; 
    127             // color of light source (from "Lighting.cginc")
    128  
    129          // User-specified properties
    130          uniform float4 _Color; 
    131          uniform float4 _SpecColor; 
    132          uniform float _Shininess;
    133          uniform float4 _BackColor; 
    134          uniform float4 _BackSpecColor; 
    135          uniform float _BackShininess;
    136  
    137          struct vertexInput {
    138             float4 vertex : POSITION;
    139             float3 normal : NORMAL;
    140          };
    141          struct vertexOutput {
    142             float4 pos : SV_POSITION;
    143             float4 posWorld : TEXCOORD0;
    144             float3 normalDir : TEXCOORD1;
    145          };
    146  
    147          vertexOutput vert(vertexInput input) 
    148          {
    149             vertexOutput output;
    150  
    151             float4x4 modelMatrix = unity_ObjectToWorld;
    152             float4x4 modelMatrixInverse = unity_WorldToObject; 
    153  
    154             output.posWorld = mul(modelMatrix, input.vertex);
    155             output.normalDir = normalize(
    156                mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
    157             output.pos = UnityObjectToClipPos(input.vertex);
    158             return output;
    159          }
    160  
    161          float4 frag(vertexOutput input) : COLOR
    162          {
    163             float3 normalDirection = normalize(input.normalDir);
    164  
    165             float3 viewDirection = normalize(
    166                _WorldSpaceCameraPos - input.posWorld.xyz);
    167             float3 lightDirection;
    168             float attenuation;
    169  
    170             if (0.0 == _WorldSpaceLightPos0.w) // directional light?
    171             {
    172                attenuation = 1.0; // no attenuation
    173                lightDirection = normalize(_WorldSpaceLightPos0.xyz);
    174             } 
    175             else // point or spot light
    176             {
    177                float3 vertexToLightSource = 
    178                   _WorldSpaceLightPos0.xyz - input.posWorld.xyz;
    179                float distance = length(vertexToLightSource);
    180                attenuation = 1.0 / distance; // linear attenuation 
    181                lightDirection = normalize(vertexToLightSource);
    182             }
    183  
    184             float3 diffuseReflection = 
    185                attenuation * _LightColor0.rgb * _Color.rgb
    186                * max(0.0, dot(normalDirection, lightDirection));
    187  
    188             float3 specularReflection;
    189             if (dot(normalDirection, lightDirection) < 0.0) 
    190                // light source on the wrong side?
    191             {
    192                specularReflection = float3(0.0, 0.0, 0.0); 
    193                   // no specular reflection
    194             }
    195             else // light source on the right side
    196             {
    197                specularReflection = attenuation * _LightColor0.rgb 
    198                   * _SpecColor.rgb * pow(max(0.0, dot(
    199                   reflect(-lightDirection, normalDirection), 
    200                   viewDirection)), _Shininess);
    201             }
    202  
    203             return float4(diffuseReflection 
    204                + specularReflection, 1.0);
    205                // no ambient lighting in this pass
    206          }
    207  
    208          ENDCG
    209       }
    210  
    211       Pass {    
    212          Tags { "LightMode" = "ForwardBase" } 
    213             // pass for ambient light and first light source
    214          Cull Front // render only back faces
    215  
    216          CGPROGRAM
    217  
    218          #pragma vertex vert  
    219          #pragma fragment frag 
    220  
    221          #include "UnityCG.cginc"
    222          uniform float4 _LightColor0; 
    223             // color of light source (from "Lighting.cginc")
    224  
    225          // User-specified properties
    226          uniform float4 _Color; 
    227          uniform float4 _SpecColor; 
    228          uniform float _Shininess;
    229          uniform float4 _BackColor; 
    230          uniform float4 _BackSpecColor; 
    231          uniform float _BackShininess;
    232  
    233          struct vertexInput {
    234             float4 vertex : POSITION;
    235             float3 normal : NORMAL;
    236          };
    237          struct vertexOutput {
    238             float4 pos : SV_POSITION;
    239             float4 posWorld : TEXCOORD0;
    240             float3 normalDir : TEXCOORD1;
    241          };
    242  
    243          vertexOutput vert(vertexInput input) 
    244          {
    245             vertexOutput output;
    246  
    247             float4x4 modelMatrix = unity_ObjectToWorld;
    248             float4x4 modelMatrixInverse = unity_WorldToObject; 
    249  
    250             output.posWorld = mul(modelMatrix, input.vertex);
    251             output.normalDir = normalize(
    252                mul(float4(-input.normal, 0.0), modelMatrixInverse).xyz);
    253             output.pos = UnityObjectToClipPos(input.vertex);
    254             return output;
    255          }
    256  
    257          float4 frag(vertexOutput input) : COLOR
    258          {
    259             float3 normalDirection = normalize(input.normalDir);
    260  
    261             float3 viewDirection = normalize(
    262                _WorldSpaceCameraPos - input.posWorld.xyz);
    263             float3 lightDirection;
    264             float attenuation;
    265  
    266             if (0.0 == _WorldSpaceLightPos0.w) // directional light?
    267             {
    268                attenuation = 1.0; // no attenuation
    269                lightDirection = normalize(_WorldSpaceLightPos0.xyz);
    270             } 
    271             else // point or spot light
    272             {
    273                float3 vertexToLightSource = 
    274                   _WorldSpaceLightPos0.xyz - input.posWorld.xyz;
    275                float distance = length(vertexToLightSource);
    276                attenuation = 1.0 / distance; // linear attenuation 
    277                lightDirection = normalize(vertexToLightSource);
    278             }
    279  
    280             float3 ambientLighting = 
    281                UNITY_LIGHTMODEL_AMBIENT.rgb * _BackColor.rgb;
    282  
    283             float3 diffuseReflection = 
    284                attenuation * _LightColor0.rgb * _BackColor.rgb
    285                * max(0.0, dot(normalDirection, lightDirection));
    286  
    287             float3 specularReflection;
    288             if (dot(normalDirection, lightDirection) < 0.0) 
    289                // light source on the wrong side?
    290             {
    291                specularReflection = float3(0.0, 0.0, 0.0); 
    292                   // no specular reflection
    293             }
    294             else // light source on the right side
    295             {
    296                specularReflection = attenuation * _LightColor0.rgb 
    297                   * _BackSpecColor.rgb * pow(max(0.0, dot(
    298                   reflect(-lightDirection, normalDirection), 
    299                   viewDirection)), _BackShininess);
    300             }
    301  
    302             return float4(ambientLighting + diffuseReflection 
    303                + specularReflection, 1.0);
    304          }
    305  
    306          ENDCG
    307       }
    308  
    309       Pass {    
    310          Tags { "LightMode" = "ForwardAdd" } 
    311             // pass for additional light sources
    312          Blend One One // additive blending 
    313          Cull Front // render only back faces
    314  
    315          CGPROGRAM
    316  
    317          #pragma vertex vert  
    318          #pragma fragment frag 
    319  
    320          #include "UnityCG.cginc"
    321          uniform float4 _LightColor0; 
    322             // color of light source (from "Lighting.cginc")
    323  
    324          // User-specified properties
    325          uniform float4 _Color; 
    326          uniform float4 _SpecColor; 
    327          uniform float _Shininess;
    328          uniform float4 _BackColor; 
    329          uniform float4 _BackSpecColor; 
    330          uniform float _BackShininess;
    331  
    332          struct vertexInput {
    333             float4 vertex : POSITION;
    334             float3 normal : NORMAL;
    335          };
    336          struct vertexOutput {
    337             float4 pos : SV_POSITION;
    338             float4 posWorld : TEXCOORD0;
    339             float3 normalDir : TEXCOORD1;
    340          };
    341  
    342          vertexOutput vert(vertexInput input) 
    343          {
    344             vertexOutput output;
    345  
    346             float4x4 modelMatrix = unity_ObjectToWorld;
    347             float4x4 modelMatrixInverse = unity_WorldToObject; 
    348  
    349             output.posWorld = mul(modelMatrix, input.vertex);
    350             output.normalDir = normalize(
    351                mul(float4(-input.normal, 0.0), modelMatrixInverse).xyz);
    352             output.pos = UnityObjectToClipPos(input.vertex);
    353             return output;
    354          }
    355  
    356          float4 frag(vertexOutput input) : COLOR
    357          {
    358             float3 normalDirection = normalize(input.normalDir);
    359  
    360             float3 viewDirection = normalize(
    361                _WorldSpaceCameraPos - input.posWorld.xyz);
    362             float3 lightDirection;
    363             float attenuation;
    364  
    365             if (0.0 == _WorldSpaceLightPos0.w) // directional light?
    366             {
    367                attenuation = 1.0; // no attenuation
    368                lightDirection = normalize(_WorldSpaceLightPos0.xyz);
    369             } 
    370             else // point or spot light
    371             {
    372                float3 vertexToLightSource = 
    373                   _WorldSpaceLightPos0.xyz - input.posWorld.xyz;
    374                float distance = length(vertexToLightSource);
    375                attenuation = 1.0 / distance; // linear attenuation 
    376                lightDirection = normalize(vertexToLightSource);
    377             }
    378  
    379             float3 diffuseReflection = 
    380                attenuation * _LightColor0.rgb * _BackColor.rgb
    381                * max(0.0, dot(normalDirection, lightDirection));
    382  
    383             float3 specularReflection;
    384             if (dot(normalDirection, lightDirection) < 0.0) 
    385                // light source on the wrong side?
    386             {
    387                specularReflection = float3(0.0, 0.0, 0.0); 
    388                   // no specular reflection
    389             }
    390             else // light source on the right side
    391             {
    392                specularReflection = attenuation * _LightColor0.rgb 
    393                   * _BackSpecColor.rgb * pow(max(0.0, dot(
    394                   reflect(-lightDirection, normalDirection), 
    395                   viewDirection)), _BackShininess);
    396             }
    397  
    398             return float4(diffuseReflection 
    399                + specularReflection, 1.0);
    400                // no ambient lighting in this pass
    401          }
    402  
    403          ENDCG
    404       }
    405  
    406    }
    407    Fallback "Specular"
    408 }
    Two-sided per-pixel lighting

    Multiple Lights (about for-loops for handling multiple light sources in one shader pass)

      1 // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
      2 // Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
      3 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
      4 
      5 Shader "Custom/Cg per-pixel lighting with vertex lights" {
      6    Properties {
      7       _Color ("Diffuse Material Color", Color) = (1,1,1,1) 
      8       _SpecColor ("Specular Material Color", Color) = (1,1,1,1) 
      9       _Shininess ("Shininess", Float) = 10
     10    }
     11    SubShader {
     12       Pass {      
     13          Tags { "LightMode" = "ForwardBase" } // pass for 
     14             // 4 vertex lights, ambient light & first pixel light
     15  
     16          CGPROGRAM
     17          #pragma multi_compile_fwdbase 
     18          #pragma vertex vert
     19          #pragma fragment frag
     20  
     21          #include "UnityCG.cginc" 
     22          uniform float4 _LightColor0; 
     23             // color of light source (from "Lighting.cginc")
     24  
     25          // User-specified properties
     26          uniform float4 _Color; 
     27          uniform float4 _SpecColor; 
     28          uniform float _Shininess;
     29  
     30          struct vertexInput {
     31             float4 vertex : POSITION;
     32             float3 normal : NORMAL;
     33          };
     34          struct vertexOutput {
     35             float4 pos : SV_POSITION;
     36             float4 posWorld : TEXCOORD0;
     37             float3 normalDir : TEXCOORD1;
     38             float3 vertexLighting : TEXCOORD2;
     39          };
     40  
     41          vertexOutput vert(vertexInput input)
     42          {          
     43             vertexOutput output;
     44  
     45             float4x4 modelMatrix = unity_ObjectToWorld;
     46             float4x4 modelMatrixInverse = unity_WorldToObject; 
     47  
     48             output.posWorld = mul(modelMatrix, input.vertex);
     49             output.normalDir = normalize(
     50                mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
     51             output.pos = UnityObjectToClipPos(input.vertex);
     52  
     53             // Diffuse reflection by four "vertex lights"            
     54             output.vertexLighting = float3(0.0, 0.0, 0.0);
     55             #ifdef VERTEXLIGHT_ON
     56             for (int index = 0; index < 4; index++)
     57             {    
     58                float4 lightPosition = float4(unity_4LightPosX0[index], 
     59                   unity_4LightPosY0[index], 
     60                   unity_4LightPosZ0[index], 1.0);
     61  
     62                float3 vertexToLightSource = 
     63                   lightPosition.xyz - output.posWorld.xyz;        
     64                float3 lightDirection = normalize(vertexToLightSource);
     65                float squaredDistance = 
     66                   dot(vertexToLightSource, vertexToLightSource);
     67                float attenuation = 1.0 / (1.0 + 
     68                   unity_4LightAtten0[index] * squaredDistance);
     69                float3 diffuseReflection = attenuation 
     70                   * unity_LightColor[index].rgb * _Color.rgb 
     71                   * max(0.0, dot(output.normalDir, lightDirection));         
     72  
     73                output.vertexLighting = 
     74                   output.vertexLighting + diffuseReflection;
     75             }
     76             #endif
     77             return output;
     78          }
     79  
     80          float4 frag(vertexOutput input) : COLOR
     81          {
     82             float3 normalDirection = normalize(input.normalDir); 
     83             float3 viewDirection = normalize(
     84                _WorldSpaceCameraPos - input.posWorld.xyz);
     85             float3 lightDirection;
     86             float attenuation;
     87  
     88             if (0.0 == _WorldSpaceLightPos0.w) // directional light?
     89             {
     90                attenuation = 1.0; // no attenuation
     91                lightDirection = 
     92                   normalize(_WorldSpaceLightPos0.xyz);
     93             } 
     94             else // point or spot light
     95             {
     96                float3 vertexToLightSource = 
     97                   _WorldSpaceLightPos0.xyz - input.posWorld.xyz;
     98                float distance = length(vertexToLightSource);
     99                attenuation = 1.0 / distance; // linear attenuation 
    100                lightDirection = normalize(vertexToLightSource);
    101             }
    102  
    103             float3 ambientLighting = 
    104                 UNITY_LIGHTMODEL_AMBIENT.rgb * _Color.rgb;
    105  
    106             float3 diffuseReflection = 
    107                attenuation * _LightColor0.rgb * _Color.rgb 
    108                * max(0.0, dot(normalDirection, lightDirection));
    109  
    110             float3 specularReflection;
    111             if (dot(normalDirection, lightDirection) < 0.0) 
    112                // light source on the wrong side?
    113             {
    114                specularReflection = float3(0.0, 0.0, 0.0); 
    115                   // no specular reflection
    116             }
    117             else // light source on the right side
    118             {
    119                specularReflection = attenuation * _LightColor0.rgb 
    120                   * _SpecColor.rgb * pow(max(0.0, dot(
    121                   reflect(-lightDirection, normalDirection), 
    122                   viewDirection)), _Shininess);
    123             }
    124  
    125             return float4(input.vertexLighting + ambientLighting 
    126                + diffuseReflection + specularReflection, 1.0);
    127          }
    128          ENDCG
    129       }
    130  
    131       Pass {    
    132          Tags { "LightMode" = "ForwardAdd" } 
    133             // pass for additional light sources
    134          Blend One One // additive blending 
    135  
    136           CGPROGRAM
    137  
    138          #pragma vertex vert  
    139          #pragma fragment frag 
    140  
    141          #include "UnityCG.cginc" 
    142          uniform float4 _LightColor0; 
    143             // color of light source (from "Lighting.cginc")
    144  
    145          // User-specified properties
    146          uniform float4 _Color; 
    147          uniform float4 _SpecColor; 
    148          uniform float _Shininess;
    149  
    150          struct vertexInput {
    151             float4 vertex : POSITION;
    152             float3 normal : NORMAL;
    153          };
    154          struct vertexOutput {
    155             float4 pos : SV_POSITION;
    156             float4 posWorld : TEXCOORD0;
    157             float3 normalDir : TEXCOORD1;
    158          };
    159  
    160          vertexOutput vert(vertexInput input) 
    161          {
    162             vertexOutput output;
    163  
    164             float4x4 modelMatrix = unity_ObjectToWorld;
    165             float4x4 modelMatrixInverse = unity_WorldToObject; 
    166  
    167             output.posWorld = mul(modelMatrix, input.vertex);
    168             output.normalDir = normalize(
    169                mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
    170             output.pos = UnityObjectToClipPos(input.vertex);
    171             return output;
    172          }
    173  
    174          float4 frag(vertexOutput input) : COLOR
    175          {
    176             float3 normalDirection = normalize(input.normalDir);
    177  
    178             float3 viewDirection = normalize(
    179                _WorldSpaceCameraPos.xyz - input.posWorld.xyz);
    180             float3 lightDirection;
    181             float attenuation;
    182  
    183             if (0.0 == _WorldSpaceLightPos0.w) // directional light?
    184             {
    185                attenuation = 1.0; // no attenuation
    186                lightDirection = 
    187                   normalize(_WorldSpaceLightPos0.xyz);
    188             } 
    189             else // point or spot light
    190             {
    191                float3 vertexToLightSource = 
    192                   _WorldSpaceLightPos0.xyz - input.posWorld.xyz;
    193                float distance = length(vertexToLightSource);
    194                attenuation = 1.0 / distance; // linear attenuation 
    195                lightDirection = normalize(vertexToLightSource);
    196             }
    197  
    198             float3 diffuseReflection = 
    199                attenuation * _LightColor0.rgb * _Color.rgb
    200                * max(0.0, dot(normalDirection, lightDirection));
    201  
    202             float3 specularReflection;
    203             if (dot(normalDirection, lightDirection) < 0.0) 
    204                // light source on the wrong side?
    205             {
    206                specularReflection = float3(0.0, 0.0, 0.0); 
    207                   // no specular reflection
    208             }
    209             else // light source on the right side
    210             {
    211                specularReflection = attenuation * _LightColor0.rgb 
    212                   * _SpecColor.rgb * pow(max(0.0, dot(
    213                   reflect(-lightDirection, normalDirection), 
    214                   viewDirection)), _Shininess);
    215             }
    216  
    217             return float4(diffuseReflection 
    218                + specularReflection, 1.0);
    219                // no ambient lighting in this pass
    220          }
    221  
    222          ENDCG
    223       }
    224  
    225    } 
    226    Fallback "Specular"
    227 }
    Per-pixel lighting with vertex lights

    Basic Texturing

    Textured Spheres (about texturing a sphere)

     1 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
     2 
     3 Shader "Custom/Cg shader with single texture" {
     4    Properties {
     5       _MainTex ("Texture Image", 2D) = "white" {} 
     6          // a 2D texture property that we call "_MainTex", which should
     7          // be labeled "Texture Image" in Unity's user interface.
     8          // By default we use the built-in texture "white"  
     9          // (alternatives: "black", "gray" and "bump").
    10    }
    11    SubShader {
    12       Pass {    
    13          CGPROGRAM
    14  
    15          #pragma vertex vert  
    16          #pragma fragment frag 
    17  
    18          uniform sampler2D _MainTex;    
    19             // a uniform variable refering to the property above
    20             // (in fact, this is just a small integer specifying a 
    21             // "texture unit", which has the texture image "bound" 
    22             // to it; Unity takes care of this).
    23  
    24          struct vertexInput {
    25             float4 vertex : POSITION;
    26             float4 texcoord : TEXCOORD0;
    27          };
    28          struct vertexOutput {
    29             float4 pos : SV_POSITION;
    30             float4 tex : TEXCOORD0;
    31          };
    32  
    33          vertexOutput vert(vertexInput input) 
    34          {
    35             vertexOutput output;
    36  
    37             output.tex = input.texcoord;
    38                // Unity provides default longitude-latitude-like 
    39                // texture coordinates at all vertices of a 
    40                // sphere mesh as the input parameter 
    41                // "input.texcoord" with semantic "TEXCOORD0".
    42             output.pos = UnityObjectToClipPos(input.vertex);
    43             return output;
    44          }
    45          float4 frag(vertexOutput input) : COLOR
    46          {
    47             return tex2D(_MainTex, input.tex.xy);    
    48                // look up the color of the texture image specified by 
    49                // the uniform "_MainTex" at the position specified by 
    50                // "input.tex.x" and "input.tex.y" and return it
    51  
    52          }
    53  
    54          ENDCG
    55       }
    56    }
    57    Fallback "Unlit/Texture"
    58 }
    Shader with single texture

    Lighting Textured Surfaces (about textures for diffuse lighting)

      1 // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
      2 // Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
      3 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
      4 
      5 Shader "Custom/Cg per-vertex lighting with texture" {
      6    Properties {
      7       _MainTex ("Texture For Diffuse Material Color", 2D) = "white" {} 
      8       _Color ("Overall Diffuse Color Filter", Color) = (1,1,1,1)
      9       _SpecColor ("Specular Material Color", Color) = (1,1,1,1) 
     10       _Shininess ("Shininess", Float) = 10
     11    }
     12    SubShader {
     13       Pass {    
     14          Tags { "LightMode" = "ForwardBase" } 
     15             // pass for ambient light and first light source
     16  
     17          CGPROGRAM
     18  
     19          #pragma vertex vert  
     20          #pragma fragment frag
     21  
     22          #include "UnityCG.cginc" 
     23          uniform float4 _LightColor0; 
     24             // color of light source (from "Lighting.cginc")
     25  
     26          // User-specified properties
     27          uniform sampler2D _MainTex;    
     28          uniform float4 _Color; 
     29          uniform float4 _SpecColor; 
     30          uniform float _Shininess;
     31  
     32          struct vertexInput {
     33             float4 vertex : POSITION;
     34             float3 normal : NORMAL;
     35             float4 texcoord : TEXCOORD0;
     36          };
     37          struct vertexOutput {
     38             float4 pos : SV_POSITION;
     39             float4 tex : TEXCOORD0;
     40             float3 diffuseColor : TEXCOORD1;
     41             float3 specularColor : TEXCOORD2;
     42          };
     43  
     44          vertexOutput vert(vertexInput input) 
     45          {
     46             vertexOutput output;
     47  
     48             float4x4 modelMatrix = unity_ObjectToWorld;
     49             float4x4 modelMatrixInverse = unity_WorldToObject; 
     50  
     51             float3 normalDirection = normalize(
     52                mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
     53             float3 viewDirection = normalize(_WorldSpaceCameraPos 
     54                - mul(modelMatrix, input.vertex).xyz);
     55             float3 lightDirection;
     56             float attenuation;
     57  
     58             if (0.0 == _WorldSpaceLightPos0.w) // directional light?
     59             {
     60                attenuation = 1.0; // no attenuation
     61                lightDirection = normalize(_WorldSpaceLightPos0.xyz);
     62             } 
     63             else // point or spot light
     64             {
     65                float3 vertexToLightSource = _WorldSpaceLightPos0.xyz
     66                   - mul(modelMatrix, input.vertex).xyz;
     67                float distance = length(vertexToLightSource);
     68                attenuation = 1.0 / distance; // linear attenuation 
     69                lightDirection = normalize(vertexToLightSource);
     70             }
     71  
     72             float3 ambientLighting = 
     73                UNITY_LIGHTMODEL_AMBIENT.rgb * _Color.rgb;
     74  
     75             float3 diffuseReflection = 
     76                attenuation * _LightColor0.rgb * _Color.rgb
     77                * max(0.0, dot(normalDirection, lightDirection));
     78  
     79             float3 specularReflection;
     80             if (dot(normalDirection, lightDirection) < 0.0) 
     81                // light source on the wrong side?
     82             {
     83                specularReflection = float3(0.0, 0.0, 0.0); 
     84                   // no specular reflection
     85             }
     86             else // light source on the right side
     87             {
     88                specularReflection = attenuation * _LightColor0.rgb 
     89                   * _SpecColor.rgb * pow(max(0.0, dot(
     90                   reflect(-lightDirection, normalDirection), 
     91                   viewDirection)), _Shininess);
     92             }
     93  
     94             output.diffuseColor = ambientLighting + diffuseReflection;
     95             output.specularColor = specularReflection;
     96             output.tex = input.texcoord;
     97             output.pos = UnityObjectToClipPos(input.vertex);
     98             return output;
     99          }
    100  
    101          float4 frag(vertexOutput input) : COLOR
    102          {
    103             return float4(input.specularColor +
    104                input.diffuseColor * tex2D(_MainTex, input.tex.xy),
    105                1.0);
    106          }
    107  
    108          ENDCG
    109       }
    110  
    111       Pass {    
    112          Tags { "LightMode" = "ForwardAdd" } 
    113             // pass for additional light sources
    114          Blend One One // additive blending 
    115  
    116          CGPROGRAM
    117  
    118          #pragma vertex vert  
    119          #pragma fragment frag 
    120  
    121          #include "UnityCG.cginc" 
    122          uniform float4 _LightColor0; 
    123             // color of light source (from "Lighting.cginc")
    124  
    125          // User-specified properties
    126          uniform sampler2D _MainTex;    
    127          uniform float4 _Color; 
    128          uniform float4 _SpecColor; 
    129          uniform float _Shininess;
    130  
    131          struct vertexInput {
    132             float4 vertex : POSITION;
    133             float3 normal : NORMAL;
    134             float4 texcoord : TEXCOORD0;
    135          };
    136          struct vertexOutput {
    137             float4 pos : SV_POSITION;
    138             float4 tex : TEXCOORD0;
    139             float3 diffuseColor : TEXCOORD1;
    140             float3 specularColor : TEXCOORD2;
    141          };
    142  
    143          vertexOutput vert(vertexInput input) 
    144          {
    145             vertexOutput output;
    146  
    147             float4x4 modelMatrix = unity_ObjectToWorld;
    148             float4x4 modelMatrixInverse = unity_WorldToObject;
    149  
    150             float3 normalDirection = normalize(
    151                mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
    152             float3 viewDirection = normalize(_WorldSpaceCameraPos 
    153                - mul(modelMatrix, input.vertex).xyz);
    154             float3 lightDirection;
    155             float attenuation;
    156  
    157             if (0.0 == _WorldSpaceLightPos0.w) // directional light?
    158             {
    159                attenuation = 1.0; // no attenuation
    160                lightDirection = normalize(_WorldSpaceLightPos0.xyz);
    161             } 
    162             else // point or spot light
    163             {
    164                float3 vertexToLightSource = _WorldSpaceLightPos0.xyz
    165                   - mul(modelMatrix, input.vertex).xyz;
    166                float distance = length(vertexToLightSource);
    167                attenuation = 1.0 / distance; // linear attenuation 
    168                lightDirection = normalize(vertexToLightSource);
    169             }
    170  
    171             float3 diffuseReflection = 
    172                attenuation * _LightColor0.rgb * _Color.rgb
    173                * max(0.0, dot(normalDirection, lightDirection));
    174  
    175             float3 specularReflection;
    176             if (dot(normalDirection, lightDirection) < 0.0) 
    177                // light source on the wrong side?
    178             {
    179                specularReflection = float3(0.0, 0.0, 0.0); 
    180                   // no specular reflection
    181             }
    182             else // light source on the right side
    183             {
    184                specularReflection = attenuation * _LightColor0.rgb 
    185                   * _SpecColor.rgb * pow(max(0.0, dot(
    186                   reflect(-lightDirection, normalDirection), 
    187                   viewDirection)), _Shininess);
    188             }
    189  
    190             output.diffuseColor = diffuseReflection; // no ambient
    191             output.specularColor = specularReflection;
    192             output.tex = input.texcoord;
    193             output.pos = UnityObjectToClipPos(input.vertex);
    194             return output;
    195          }
    196  
    197          float4 frag(vertexOutput input) : COLOR
    198          {
    199             return float4(input.specularColor +
    200                input.diffuseColor * tex2D(_MainTex, input.tex.xy),
    201                1.0);
    202          }
    203  
    204          ENDCG
    205       }
    206    }
    207    Fallback "Specular"
    208 }
    Per-vertex lighting with texture

    Glossy Textures (about gloss mapping)

      1 // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
      2 // Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
      3 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
      4 
      5 Shader "Custom/Cg per-pixel lighting with texture" {
      6    Properties {
      7       _MainTex ("RGBA Texture For Material Color", 2D) = "white" {} 
      8       _Color ("Diffuse Material Color", Color) = (1,1,1,1) 
      9       _SpecColor ("Specular Material Color", Color) = (1,1,1,1) 
     10       _Shininess ("Shininess", Float) = 10
     11    }
     12    SubShader {
     13       Pass {    
     14          Tags { "LightMode" = "ForwardBase" } 
     15             // pass for ambient light and first light source
     16  
     17          CGPROGRAM
     18  
     19          #pragma vertex vert  
     20          #pragma fragment frag 
     21  
     22          #include "UnityCG.cginc"
     23          uniform float4 _LightColor0; 
     24             // color of light source (from "Lighting.cginc")
     25  
     26          // User-specified properties
     27          uniform sampler2D _MainTex;    
     28          uniform float4 _Color; 
     29          uniform float4 _SpecColor; 
     30          uniform float _Shininess;
     31  
     32          struct vertexInput {
     33             float4 vertex : POSITION;
     34             float3 normal : NORMAL;
     35             float4 texcoord : TEXCOORD0;
     36         };
     37          struct vertexOutput {
     38             float4 pos : SV_POSITION;
     39             float4 posWorld : TEXCOORD0;
     40             float3 normalDir : TEXCOORD1;
     41             float4 tex : TEXCOORD2;
     42         };
     43  
     44          vertexOutput vert(vertexInput input) 
     45          {
     46             vertexOutput output;
     47  
     48             float4x4 modelMatrix = unity_ObjectToWorld;
     49             float4x4 modelMatrixInverse = unity_WorldToObject;
     50  
     51             output.posWorld = mul(modelMatrix, input.vertex);
     52             output.normalDir = normalize(
     53                mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
     54             output.tex = input.texcoord;
     55             output.pos = UnityObjectToClipPos(input.vertex);
     56             return output;
     57          }
     58  
     59          float4 frag(vertexOutput input) : COLOR
     60          {
     61             float3 normalDirection = normalize(input.normalDir);
     62  
     63             float3 viewDirection = normalize(
     64                _WorldSpaceCameraPos - input.posWorld.xyz);
     65             float3 lightDirection;
     66             float attenuation;
     67  
     68             float4 textureColor = tex2D(_MainTex, input.tex.xy);
     69  
     70             if (0.0 == _WorldSpaceLightPos0.w) // directional light?
     71             {
     72                attenuation = 1.0; // no attenuation
     73                lightDirection = 
     74                   normalize(_WorldSpaceLightPos0.xyz);
     75             } 
     76             else // point or spot light
     77             {
     78                float3 vertexToLightSource = 
     79                   _WorldSpaceLightPos0.xyz - input.posWorld.xyz;
     80                float distance = length(vertexToLightSource);
     81                attenuation = 1.0 / distance; // linear attenuation 
     82                lightDirection = normalize(vertexToLightSource);
     83             }
     84  
     85             float3 ambientLighting = textureColor.rgb  
     86                * UNITY_LIGHTMODEL_AMBIENT.rgb * _Color.rgb;
     87  
     88             float3 diffuseReflection = textureColor.rgb  
     89                * attenuation * _LightColor0.rgb * _Color.rgb
     90                * max(0.0, dot(normalDirection, lightDirection));
     91  
     92             float3 specularReflection;
     93             if (dot(normalDirection, lightDirection) < 0.0) 
     94                // light source on the wrong side?
     95             {
     96                specularReflection = float3(0.0, 0.0, 0.0); 
     97                   // no specular reflection
     98             }
     99             else // light source on the right side
    100             {
    101                specularReflection = attenuation * _LightColor0.rgb 
    102                   * _SpecColor.rgb * (1.0 - textureColor.a) 
    103                      // for usual gloss maps: "... * textureColor.a" 
    104                   * pow(max(0.0, dot(
    105                   reflect(-lightDirection, normalDirection), 
    106                   viewDirection)), _Shininess);
    107             }
    108  
    109             return float4(ambientLighting + diffuseReflection 
    110                + specularReflection, 1.0);
    111          }
    112  
    113          ENDCG
    114       }
    115  
    116       Pass {    
    117          Tags { "LightMode" = "ForwardAdd" } 
    118             // pass for additional light sources
    119          Blend One One // additive blending 
    120  
    121           CGPROGRAM
    122  
    123          #pragma vertex vert  
    124          #pragma fragment frag 
    125  
    126          #include "UnityCG.cginc"
    127          uniform float4 _LightColor0; 
    128             // color of light source (from "Lighting.cginc")
    129  
    130          // User-specified properties
    131          uniform sampler2D _MainTex;    
    132          uniform float4 _Color; 
    133          uniform float4 _SpecColor; 
    134          uniform float _Shininess;
    135  
    136         struct vertexInput {
    137             float4 vertex : POSITION;
    138             float3 normal : NORMAL;
    139             float4 texcoord : TEXCOORD0;
    140         };
    141          struct vertexOutput {
    142             float4 pos : SV_POSITION;
    143             float4 posWorld : TEXCOORD0;
    144             float3 normalDir : TEXCOORD1;
    145             float4 tex : TEXCOORD2;
    146         };
    147  
    148          vertexOutput vert(vertexInput input) 
    149          {
    150             vertexOutput output;
    151  
    152             float4x4 modelMatrix = unity_ObjectToWorld;
    153             float4x4 modelMatrixInverse = unity_WorldToObject;
    154  
    155             output.posWorld = mul(modelMatrix, input.vertex);
    156             output.normalDir = normalize(
    157                mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
    158             output.tex = input.texcoord;
    159             output.pos = UnityObjectToClipPos(input.vertex);
    160             return output;
    161          }
    162  
    163          float4 frag(vertexOutput input) : COLOR
    164          {
    165             float3 normalDirection = normalize(input.normalDir);
    166  
    167             float3 viewDirection = normalize(
    168                _WorldSpaceCameraPos - input.posWorld.xyz);
    169             float3 lightDirection;
    170             float attenuation;
    171  
    172             float4 textureColor = tex2D(_MainTex, input.tex.xy);
    173  
    174             if (0.0 == _WorldSpaceLightPos0.w) // directional light?
    175             {
    176                attenuation = 1.0; // no attenuation
    177                lightDirection = 
    178                   normalize(_WorldSpaceLightPos0.xyz);
    179             } 
    180             else // point or spot light
    181             {
    182                float3 vertexToLightSource = 
    183                   _WorldSpaceLightPos0.xyz - input.posWorld.xyz;
    184                float distance = length(vertexToLightSource);
    185                attenuation = 1.0 / distance; // linear attenuation 
    186                lightDirection = normalize(vertexToLightSource);
    187             }
    188  
    189             float3 diffuseReflection = textureColor.rgb  
    190                * attenuation * _LightColor0.rgb * _Color.rgb
    191                * max(0.0, dot(normalDirection, lightDirection));
    192  
    193             float3 specularReflection;
    194             if (dot(normalDirection, lightDirection) < 0.0) 
    195                // light source on the wrong side?
    196             {
    197                specularReflection = float3(0.0, 0.0, 0.0); 
    198                   // no specular reflection
    199             }
    200             else // light source on the right side
    201             {
    202                specularReflection = attenuation * _LightColor0.rgb 
    203                   * _SpecColor.rgb * (1.0 - textureColor.a) 
    204                      // for usual gloss maps: "... * textureColor.a" 
    205                   * pow(max(0.0, dot(
    206                   reflect(-lightDirection, normalDirection), 
    207                   viewDirection)), _Shininess);
    208             }
    209  
    210             return float4(diffuseReflection 
    211                + specularReflection, 1.0);
    212                // no ambient lighting in this pass
    213          }
    214  
    215          ENDCG
    216       }
    217    }
    218    Fallback "Specular"
    219 }
    Per-pixel lighting with texture

    Transparent Textures (about using alpha textures for discarding fragments, alpha testing, and blending)

     1 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
     2 
     3 Shader "Custom/Cg texturing with alpha discard" {
     4    Properties {
     5       _MainTex ("RGBA Texture Image", 2D) = "white" {} 
     6       _Cutoff ("Alpha Cutoff", Float) = 0.5
     7    }
     8    SubShader {
     9       Pass {    
    10          Cull Off // since the front is partially transparent, 
    11             // we shouldn't cull the back
    12 
    13          CGPROGRAM
    14  
    15          #pragma vertex vert  
    16          #pragma fragment frag 
    17  
    18          uniform sampler2D _MainTex;    
    19          uniform float _Cutoff;
    20  
    21          struct vertexInput {
    22             float4 vertex : POSITION;
    23             float4 texcoord : TEXCOORD0;
    24          };
    25          struct vertexOutput {
    26             float4 pos : SV_POSITION;
    27             float4 tex : TEXCOORD0;
    28          };
    29  
    30          vertexOutput vert(vertexInput input) 
    31          {
    32             vertexOutput output;
    33  
    34             output.tex = input.texcoord;
    35             output.pos = UnityObjectToClipPos(input.vertex);
    36             return output;
    37          }
    38 
    39          float4 frag(vertexOutput input) : COLOR
    40          {
    41             float4 textureColor = tex2D(_MainTex, input.tex.xy);  
    42             if (textureColor.a < _Cutoff)
    43                // alpha value less than user-specified threshold?
    44             {
    45                discard; // yes: discard this fragment
    46             }
    47             return textureColor;
    48          }
    49  
    50          ENDCG
    51       }
    52    }
    53    Fallback "Unlit/Transparent Cutout"
    54 }
    Texturing with alpha discard
     1 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
     2 
     3 Shader "Custom/Cg texturing with alpha blending" {
     4    Properties {
     5       _MainTex ("RGBA Texture Image", 2D) = "white" {} 
     6    }
     7    SubShader {
     8       Tags {"Queue" = "Transparent"}
     9 
    10       Pass {    
    11          Cull Front // first render the back faces
    12          ZWrite Off // don't write to depth buffer 
    13             // in order not to occlude other objects
    14          Blend SrcAlpha OneMinusSrcAlpha 
    15             // blend based on the fragment's alpha value
    16          
    17          CGPROGRAM
    18  
    19          #pragma vertex vert  
    20          #pragma fragment frag 
    21  
    22          uniform sampler2D _MainTex;
    23  
    24          struct vertexInput {
    25             float4 vertex : POSITION;
    26             float4 texcoord : TEXCOORD0;
    27          };
    28          struct vertexOutput {
    29             float4 pos : SV_POSITION;
    30             float4 tex : TEXCOORD0;
    31          };
    32  
    33          vertexOutput vert(vertexInput input) 
    34          {
    35             vertexOutput output;
    36  
    37             output.tex = input.texcoord;
    38             output.pos = UnityObjectToClipPos(input.vertex);
    39             return output;
    40          }
    41 
    42          float4 frag(vertexOutput input) : COLOR
    43          {
    44             return tex2D(_MainTex, input.tex.xy);  
    45          }
    46  
    47          ENDCG
    48       }
    49 
    50       Pass {    
    51          Cull Back // now render the front faces
    52          ZWrite Off // don't write to depth buffer 
    53             // in order not to occlude other objects
    54          Blend SrcAlpha OneMinusSrcAlpha 
    55             // blend based on the fragment's alpha value
    56          
    57          CGPROGRAM
    58  
    59          #pragma vertex vert  
    60          #pragma fragment frag 
    61  
    62          uniform sampler2D _MainTex;
    63  
    64          struct vertexInput {
    65             float4 vertex : POSITION;
    66             float4 texcoord : TEXCOORD0;
    67          };
    68          struct vertexOutput {
    69             float4 pos : SV_POSITION;
    70             float4 tex : TEXCOORD0;
    71          };
    72  
    73          vertexOutput vert(vertexInput input) 
    74          {
    75             vertexOutput output;
    76  
    77             output.tex = input.texcoord;
    78             output.pos = UnityObjectToClipPos(input.vertex);
    79             return output;
    80          }
    81 
    82          float4 frag(vertexOutput input) : COLOR
    83          {
    84             return tex2D(_MainTex, input.tex.xy);  
    85          }
    86  
    87          ENDCG
    88       }
    89    }
    90    Fallback "Unlit/Transparent"
    91 }
    Texturing with alpha blending

      1 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
      2 
      3 Shader "Custom/Cg semitransparent colors based on alpha" {
      4    Properties {
      5       _MainTex ("RGBA Texture Image", 2D) = "white" {} 
      6    }
      7    SubShader {
      8       Tags {"Queue" = "Transparent"}
      9 
     10       Pass {    
     11          Cull Front // first render the back faces
     12          ZWrite Off // don't write to depth buffer 
     13             // in order not to occlude other objects
     14          Blend SrcAlpha OneMinusSrcAlpha 
     15             // blend based on the fragment's alpha value
     16          
     17          CGPROGRAM
     18  
     19          #pragma vertex vert  
     20          #pragma fragment frag 
     21  
     22          uniform sampler2D _MainTex;
     23  
     24          struct vertexInput {
     25             float4 vertex : POSITION;
     26             float4 texcoord : TEXCOORD0;
     27          };
     28          struct vertexOutput {
     29             float4 pos : SV_POSITION;
     30             float4 tex : TEXCOORD0;
     31          };
     32  
     33          vertexOutput vert(vertexInput input) 
     34          {
     35             vertexOutput output;
     36  
     37             output.tex = input.texcoord;
     38             output.pos = UnityObjectToClipPos(input.vertex);
     39             return output;
     40          }
     41 
     42          float4 frag(vertexOutput input) : COLOR
     43          {
     44             float4 color =  tex2D(_MainTex, input.tex.xy);  
     45             if (color.a > 0.5) // opaque back face?
     46             {
     47                color = float4(0.0, 0.0, 0.2, 1.0); 
     48                   // opaque dark blue
     49             }
     50             else // transparent back face?
     51             {
     52                color = float4(0.0, 0.0, 1.0, 0.3); 
     53                   // semitransparent green
     54             }
     55             return color;
     56          }
     57  
     58          ENDCG
     59       }
     60 
     61       Pass {    
     62          Cull Back // now render the front faces
     63          ZWrite Off // don't write to depth buffer 
     64             // in order not to occlude other objects
     65          Blend SrcAlpha OneMinusSrcAlpha 
     66             // blend based on the fragment's alpha value
     67          
     68          CGPROGRAM
     69  
     70          #pragma vertex vert  
     71          #pragma fragment frag 
     72  
     73          uniform sampler2D _MainTex;
     74  
     75          struct vertexInput {
     76             float4 vertex : POSITION;
     77             float4 texcoord : TEXCOORD0;
     78          };
     79          struct vertexOutput {
     80             float4 pos : SV_POSITION;
     81             float4 tex : TEXCOORD0;
     82          };
     83  
     84          vertexOutput vert(vertexInput input) 
     85          {
     86             vertexOutput output;
     87  
     88             output.tex = input.texcoord;
     89             output.pos = UnityObjectToClipPos(input.vertex);
     90             return output;
     91          }
     92 
     93          float4 frag(vertexOutput input) : COLOR
     94          {
     95             float4 color = tex2D(_MainTex, input.tex.xy);  
     96             if (color.a > 0.5) // opaque front face?
     97             {
     98                color = float4(0.0, 1.0, 0.0, 1.0); 
     99                   // opaque green
    100             }
    101             else // transparent front face
    102             {
    103                color = float4(0.0, 0.0, 1.0, 0.3); 
    104                   // semitransparent dark blue
    105             }
    106             return color;
    107         }
    108  
    109          ENDCG
    110       }
    111    }
    112    Fallback "Unlit/Transparent"
    113 }
    Semitransparent colors based on alpha

    Layers of Textures (about multitexturing)

     1 // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
     2 // Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
     3 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
     4 
     5 Shader "Custom/Cg multitexturing of Earth" {
     6    Properties {
     7       _DecalTex ("Daytime Earth", 2D) = "white" {}
     8       _MainTex ("Nighttime Earth", 2D) = "white" {} 
     9       _Color ("Nighttime Color Filter", Color) = (1,1,1,1)
    10    }
    11    SubShader {
    12       Pass {    
    13          Tags { "LightMode" = "ForwardBase" } 
    14             // pass for the first, directional light 
    15  
    16          CGPROGRAM
    17  
    18          #pragma vertex vert  
    19          #pragma fragment frag 
    20  
    21          #include "UnityCG.cginc"
    22          uniform float4 _LightColor0; 
    23             // color of light source (from "Lighting.cginc")
    24  
    25          uniform sampler2D _MainTex;
    26          uniform sampler2D _DecalTex;
    27          uniform float4 _Color; 
    28  
    29          struct vertexInput {
    30             float4 vertex : POSITION;
    31             float3 normal : NORMAL;
    32             float4 texcoord : TEXCOORD0;
    33          };
    34          struct vertexOutput {
    35             float4 pos : SV_POSITION;
    36             float4 tex : TEXCOORD0;
    37             float levelOfLighting : TEXCOORD1;
    38                // level of diffuse lighting computed in vertex shader
    39          };
    40  
    41          vertexOutput vert(vertexInput input) 
    42          {
    43             vertexOutput output;
    44  
    45             float4x4 modelMatrix = unity_ObjectToWorld;
    46             float4x4 modelMatrixInverse = unity_WorldToObject;
    47  
    48             float3 normalDirection = normalize(
    49                mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
    50             float3 lightDirection = normalize(
    51                _WorldSpaceLightPos0.xyz);
    52  
    53             output.levelOfLighting = 
    54                max(0.0, dot(normalDirection, lightDirection));
    55             output.tex = input.texcoord;
    56             output.pos = UnityObjectToClipPos(input.vertex);
    57             return output;
    58          }
    59  
    60          float4 frag(vertexOutput input) : COLOR
    61          {
    62             float4 nighttimeColor = 
    63                tex2D(_MainTex, input.tex.xy);    
    64             float4 daytimeColor = 
    65                tex2D(_DecalTex, input.tex.xy);    
    66             return lerp(nighttimeColor, daytimeColor, 
    67                input.levelOfLighting);
    68                // = daytimeColor * levelOfLighting 
    69                // + nighttimeColor * (1.0 - levelOfLighting)
    70          }
    71  
    72          ENDCG
    73       }
    74    } 
    75    Fallback "Decal"
    76 }
    Multitexturing of Earth

    Textures in 3D

    Lighting of Bumpy Surfaces (about normal mapping)

      1 // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
      2 // Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
      3 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
      4 
      5 Shader "Custom/Cg normal mapping" {
      6    Properties {
      7       _BumpMap ("Normal Map", 2D) = "bump" {}
      8       _Color ("Diffuse Material Color", Color) = (1,1,1,1) 
      9       _SpecColor ("Specular Material Color", Color) = (1,1,1,1) 
     10       _Shininess ("Shininess", Float) = 10
     11    }
     12 
     13    CGINCLUDE // common code for all passes of all subshaders
     14 
     15       #include "UnityCG.cginc"
     16       uniform float4 _LightColor0; 
     17       // color of light source (from "Lighting.cginc")
     18 
     19       // User-specified properties
     20       uniform sampler2D _BumpMap;   
     21       uniform float4 _BumpMap_ST;
     22       uniform float4 _Color; 
     23       uniform float4 _SpecColor; 
     24       uniform float _Shininess;
     25 
     26       struct vertexInput {
     27          float4 vertex : POSITION;
     28          float4 texcoord : TEXCOORD0;
     29          float3 normal : NORMAL;
     30          float4 tangent : TANGENT;
     31       };
     32       struct vertexOutput {
     33          float4 pos : SV_POSITION;
     34          float4 posWorld : TEXCOORD0;
     35          // position of the vertex (and fragment) in world space 
     36          float4 tex : TEXCOORD1;
     37          float3 tangentWorld : TEXCOORD2;  
     38          float3 normalWorld : TEXCOORD3;
     39          float3 binormalWorld : TEXCOORD4;
     40       };
     41 
     42       vertexOutput vert(vertexInput input) 
     43       {
     44          vertexOutput output;
     45 
     46          float4x4 modelMatrix = unity_ObjectToWorld;
     47          float4x4 modelMatrixInverse = unity_WorldToObject;
     48 
     49          output.tangentWorld = normalize(
     50             mul(modelMatrix, float4(input.tangent.xyz, 0.0)).xyz);
     51          output.normalWorld = normalize(
     52             mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
     53          output.binormalWorld = normalize(
     54             cross(output.normalWorld, output.tangentWorld) 
     55             * input.tangent.w); // tangent.w is specific to Unity
     56 
     57          output.posWorld = mul(modelMatrix, input.vertex);
     58          output.tex = input.texcoord;
     59          output.pos = UnityObjectToClipPos(input.vertex);
     60          return output;
     61       }
     62 
     63       // fragment shader with ambient lighting
     64       float4 fragWithAmbient(vertexOutput input) : COLOR
     65       {
     66          // in principle we have to normalize tangentWorld,
     67          // binormalWorld, and normalWorld again; however, the 
     68          // potential problems are small since we use this 
     69          // matrix only to compute "normalDirection", 
     70          // which we normalize anyways
     71 
     72          float4 encodedNormal = tex2D(_BumpMap, 
     73             _BumpMap_ST.xy * input.tex.xy + _BumpMap_ST.zw);
     74          float3 localCoords = float3(2.0 * encodedNormal.a - 1.0, 
     75              2.0 * encodedNormal.g - 1.0, 0.0);
     76          localCoords.z = sqrt(1.0 - dot(localCoords, localCoords));
     77          // approximation without sqrt:  localCoords.z = 
     78          // 1.0 - 0.5 * dot(localCoords, localCoords);
     79 
     80          float3x3 local2WorldTranspose = float3x3(
     81             input.tangentWorld, 
     82             input.binormalWorld, 
     83             input.normalWorld);
     84          float3 normalDirection = 
     85             normalize(mul(localCoords, local2WorldTranspose));
     86 
     87          float3 viewDirection = normalize(
     88             _WorldSpaceCameraPos - input.posWorld.xyz);
     89          float3 lightDirection;
     90          float attenuation;
     91 
     92          if (0.0 == _WorldSpaceLightPos0.w) // directional light?
     93          { 
     94             attenuation = 1.0; // no attenuation
     95             lightDirection = normalize(_WorldSpaceLightPos0.xyz);
     96          } 
     97          else // point or spot light
     98          {
     99             float3 vertexToLightSource = 
    100                _WorldSpaceLightPos0.xyz - input.posWorld.xyz;
    101             float distance = length(vertexToLightSource);
    102             attenuation = 1.0 / distance; // linear attenuation 
    103             lightDirection = normalize(vertexToLightSource);
    104          }
    105 
    106          float3 ambientLighting = 
    107             UNITY_LIGHTMODEL_AMBIENT.rgb * _Color.rgb;
    108 
    109          float3 diffuseReflection = 
    110             attenuation * _LightColor0.rgb * _Color.rgb
    111             * max(0.0, dot(normalDirection, lightDirection));
    112 
    113          float3 specularReflection;
    114          if (dot(normalDirection, lightDirection) < 0.0) 
    115             // light source on the wrong side?
    116          {
    117             specularReflection = float3(0.0, 0.0, 0.0); 
    118             // no specular reflection
    119          }
    120          else // light source on the right side
    121          {
    122             specularReflection = attenuation * _LightColor0.rgb 
    123                * _SpecColor.rgb * pow(max(0.0, dot(
    124                reflect(-lightDirection, normalDirection), 
    125                viewDirection)), _Shininess);
    126          }
    127          return float4(ambientLighting + diffuseReflection 
    128             + specularReflection, 1.0);
    129       }
    130       
    131       // fragment shader for pass 2 without ambient lighting 
    132       float4 fragWithoutAmbient(vertexOutput input) : COLOR
    133       {
    134         // in principle we have to normalize tangentWorld,
    135         // binormalWorld, and normalWorld again; however, the  
    136         // potential problems are small since we use this 
    137         // matrix only to compute "normalDirection", 
    138         // which we normalize anyways
    139 
    140         float4 encodedNormal = tex2D(_BumpMap, 
    141            _BumpMap_ST.xy * input.tex.xy + _BumpMap_ST.zw);
    142         float3 localCoords = float3(2.0 * encodedNormal.a - 1.0, 
    143             2.0 * encodedNormal.g - 1.0, 0.0);
    144         localCoords.z = sqrt(1.0 - dot(localCoords, localCoords));
    145            // approximation without sqrt:  localCoords.z = 
    146            // 1.0 - 0.5 * dot(localCoords, localCoords);
    147 
    148         float3x3 local2WorldTranspose = float3x3(
    149            input.tangentWorld,
    150            input.binormalWorld, 
    151            input.normalWorld);
    152         float3 normalDirection = 
    153            normalize(mul(localCoords, local2WorldTranspose));
    154 
    155         float3 viewDirection = normalize(
    156            _WorldSpaceCameraPos - input.posWorld.xyz);
    157         float3 lightDirection;
    158         float attenuation;
    159 
    160         if (0.0 == _WorldSpaceLightPos0.w) // directional light?
    161         {
    162            attenuation = 1.0; // no attenuation
    163            lightDirection = normalize(_WorldSpaceLightPos0.xyz);
    164         } 
    165         else // point or spot light
    166         {
    167            float3 vertexToLightSource = 
    168               _WorldSpaceLightPos0.xyz - input.posWorld.xyz;
    169            float distance = length(vertexToLightSource);
    170            attenuation = 1.0 / distance; // linear attenuation 
    171            lightDirection = normalize(vertexToLightSource);
    172         }
    173 
    174         float3 diffuseReflection = 
    175            attenuation * _LightColor0.rgb * _Color.rgb
    176            * max(0.0, dot(normalDirection, lightDirection));
    177 
    178         float3 specularReflection;
    179         if (dot(normalDirection, lightDirection) < 0.0) 
    180            // light source on the wrong side?
    181         {
    182            specularReflection = float3(0.0, 0.0, 0.0); 
    183               // no specular reflection
    184         }
    185         else // light source on the right side
    186         {
    187            specularReflection = attenuation * _LightColor0.rgb 
    188               * _SpecColor.rgb * pow(max(0.0, dot(
    189               reflect(-lightDirection, normalDirection), 
    190               viewDirection)), _Shininess);
    191         }
    192         return float4(diffuseReflection + specularReflection, 1.0);
    193       }
    194    ENDCG
    195 
    196    SubShader {
    197       Pass {      
    198          Tags { "LightMode" = "ForwardBase" } 
    199             // pass for ambient light and first light source
    200  
    201          CGPROGRAM
    202             #pragma vertex vert  
    203             #pragma fragment fragWithAmbient  
    204             // the functions are defined in the CGINCLUDE part
    205          ENDCG
    206       }
    207  
    208       Pass {      
    209          Tags { "LightMode" = "ForwardAdd" } 
    210             // pass for additional light sources
    211          Blend One One // additive blending 
    212  
    213          CGPROGRAM
    214             #pragma vertex vert  
    215             #pragma fragment fragWithoutAmbient
    216             // the functions are defined in the CGINCLUDE part
    217          ENDCG
    218       }
    219    }
    220 }
    Normal mapping

    Projection of Bumpy Surfaces (about parallax mapping)

      1 // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
      2 // Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
      3 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
      4 
      5 Shader "Cg parallax mapping" {
      6    Properties {
      7       _BumpMap ("Normal Map", 2D) = "bump" {}
      8       _ParallaxMap ("Heightmap (in A)", 2D) = "black" {}
      9       _Parallax ("Max Height", Float) = 0.01
     10       _MaxTexCoordOffset ("Max Texture Coordinate Offset", Float) = 
     11          0.01
     12       _Color ("Diffuse Material Color", Color) = (1,1,1,1) 
     13       _SpecColor ("Specular Material Color", Color) = (1,1,1,1) 
     14       _Shininess ("Shininess", Float) = 10
     15    }
     16    CGINCLUDE // common code for all passes of all subshaders
     17       #include "UnityCG.cginc"
     18       uniform float4 _LightColor0; 
     19          // color of light source (from "Lighting.cginc")
     20  
     21       // User-specified properties
     22       uniform sampler2D _BumpMap; 
     23       uniform float4 _BumpMap_ST;
     24       uniform sampler2D _ParallaxMap; 
     25       uniform float4 _ParallaxMap_ST;
     26       uniform float _Parallax;
     27       uniform float _MaxTexCoordOffset;
     28       uniform float4 _Color; 
     29       uniform float4 _SpecColor; 
     30       uniform float _Shininess;
     31  
     32       struct vertexInput {
     33          float4 vertex : POSITION;
     34          float4 texcoord : TEXCOORD0;
     35          float3 normal : NORMAL;
     36          float4 tangent : TANGENT;
     37       };
     38       struct vertexOutput {
     39          float4 pos : SV_POSITION;
     40          float4 posWorld : TEXCOORD0;
     41             // position of the vertex (and fragment) in world space 
     42          float4 tex : TEXCOORD1;
     43          float3 tangentWorld : TEXCOORD2;  
     44          float3 normalWorld : TEXCOORD3;
     45          float3 binormalWorld : TEXCOORD4;
     46          float3 viewDirWorld : TEXCOORD5; 
     47          float3 viewDirInScaledSurfaceCoords : TEXCOORD6;
     48       };
     49  
     50       vertexOutput vert(vertexInput input) 
     51       {
     52          vertexOutput output;
     53  
     54          float4x4 modelMatrix = unity_ObjectToWorld;
     55          float4x4 modelMatrixInverse = unity_WorldToObject; 
     56  
     57          output.tangentWorld = normalize(
     58             mul(modelMatrix, float4(input.tangent.xyz, 0.0)).xyz);
     59          output.normalWorld = normalize(
     60             mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
     61          output.binormalWorld = normalize(
     62             cross(output.normalWorld, output.tangentWorld) 
     63             * input.tangent.w); // tangent.w is specific to Unity
     64  
     65  
     66          float3 binormal = cross(input.normal, input.tangent.xyz) 
     67             * input.tangent.w;
     68             // appropriately scaled tangent and binormal 
     69             // to map distances from object space to texture space
     70               
     71             float3 viewDirInObjectCoords = mul(
     72             modelMatrixInverse, float4(_WorldSpaceCameraPos, 1.0)).xyz 
     73             - input.vertex.xyz;
     74          float3x3 localSurface2ScaledObjectT = 
     75             float3x3(input.tangent.xyz, binormal, input.normal); 
     76             // vectors are orthogonal
     77          output.viewDirInScaledSurfaceCoords = 
     78             mul(localSurface2ScaledObjectT, viewDirInObjectCoords); 
     79             // we multiply with the transpose to multiply with 
     80             // the "inverse" (apart from the scaling)
     81  
     82          output.posWorld = mul(modelMatrix, input.vertex);
     83          output.viewDirWorld = normalize(
     84             _WorldSpaceCameraPos - output.posWorld.xyz);
     85          output.tex = input.texcoord;
     86          output.pos = UnityObjectToClipPos(input.vertex);
     87          return output;
     88       }
     89       
     90       // fragment shader with ambient lighting
     91       float4 fragWithAmbient(vertexOutput input) : COLOR
     92       {
     93          // parallax mapping: compute height and 
     94          // find offset in texture coordinates 
     95          // for the intersection of the view ray 
     96          // with the surface at this height
     97          
     98          float height = _Parallax 
     99             * (-0.5 + tex2D(_ParallaxMap, _ParallaxMap_ST.xy 
    100             * input.tex.xy + _ParallaxMap_ST.zw).x);
    101                
    102          float2 texCoordOffsets = 
    103             clamp(height * input.viewDirInScaledSurfaceCoords.xy 
    104             / input.viewDirInScaledSurfaceCoords.z,
    105             -_MaxTexCoordOffset, +_MaxTexCoordOffset); 
    106               
    107          // normal mapping: lookup and decode normal from bump map
    108  
    109          // in principle we have to normalize tangentWorld,
    110          // binormalWorld, and normalWorld again; however, the  
    111          // potential problems are small since we use this 
    112          // matrix only to compute "normalDirection", 
    113          // which we normalize anyways
    114 
    115          float4 encodedNormal = tex2D(_BumpMap, 
    116             _BumpMap_ST.xy * (input.tex.xy + texCoordOffsets) 
    117             + _BumpMap_ST.zw);                             
    118          float3 localCoords = float3(2.0 * encodedNormal.a - 1.0, 
    119                2.0 * encodedNormal.g - 1.0, 0.0);
    120          localCoords.z = sqrt(1.0 - dot(localCoords, localCoords));
    121             // approximation without sqrt:  localCoords.z = 
    122             // 1.0 - 0.5 * dot(localCoords, localCoords);
    123  
    124          float3x3 local2WorldTranspose = float3x3(
    125             input.tangentWorld, 
    126             input.binormalWorld, 
    127             input.normalWorld);
    128          float3 normalDirection = 
    129             normalize(mul(localCoords, local2WorldTranspose));
    130  
    131          float3 lightDirection;
    132          float attenuation;
    133  
    134          if (0.0 == _WorldSpaceLightPos0.w) // directional light?
    135          {
    136             attenuation = 1.0; // no attenuation
    137             lightDirection = normalize(_WorldSpaceLightPos0.xyz);
    138          } 
    139          else // point or spot light
    140          {
    141             float3 vertexToLightSource = 
    142                _WorldSpaceLightPos0.xyz - input.posWorld.xyz;
    143             float distance = length(vertexToLightSource);
    144             attenuation = 1.0 / distance; // linear attenuation 
    145             lightDirection = normalize(vertexToLightSource);
    146          }
    147  
    148          float3 ambientLighting = 
    149             UNITY_LIGHTMODEL_AMBIENT.rgb * _Color.rgb;
    150  
    151          float3 diffuseReflection = 
    152             attenuation * _LightColor0.rgb * _Color.rgb
    153             * max(0.0, dot(normalDirection, lightDirection));
    154  
    155          float3 specularReflection;
    156          if (dot(normalDirection, lightDirection) < 0.0) 
    157             // light source on the wrong side?
    158          {
    159             specularReflection = float3(0.0, 0.0, 0.0); 
    160                // no specular reflection
    161          }
    162          else // light source on the right side
    163          {
    164             specularReflection = attenuation * _LightColor0.rgb 
    165                * _SpecColor.rgb * pow(max(0.0, dot(
    166                reflect(-lightDirection, normalDirection), 
    167                input.viewDirWorld)), _Shininess);
    168          }
    169          return float4(ambientLighting + diffuseReflection 
    170             + specularReflection, 1.0);
    171       }
    172 
    173       // fragement shader for pass 2 without ambient lighting 
    174       float4 fragWithoutAmbient(vertexOutput input) : COLOR
    175       {
    176          // parallax mapping: compute height and 
    177          // find offset in texture coordinates 
    178          // for the intersection of the view ray 
    179          // with the surface at this height
    180          
    181          float height = _Parallax 
    182             * (-0.5 + tex2D(_ParallaxMap, _ParallaxMap_ST.xy 
    183             * input.tex.xy + _ParallaxMap_ST.zw).x);
    184                
    185          float2 texCoordOffsets = 
    186             clamp(height * input.viewDirInScaledSurfaceCoords.xy 
    187             / input.viewDirInScaledSurfaceCoords.z,
    188             -_MaxTexCoordOffset, +_MaxTexCoordOffset); 
    189               
    190          // normal mapping: lookup and decode normal from bump map
    191  
    192          // in principle we have to normalize tangentWorld,
    193          // binormalWorld, and normalWorld again; however, the  
    194          // potential problems are small since we use this 
    195          // matrix only to compute "normalDirection", 
    196          // which we normalize anyways
    197 
    198          float4 encodedNormal = tex2D(_BumpMap, 
    199             _BumpMap_ST.xy * (input.tex.xy + texCoordOffsets) 
    200             + _BumpMap_ST.zw);                             
    201          float3 localCoords = float3(2.0 * encodedNormal.a - 1.0, 
    202                2.0 * encodedNormal.g - 1.0, 0.0);
    203          localCoords.z = sqrt(1.0 - dot(localCoords, localCoords));
    204             // approximation without sqrt:  localCoords.z = 
    205             // 1.0 - 0.5 * dot(localCoords, localCoords);
    206  
    207          float3x3 local2WorldTranspose = float3x3(
    208             input.tangentWorld, 
    209             input.binormalWorld, 
    210             input.normalWorld);
    211          float3 normalDirection = 
    212             normalize(mul(localCoords, local2WorldTranspose));
    213  
    214          float3 lightDirection;
    215          float attenuation;
    216  
    217          if (0.0 == _WorldSpaceLightPos0.w) // directional light?
    218          {
    219             attenuation = 1.0; // no attenuation
    220             lightDirection = normalize(_WorldSpaceLightPos0.xyz);
    221          } 
    222          else // point or spot light
    223          {
    224             float3 vertexToLightSource = 
    225                _WorldSpaceLightPos0.xyz - input.posWorld.xyz;
    226             float distance = length(vertexToLightSource);
    227             attenuation = 1.0 / distance; // linear attenuation 
    228             lightDirection = normalize(vertexToLightSource);
    229          }
    230  
    231          float3 diffuseReflection = 
    232             attenuation * _LightColor0.rgb * _Color.rgb
    233             * max(0.0, dot(normalDirection, lightDirection));
    234  
    235          float3 specularReflection;
    236          if (dot(normalDirection, lightDirection) < 0.0) 
    237             // light source on the wrong side?
    238          {
    239             specularReflection = float3(0.0, 0.0, 0.0); 
    240                // no specular reflection
    241          }
    242          else // light source on the right side
    243          {
    244             specularReflection = attenuation * _LightColor0.rgb 
    245                * _SpecColor.rgb * pow(max(0.0, dot(
    246                reflect(-lightDirection, normalDirection), 
    247                input.viewDirWorld)), _Shininess);
    248          } 
    249          return float4(diffuseReflection + specularReflection, 
    250             1.0);
    251       }
    252    ENDCG
    253    SubShader {
    254       Pass {      
    255          Tags { "LightMode" = "ForwardBase" } 
    256             // pass for ambient light and first light source
    257  
    258          CGPROGRAM
    259             #pragma vertex vert  
    260             #pragma fragment fragWithAmbient
    261 
    262             // the functions are defined in the CGINCLUDE part
    263          ENDCG
    264       }
    265  
    266       Pass {      
    267          Tags { "LightMode" = "ForwardAdd" } 
    268             // pass for additional light sources
    269          Blend One One // additive blending 
    270  
    271          CGPROGRAM
    272             #pragma vertex vert  
    273             #pragma fragment fragWithoutAmbient  
    274           
    275             // the functions are defined in the CGINCLUDE part   
    276          ENDCG
    277       } 
    278    }
    279 }
    Parallax mapping

    Cookies (about projective texture mapping for shaping light)

      1 Shader "Cg per-pixel lighting with cookies" {
      2    Properties {
      3       _Color ("Diffuse Material Color", Color) = (1,1,1,1) 
      4       _SpecColor ("Specular Material Color", Color) = (1,1,1,1) 
      5       _Shininess ("Shininess", Float) = 10
      6    }
      7    SubShader {
      8       Pass {    
      9          Tags { "LightMode" = "ForwardBase" } // pass for ambient light 
     10             // and first directional light source without cookie
     11  
     12          CGPROGRAM
     13  
     14          #pragma vertex vert  
     15          #pragma fragment frag 
     16  
     17          #include "UnityCG.cginc"
     18          uniform float4 _LightColor0; 
     19             // color of light source (from "Lighting.cginc")
     20  
     21          // User-specified properties
     22          uniform float4 _Color; 
     23          uniform float4 _SpecColor; 
     24          uniform float _Shininess;
     25  
     26          struct vertexInput {
     27             float4 vertex : POSITION;
     28             float3 normal : NORMAL;
     29          };
     30          struct vertexOutput {
     31             float4 pos : SV_POSITION;
     32             float4 posWorld : TEXCOORD0;
     33             float3 normalDir : TEXCOORD1;
     34          };
     35  
     36          vertexOutput vert(vertexInput input) 
     37          {
     38             vertexOutput output;
     39  
     40             float4x4 modelMatrix = _Object2World;
     41             float4x4 modelMatrixInverse = _World2Object; 
     42  
     43             output.posWorld = mul(modelMatrix, input.vertex);
     44             output.normalDir = normalize(
     45                mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
     46             output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
     47             return output;
     48          }
     49  
     50          float4 frag(vertexOutput input) : COLOR
     51          {
     52             float3 normalDirection = normalize(input.normalDir);
     53  
     54             float3 viewDirection = normalize(
     55                _WorldSpaceCameraPos - input.posWorld.xyz);
     56             float3 lightDirection = 
     57                normalize(_WorldSpaceLightPos0.xyz);
     58  
     59             float3 ambientLighting = 
     60                UNITY_LIGHTMODEL_AMBIENT.rgb * _Color.rgb;
     61  
     62             float3 diffuseReflection = 
     63                _LightColor0.rgb * _Color.rgb
     64                * max(0.0, dot(normalDirection, lightDirection));
     65  
     66             float3 specularReflection;
     67             if (dot(normalDirection, lightDirection) < 0.0) 
     68                // light source on the wrong side?
     69             {
     70                specularReflection = float3(0.0, 0.0, 0.0); 
     71                   // no specular reflection
     72             }
     73             else // light source on the right side
     74             {
     75                specularReflection = _LightColor0.rgb 
     76                   * _SpecColor.rgb * pow(max(0.0, dot(
     77                   reflect(-lightDirection, normalDirection), 
     78                   viewDirection)), _Shininess);
     79             }
     80  
     81             return float4(ambientLighting + diffuseReflection 
     82                + specularReflection, 1.0);
     83          }
     84  
     85          ENDCG
     86       }
     87 
     88       Pass {    
     89          Tags { "LightMode" = "ForwardAdd" } 
     90             // pass for additional light sources
     91          Blend One One // additive blending 
     92  
     93          CGPROGRAM
     94  
     95          #pragma vertex vert  
     96          #pragma fragment frag 
     97  
     98          #include "UnityCG.cginc"
     99          uniform float4 _LightColor0; 
    100             // color of light source (from "Lighting.cginc")
    101          uniform float4x4 _LightMatrix0; // transformation 
    102             // from world to light space (from Autolight.cginc)
    103          uniform sampler2D _LightTexture0; 
    104             // cookie alpha texture map (from Autolight.cginc)
    105  
    106          // User-specified properties
    107          uniform float4 _Color; 
    108          uniform float4 _SpecColor; 
    109          uniform float _Shininess;
    110  
    111          struct vertexInput {
    112             float4 vertex : POSITION;
    113             float3 normal : NORMAL;
    114          };
    115          struct vertexOutput {
    116             float4 pos : SV_POSITION;
    117             float4 posWorld : TEXCOORD0;
    118                // position of the vertex (and fragment) in world space 
    119             float4 posLight : TEXCOORD1;
    120                // position of the vertex (and fragment) in light space
    121             float3 normalDir : TEXCOORD2;
    122                // surface normal vector in world space
    123          };
    124  
    125          vertexOutput vert(vertexInput input) 
    126          {
    127             vertexOutput output;
    128  
    129             float4x4 modelMatrix = _Object2World;
    130             float4x4 modelMatrixInverse = _World2Object;
    131 
    132             output.posWorld = mul(modelMatrix, input.vertex);
    133             output.posLight = mul(_LightMatrix0, output.posWorld);
    134             output.normalDir = normalize(
    135                mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
    136             output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
    137             return output;
    138          }
    139  
    140          float4 frag(vertexOutput input) : COLOR
    141          {
    142             float3 normalDirection = normalize(input.normalDir);
    143  
    144             float3 viewDirection = normalize(
    145                _WorldSpaceCameraPos - input.posWorld.xyz);
    146             float3 lightDirection;
    147             float attenuation;
    148  
    149             if (0.0 == _WorldSpaceLightPos0.w) // directional light?
    150             {
    151                attenuation = 1.0; // no attenuation
    152                lightDirection = normalize(_WorldSpaceLightPos0.xyz);
    153             } 
    154             else // point or spot light
    155             {
    156                float3 vertexToLightSource = 
    157                   _WorldSpaceLightPos0.xyz - input.posWorld.xyz;
    158                float distance = length(vertexToLightSource);
    159                attenuation = 1.0 / distance; // linear attenuation 
    160                lightDirection = normalize(vertexToLightSource);
    161             }
    162  
    163             float3 diffuseReflection = 
    164                attenuation * _LightColor0.rgb * _Color.rgb
    165                * max(0.0, dot(normalDirection, lightDirection));
    166  
    167             float3 specularReflection;
    168             if (dot(normalDirection, lightDirection) < 0.0) 
    169                // light source on the wrong side?
    170             {
    171                specularReflection = float3(0.0, 0.0, 0.0); 
    172                   // no specular reflection
    173             }
    174             else // light source on the right side
    175             {
    176                specularReflection = attenuation * _LightColor0.rgb 
    177                   * _SpecColor.rgb * pow(max(0.0, dot(
    178                   reflect(-lightDirection, normalDirection), 
    179                   viewDirection)), _Shininess);
    180             }
    181  
    182             float cookieAttenuation = 1.0;
    183             if (0.0 == _WorldSpaceLightPos0.w) // directional light?
    184             {
    185                cookieAttenuation = tex2D(_LightTexture0, 
    186                   input.posLight.xy).a;
    187             }
    188             else if (1.0 != _LightMatrix0[3][3]) 
    189                // spotlight (i.e. not a point light)?
    190             {
    191                cookieAttenuation = tex2D(_LightTexture0, 
    192                   input.posLight.xy / input.posLight.w 
    193                   + float2(0.5, 0.5)).a;
    194             }
    195 
    196             return float4(cookieAttenuation 
    197                * (diffuseReflection + specularReflection), 1.0);
    198          }
    199  
    200          ENDCG
    201       }
    202    }
    203    Fallback "Specular"
    204 }
    Per-pixel lighting with cookies
      1 Shader "Cg per-pixel lighting with cookies" {
      2    Properties {
      3       _Color ("Diffuse Material Color", Color) = (1,1,1,1) 
      4       _SpecColor ("Specular Material Color", Color) = (1,1,1,1) 
      5       _Shininess ("Shininess", Float) = 10
      6    }
      7    SubShader {
      8       Pass {    
      9          Tags { "LightMode" = "ForwardBase" } // pass for ambient light 
     10             // and first directional light source without cookie
     11  
     12          CGPROGRAM
     13  
     14          #pragma vertex vert  
     15          #pragma fragment frag 
     16  
     17          #include "UnityCG.cginc"
     18          uniform float4 _LightColor0; 
     19             // color of light source (from "Lighting.cginc")
     20  
     21          // User-specified properties
     22          uniform float4 _Color; 
     23          uniform float4 _SpecColor; 
     24          uniform float _Shininess;
     25  
     26          struct vertexInput {
     27             float4 vertex : POSITION;
     28             float3 normal : NORMAL;
     29          };
     30          struct vertexOutput {
     31             float4 pos : SV_POSITION;
     32             float4 posWorld : TEXCOORD0;
     33             float3 normalDir : TEXCOORD1;
     34          };
     35  
     36          vertexOutput vert(vertexInput input) 
     37          {
     38             vertexOutput output;
     39  
     40             float4x4 modelMatrix = _Object2World;
     41             float4x4 modelMatrixInverse = _World2Object;
     42  
     43             output.posWorld = mul(modelMatrix, input.vertex);
     44             output.normalDir = normalize(
     45                mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
     46             output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
     47             return output;
     48          }
     49  
     50          float4 frag(vertexOutput input) : COLOR
     51          {
     52             float3 normalDirection = normalize(input.normalDir);
     53  
     54             float3 viewDirection = normalize(
     55                _WorldSpaceCameraPos - input.posWorld.xyz);
     56             float3 lightDirection = 
     57                normalize(_WorldSpaceLightPos0.xyz);
     58  
     59             float3 ambientLighting = 
     60                UNITY_LIGHTMODEL_AMBIENT.rgb * _Color.rgb;
     61  
     62             float3 diffuseReflection = 
     63                _LightColor0.rgb * _Color.rgb
     64                * max(0.0, dot(normalDirection, lightDirection));
     65  
     66             float3 specularReflection;
     67             if (dot(normalDirection, lightDirection) < 0.0) 
     68                // light source on the wrong side?
     69             {
     70                specularReflection = float3(0.0, 0.0, 0.0); 
     71                   // no specular reflection
     72             }
     73             else // light source on the right side
     74             {
     75                specularReflection = _LightColor0.rgb 
     76                   * _SpecColor.rgb * pow(max(0.0, dot(
     77                   reflect(-lightDirection, normalDirection), 
     78                   viewDirection)), _Shininess);
     79             }
     80  
     81             return float4(ambientLighting + diffuseReflection 
     82                + specularReflection, 1.0);
     83          }
     84  
     85          ENDCG
     86       }
     87 
     88       Pass {    
     89          Tags { "LightMode" = "ForwardAdd" } 
     90             // pass for additional light sources
     91          Blend One One // additive blending 
     92  
     93          CGPROGRAM
     94  
     95          #pragma multi_compile_lightpass
     96  
     97          #pragma vertex vert  
     98          #pragma fragment frag 
     99  
    100          #include "UnityCG.cginc"
    101          uniform float4 _LightColor0; 
    102             // color of light source (from "Lighting.cginc")
    103          uniform float4x4 _LightMatrix0; // transformation 
    104             // from world to light space (from Autolight.cginc)
    105          #if defined (DIRECTIONAL_COOKIE) || defined (SPOT)
    106             uniform sampler2D _LightTexture0; 
    107                // cookie alpha texture map (from Autolight.cginc)
    108          #elif defined (POINT_COOKIE)
    109             uniform samplerCUBE _LightTexture0; 
    110                // cookie alpha texture map (from Autolight.cginc)
    111          #endif
    112  
    113          // User-specified properties
    114          uniform float4 _Color; 
    115          uniform float4 _SpecColor; 
    116          uniform float _Shininess;
    117  
    118          struct vertexInput {
    119             float4 vertex : POSITION;
    120             float3 normal : NORMAL;
    121          };
    122          struct vertexOutput {
    123             float4 pos : SV_POSITION;
    124             float4 posWorld : TEXCOORD0;
    125                // position of the vertex (and fragment) in world space 
    126             float4 posLight : TEXCOORD1;
    127                // position of the vertex (and fragment) in light space
    128             float3 normalDir : TEXCOORD2;
    129                // surface normal vector in world space
    130          };
    131  
    132          vertexOutput vert(vertexInput input) 
    133          {
    134             vertexOutput output;
    135  
    136             float4x4 modelMatrix = _Object2World;
    137             float4x4 modelMatrixInverse = _World2Object;
    138 
    139             output.posWorld = mul(modelMatrix, input.vertex);
    140             output.posLight = mul(_LightMatrix0, output.posWorld);
    141             output.normalDir = normalize(
    142                mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
    143             output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
    144             return output;
    145          }
    146  
    147          float4 frag(vertexOutput input) : COLOR
    148          {
    149             float3 normalDirection = normalize(input.normalDir);
    150  
    151             float3 viewDirection = normalize(
    152                _WorldSpaceCameraPos - input.posWorld.xyz);
    153             float3 lightDirection;
    154             float attenuation = 1.0;
    155                // by default no attenuation with distance
    156 
    157             #if defined (DIRECTIONAL) || defined (DIRECTIONAL_COOKIE)
    158                lightDirection = normalize(_WorldSpaceLightPos0.xyz);
    159             #elif defined (POINT_NOATT)
    160                lightDirection = normalize(
    161                   _WorldSpaceLightPos0 - input.posWorld.xyz);
    162             #elif defined(POINT)||defined(POINT_COOKIE)||defined(SPOT)
    163                float3 vertexToLightSource = 
    164                   _WorldSpaceLightPos0.xyz - input.posWorld.xyz;
    165                float distance = length(vertexToLightSource);
    166                attenuation = 1.0 / distance; // linear attenuation 
    167                lightDirection = normalize(vertexToLightSource);
    168             #endif
    169  
    170             float3 diffuseReflection = 
    171                attenuation * _LightColor0.rgb * _Color.rgb
    172                * max(0.0, dot(normalDirection, lightDirection));
    173  
    174             float3 specularReflection;
    175             if (dot(normalDirection, lightDirection) < 0.0) 
    176                // light source on the wrong side?
    177             {
    178                specularReflection = float3(0.0, 0.0, 0.0); 
    179                   // no specular reflection
    180             }
    181             else // light source on the right side
    182             {
    183                specularReflection = attenuation * _LightColor0.rgb 
    184                   * _SpecColor.rgb * pow(max(0.0, dot(
    185                   reflect(-lightDirection, normalDirection), 
    186                   viewDirection)), _Shininess);
    187             }
    188  
    189             float cookieAttenuation = 1.0; 
    190                // by default no cookie attenuation
    191             #if defined (DIRECTIONAL_COOKIE)
    192                cookieAttenuation = tex2D(_LightTexture0, 
    193                   input.posLight.xy).a;
    194             #elif defined (POINT_COOKIE)
    195                cookieAttenuation = texCUBE(_LightTexture0, 
    196                   input.posLight.xyz).a;
    197             #elif defined (SPOT)
    198                cookieAttenuation = tex2D(_LightTexture0, 
    199                   input.posLight.xy / input.posLight.w 
    200                   + float2(0.5, 0.5)).a;
    201             #endif
    202 
    203             return float4(cookieAttenuation 
    204                * (diffuseReflection + specularReflection), 1.0);
    205          }
    206  
    207          ENDCG
    208       }
    209    }
    210    Fallback "Specular"
    211 }
    Per-pixel lighting with cookies

    Projectors (about projective texture mapping for projectors)

     1 Shader "Cg projector shader for adding light" {
     2    Properties {
     3       _ShadowTex ("Projected Image", 2D) = "white" {}
     4    }
     5    SubShader {
     6       Pass {      
     7          Blend One One 
     8             // add color of _ShadowTex to the color in the framebuffer 
     9          ZWrite Off // don't change depths
    10          Offset -1, -1 // avoid depth fighting
    11 
    12          CGPROGRAM
    13  
    14          #pragma vertex vert  
    15          #pragma fragment frag 
    16  
    17          // User-specified properties
    18          uniform sampler2D _ShadowTex; 
    19  
    20          // Projector-specific uniforms
    21          uniform float4x4 _Projector; // transformation matrix 
    22             // from object space to projector space 
    23  
    24           struct vertexInput {
    25             float4 vertex : POSITION;
    26             float3 normal : NORMAL;
    27          };
    28          struct vertexOutput {
    29             float4 pos : SV_POSITION;
    30             float4 posProj : TEXCOORD0;
    31                // position in projector space
    32          };
    33  
    34          vertexOutput vert(vertexInput input) 
    35          {
    36             vertexOutput output;
    37  
    38             output.posProj = mul(_Projector, input.vertex);
    39             output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
    40             return output;
    41          }
    42  
    43  
    44          float4 frag(vertexOutput input) : COLOR
    45          {
    46             if (input.posProj.w > 0.0) // in front of projector?
    47             {
    48                return tex2D(_ShadowTex , 
    49                   input.posProj.xy / input.posProj.w); 
    50                // alternatively: return tex2Dproj(  
    51                //    _ShadowTex, input.posProj);
    52             }
    53             else // behind projector
    54             {
    55                return float4(0.0, 0.0, 0.0, 0.0);
    56             }
    57          }
    58  
    59          ENDCG
    60       }
    61    }  
    62    Fallback "Projector/Light"
    63 }
    Projector shader for adding light
     1 // Upgrade NOTE: replaced '_Projector' with 'unity_Projector'
     2 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
     3 
     4 Shader "Cg projector shader for drop shadows" {
     5    Properties {
     6       _ShadowTex ("Projected Image", 2D) = "white" {}
     7    }
     8    SubShader {
     9       Pass {      
    10          Blend Zero OneMinusSrcAlpha // attenuate color in framebuffer 
    11             // by 1 minus alpha of _ShadowTex 
    12          ZWrite Off // don't change depths
    13          Offset -1, -1 // avoid depth fighting
    14          
    15          CGPROGRAM
    16  
    17          #pragma vertex vert  
    18          #pragma fragment frag 
    19  
    20          // User-specified properties
    21          uniform sampler2D _ShadowTex; 
    22  
    23          // Projector-specific uniforms
    24          uniform float4x4 unity_Projector; // transformation matrix 
    25             // from object space to projector space 
    26  
    27           struct vertexInput {
    28             float4 vertex : POSITION;
    29             float3 normal : NORMAL;
    30          };
    31          struct vertexOutput {
    32             float4 pos : SV_POSITION;
    33             float4 posProj : TEXCOORD0;
    34                // position in projector space
    35          };
    36  
    37          vertexOutput vert(vertexInput input) 
    38          {
    39             vertexOutput output;
    40  
    41             output.posProj = mul(unity_Projector, input.vertex);
    42             output.pos = UnityObjectToClipPos(input.vertex);
    43             return output;
    44          }
    45  
    46  
    47          float4 frag(vertexOutput input) : COLOR
    48          {
    49             if (input.posProj.w > 0.0) // in front of projector?
    50             {
    51                return tex2D(_ShadowTex , 
    52                   input.posProj.xy / input.posProj.w); 
    53                // alternatively: return tex2Dproj(  
    54                //    _ShadowTex, input.posProj);
    55             }
    56             else // behind projector
    57             {
    58                return float4(0.0, 0.0, 0.0, 0.0);
    59             }
    60          }
    61  
    62          ENDCG
    63       }
    64    }  
    65    Fallback "Projector/Light"
    66 }
    Projector shader for drop shadows

    Environment Mapping

    Reflecting Surfaces (about reflection mapping)

     1 // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
     2 // Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
     3 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
     4 
     5 Shader "Custom/Cg shader with reflection map" {
     6     Properties {
     7         _Cube("Reflection Map",Cube) = "" {}
     8     }
     9     SubShader{
    10         Pass {
    11             CGPROGRAM
    12 
    13             #pragma vertex vert
    14             #pragma fragment frag
    15 
    16             #include "UnityCG.cginc"
    17 
    18             // User-specified uniforms
    19             uniform samplerCUBE _Cube;
    20 
    21             struct vertexInput{
    22                 float4 vertex:POSITION;
    23                 float3 normal:NORMAL;
    24             };
    25             struct vertexOutput{
    26                 float4 pos:SV_POSITION;
    27                 float3 normalDir:TEXCOORD0;
    28                 float3 viewDir:TEXCOORD1;
    29             };
    30 
    31             vertexOutput vert(vertexInput input){
    32                 vertexOutput output;
    33 
    34                 float4x4 modelMatrix = unity_ObjectToWorld;
    35                 float4x4 modelMatrixInverse = unity_WorldToObject;
    36 
    37                 output.viewDir = mul(modelMatrix,input.vertex).xyz - _WorldSpaceCameraPos;
    38                 output.normalDir = normalize(mul(float4(input.normal,0.0),modelMatrixInverse).xyz);
    39                 output.pos = UnityObjectToClipPos(input.vertex);
    40 
    41                 return output;
    42             }
    43 
    44             float4 frag(vertexOutput input):COLOR{
    45                 float3 reflectionDir = reflect(input.viewDir,normalize(input.normalDir));
    46                 return texCUBE(_Cube,reflectionDir);
    47             }
    48 
    49             ENDCG
    50         }
    51     }
    52 }
    Shader with reflection map

    Curved Glass (about refraction mapping)

     1 // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
     2 // Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
     3 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
     4 
     5 Shader "Custom/Cg shader with refraction mapping" {
     6     Properties {
     7         _Cube("Reflection Map",Cube) = "" {}
     8     }
     9     SubShader {
    10         Pass {
    11             CGPROGRAM
    12 
    13             #pragma vertex vert
    14             #pragma fragment frag
    15 
    16             uniform samplerCUBE _Cube;
    17 
    18             struct vertexInput{
    19                 float4 vertex:POSITION;
    20                 float3 normal:NORMAL;
    21             };
    22             struct vertexOutput{
    23                 float4 pos:SV_POSITION;
    24                 float3 normalDir:TEXCOORD0;
    25                 float3 viewDir:TEXCOORD1;
    26             };
    27 
    28             vertexOutput vert(vertexInput input){
    29                 vertexOutput output;
    30 
    31                 float4x4 modelMatrix = unity_ObjectToWorld;
    32                 float4x4 modelMatrixInverse = unity_WorldToObject;
    33 
    34                 output.viewDir = mul(modelMatrix,input.vertex).xyz - _WorldSpaceCameraPos;
    35                 output.normalDir = normalize(mul(float4(input.normal,0.0),modelMatrixInverse).xyz);
    36                 output.pos = UnityObjectToClipPos(input.vertex);
    37                 return output;
    38             }
    39 
    40             float4 frag(vertexOutput input):COLOR{
    41                 float refractiveIndex = 1.5;
    42                 float3 refractedDir = refract(normalize(input.viewDir),normalize(input.normalDir),1.0/refractiveIndex);
    43                 return texCUBE(_Cube,refractedDir);
    44             }
    45 
    46             ENDCG
    47         }
    48     }
    49 }
    Shader with refraction mapping

    Skyboxes (about rendering of environment maps as background)

     1 // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
     2 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
     3 
     4 Shader "Cg shader for skybox" {
     5     Properties {
     6         _Cube("Environment Map",Cube)=""{}
     7     }
     8     SubShader{
     9         Tags { "Queue" = "Background" }    
    10         Pass{
    11             ZWrite Off
    12             Cull Front
    13 
    14             CGPROGRAM
    15 
    16             #pragma vertex vert
    17             #pragma fragment frag
    18 
    19             #include "UnityCG.cginc"
    20 
    21             // User-specified uniform
    22             uniform samplerCUBE _Cube;
    23 
    24             struct vertexInput{
    25                 float4 vertex:POSITION;
    26             };
    27             struct vertexOutput{
    28                 float4 pos:SV_POSITION;
    29                 float3 viewDir:TEXCOORD1;
    30             };
    31 
    32             vertexOutput vert(vertexInput input){
    33                 vertexOutput output;
    34 
    35                 float4x4 modelMatrix = unity_ObjectToWorld;
    36                 output.viewDir = mul(modelMatrix,input.vertex).xyz - _WorldSpaceCameraPos;
    37                 output.pos = UnityObjectToClipPos(input.vertex);
    38                 return output;
    39             }
    40 
    41             float4 frag(vertexOutput input):COLOR{
    42                 return texCUBE(_Cube,input.viewDir);
    43             }
    44 
    45             ENDCG
    46         }
    47     }
    48 }
    Shader for skybox
     1 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
     2 
     3 Shader "Cg shader for Unity-specific skybox" {
     4     Properties {
     5         _Cube("Environment Map",Cube)="white"{}
     6     }
     7     SubShader {
     8         Tags  {"Queue"="Background"}
     9         Pass{
    10             ZWrite Off
    11             Cull Off
    12 
    13             CGPROGRAM
    14 
    15             #pragma vertex vert
    16             #pragma fragment frag
    17 
    18             // User-specified uniforms
    19             samplerCUBE _Cube;
    20 
    21             struct vertexInput{
    22                 float4 vertex:POSITION;
    23                 float3 texcoord:TEXCOORD0;
    24             };
    25             struct vertexOutput{
    26                 float4 vertex:SV_POSITION;
    27                 float3 texcoord:TEXCOORD0;
    28             };
    29 
    30             vertexOutput vert(vertexInput input){
    31                 vertexOutput output;
    32                 output.vertex = UnityObjectToClipPos(input.vertex);
    33                 output.texcoord = input.texcoord;
    34                 return output;
    35             }
    36 
    37             float4 frag(vertexOutput input):COLOR{
    38                 return texCUBE(_Cube,input.texcoord);
    39             }
    40 
    41             ENDCG
    42         }
    43     }
    44 }
    Shader for Unity-specific skybox

    Many Light Sources (about image-based lighting)

     1 Shader "Cg shader with image-based diffuse lighting" {
     2    Properties {
     3       _OriginalCube ("Environment Map", Cube) = "" {}
     4       _Cube ("Diffuse Environment Map", Cube) = "" {}
     5    }
     6    SubShader {
     7       Pass {   
     8          CGPROGRAM
     9  
    10          #pragma vertex vert  
    11          #pragma fragment frag 
    12  
    13          #include "UnityCG.cginc"
    14 
    15          // User-specified uniforms
    16          uniform samplerCUBE _Cube;   
    17  
    18          struct vertexInput {
    19             float4 vertex : POSITION;
    20             float3 normal : NORMAL;
    21          };
    22          struct vertexOutput {
    23             float4 pos : SV_POSITION;
    24             float3 normalDir : TEXCOORD0;
    25          };
    26  
    27          vertexOutput vert(vertexInput input) 
    28          {
    29             vertexOutput output;
    30  
    31             float4x4 modelMatrixInverse = _World2Object; 
    32                // multiplication with unity_Scale.w is unnecessary 
    33                // because we normalize transformed vectors
    34  
    35             output.normalDir = normalize(
    36                mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
    37             output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
    38             return output;
    39          }
    40  
    41          float4 frag(vertexOutput input) : COLOR
    42          {
    43             return texCUBE(_Cube, input.normalDir);
    44          }
    45  
    46          ENDCG
    47       }
    48    }
    49 }
    Shader with image-based diffuse lighting

    Variations on Lighting

    Brushed Metal (about anisotropic specular reflection)

      1 // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
      2 // Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
      3 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
      4 
      5 Shader "Custom/Cg anisotropic per-pixel lighting" {
      6    Properties {
      7       _Color ("Diffuse Material Color", Color) = (1,1,1,1) 
      8       _SpecColor ("Specular Material Color", Color) = (1,1,1,1) 
      9       _AlphaX ("Roughness in Brush Direction", Float) = 1.0
     10       _AlphaY ("Roughness orthogonal to Brush Direction", Float) = 1.0
     11    }
     12    SubShader {
     13       Pass {    
     14          Tags { "LightMode" = "ForwardBase" } 
     15             // pass for ambient light and first light source
     16  
     17          CGPROGRAM
     18  
     19          #pragma vertex vert  
     20          #pragma fragment frag 
     21  
     22          #include "UnityCG.cginc"
     23          uniform float4 _LightColor0; 
     24             // color of light source (from "Lighting.cginc")
     25  
     26          // User-specified properties
     27          uniform float4 _Color; 
     28          uniform float4 _SpecColor; 
     29          uniform float _AlphaX;
     30          uniform float _AlphaY;
     31  
     32          struct vertexInput {
     33             float4 vertex : POSITION;
     34             float3 normal : NORMAL;
     35             float4 tangent : TANGENT;
     36          };
     37          struct vertexOutput {
     38             float4 pos : SV_POSITION;
     39             float4 posWorld : TEXCOORD0;
     40                // position of the vertex (and fragment) in world space 
     41             float3 viewDir : TEXCOORD1;
     42                // view direction in world space
     43             float3 normalDir : TEXCOORD2;
     44                // surface normal vector in world space
     45             float3 tangentDir : TEXCOORD3;
     46                // brush direction in world space
     47          };
     48  
     49          vertexOutput vert(vertexInput input) 
     50          {
     51             vertexOutput output;
     52  
     53             float4x4 modelMatrix = unity_ObjectToWorld;
     54             float4x4 modelMatrixInverse = unity_WorldToObject; 
     55  
     56             output.posWorld = mul(modelMatrix, input.vertex);
     57             output.viewDir = normalize(_WorldSpaceCameraPos 
     58                - output.posWorld.xyz);
     59             output.normalDir = normalize(
     60                mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
     61             output.tangentDir = normalize(
     62                mul(modelMatrix, float4(input.tangent.xyz, 0.0)).xyz);
     63             output.pos = UnityObjectToClipPos(input.vertex);
     64             return output;
     65          }
     66  
     67          float4 frag(vertexOutput input) : COLOR
     68          {
     69             float3 lightDirection;
     70             float attenuation;
     71  
     72             if (0.0 == _WorldSpaceLightPos0.w) // directional light?
     73             {
     74                attenuation = 1.0; // no attenuation
     75                lightDirection = normalize(_WorldSpaceLightPos0.xyz);
     76             } 
     77             else // point or spot light
     78             {
     79                float3 vertexToLightSource = 
     80                   _WorldSpaceLightPos0.xyz - input.posWorld.xyz;
     81                float distance = length(vertexToLightSource);
     82                attenuation = 1.0 / distance; // linear attenuation 
     83                lightDirection = normalize(vertexToLightSource);
     84             }
     85  
     86             float3 halfwayVector = 
     87                normalize(lightDirection + input.viewDir);
     88             float3 binormalDirection = 
     89                cross(input.normalDir, input.tangentDir);
     90             float dotLN = dot(lightDirection, input.normalDir); 
     91                // compute this dot product only once
     92  
     93             float3 ambientLighting = 
     94                UNITY_LIGHTMODEL_AMBIENT.rgb * _Color.rgb;
     95  
     96             float3 diffuseReflection = 
     97                attenuation * _LightColor0.rgb * _Color.rgb 
     98                * max(0.0, dotLN);
     99  
    100             float3 specularReflection;
    101             if (dotLN < 0.0) // light source on the wrong side?
    102             {
    103                specularReflection = float3(0.0, 0.0, 0.0); 
    104                   // no specular reflection
    105             }
    106             else // light source on the right side
    107             {
    108                float dotHN = dot(halfwayVector, input.normalDir);
    109                float dotVN = dot(input.viewDir, input.normalDir);
    110                float dotHTAlphaX = 
    111                   dot(halfwayVector, input.tangentDir) / _AlphaX;
    112                float dotHBAlphaY = dot(halfwayVector, 
    113                   binormalDirection) / _AlphaY;
    114  
    115                specularReflection = 
    116                   attenuation * _LightColor0.rgb * _SpecColor.rgb 
    117                   * sqrt(max(0.0, dotLN / dotVN)) 
    118                   * exp(-2.0 * (dotHTAlphaX * dotHTAlphaX 
    119                   + dotHBAlphaY * dotHBAlphaY) / (1.0 + dotHN));
    120             }
    121             return float4(ambientLighting + diffuseReflection 
    122                + specularReflection, 1.0);
    123          }
    124          ENDCG
    125       }
    126  
    127       Pass {    
    128          Tags { "LightMode" = "ForwardAdd" } 
    129             // pass for additional light sources
    130          Blend One One // additive blending 
    131  
    132          CGPROGRAM
    133  
    134          #pragma vertex vert  
    135          #pragma fragment frag 
    136  
    137          #include "UnityCG.cginc"
    138          uniform float4 _LightColor0; 
    139             // color of light source (from "Lighting.cginc")
    140  
    141          // User-specified properties
    142          uniform float4 _Color; 
    143          uniform float4 _SpecColor; 
    144          uniform float _AlphaX;
    145          uniform float _AlphaY;
    146  
    147          struct vertexInput {
    148             float4 vertex : POSITION;
    149             float3 normal : NORMAL;
    150             float4 tangent : TANGENT;
    151          };
    152          struct vertexOutput {
    153             float4 pos : SV_POSITION;
    154             float4 posWorld : TEXCOORD0;
    155                // position of the vertex (and fragment) in world space 
    156             float3 viewDir : TEXCOORD1;
    157                // view direction in world space
    158             float3 normalDir : TEXCOORD2;
    159                // surface normal vector in world space
    160             float3 tangentDir : TEXCOORD3;
    161                // brush direction in world space
    162          };
    163  
    164          vertexOutput vert(vertexInput input) 
    165          {
    166             vertexOutput output;
    167  
    168             float4x4 modelMatrix = unity_ObjectToWorld;
    169             float4x4 modelMatrixInverse = unity_WorldToObject;
    170  
    171             output.posWorld = mul(modelMatrix, input.vertex);
    172             output.viewDir = normalize(_WorldSpaceCameraPos 
    173                - output.posWorld.xyz);
    174             output.normalDir = normalize(
    175                mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
    176             output.tangentDir = normalize(
    177                mul(modelMatrix, float4(input.tangent.xyz, 0.0)).xyz);
    178             output.pos = UnityObjectToClipPos(input.vertex);
    179             return output;
    180          }
    181  
    182          float4 frag(vertexOutput input) : COLOR
    183          {
    184             float3 lightDirection;
    185             float attenuation;
    186  
    187             if (0.0 == _WorldSpaceLightPos0.w) // directional light?
    188             {
    189                attenuation = 1.0; // no attenuation
    190                lightDirection = normalize(_WorldSpaceLightPos0.xyz);
    191             } 
    192             else // point or spot light
    193             {
    194                float3 vertexToLightSource = 
    195                   _WorldSpaceLightPos0.xyz - input.posWorld.xyz;
    196                float distance = length(vertexToLightSource);
    197                attenuation = 1.0 / distance; // linear attenuation 
    198                lightDirection = normalize(vertexToLightSource);
    199             }
    200  
    201             float3 halfwayVector = 
    202                normalize(lightDirection + input.viewDir);
    203             float3 binormalDirection = 
    204                cross(input.normalDir, input.tangentDir);
    205             float dotLN = dot(lightDirection, input.normalDir); 
    206                // compute this dot product only once
    207  
    208             float3 diffuseReflection = 
    209                attenuation * _LightColor0.rgb * _Color.rgb 
    210                * max(0.0, dotLN);
    211  
    212             float3 specularReflection;
    213             if (dotLN < 0.0) // light source on the wrong side?
    214             {
    215                specularReflection = float3(0.0, 0.0, 0.0); 
    216                   // no specular reflection
    217             }
    218             else // light source on the right side
    219             {
    220                float dotHN = dot(halfwayVector, input.normalDir);
    221                float dotVN = dot(input.viewDir, input.normalDir);
    222                float dotHTAlphaX = 
    223                   dot(halfwayVector, input.tangentDir) / _AlphaX;
    224                float dotHBAlphaY = dot(halfwayVector, 
    225                   binormalDirection) / _AlphaY;
    226  
    227                specularReflection = 
    228                   attenuation * _LightColor0.rgb * _SpecColor.rgb 
    229                   * sqrt(max(0.0, dotLN / dotVN)) 
    230                   * exp(-2.0 * (dotHTAlphaX * dotHTAlphaX 
    231                   + dotHBAlphaY * dotHBAlphaY) / (1.0 + dotHN));
    232             }
    233             return float4(diffuseReflection 
    234                + specularReflection, 1.0);
    235          }
    236          ENDCG
    237       }
    238    }
    239    Fallback "Specular"
    240 }
    Anisotropic per-pixel lighting

    Specular Highlights at Silhouettes (about the Fresnel factor for specular reflection)

      1 Shader "Custom/Cg Fresnel highlights" {
      2    Properties {
      3       _Color ("Diffuse Material Color", Color) = (1,1,1,1) 
      4       _SpecColor ("Specular Material Color", Color) = (1,1,1,1) 
      5       _Shininess ("Shininess", Float) = 10
      6    }
      7    SubShader {
      8       Pass {    
      9          Tags { "LightMode" = "ForwardBase" } 
     10             // pass for ambient light and first light source
     11  
     12          CGPROGRAM
     13  
     14          #pragma vertex vert  
     15          #pragma fragment frag 
     16  
     17          #include "UnityCG.cginc"
     18          uniform float4 _LightColor0; 
     19             // color of light source (from "Lighting.cginc")
     20  
     21          // User-specified properties
     22          uniform float4 _Color; 
     23          uniform float4 _SpecColor; 
     24          uniform float _Shininess;
     25  
     26          struct vertexInput {
     27             float4 vertex : POSITION;
     28             float3 normal : NORMAL;
     29          };
     30          struct vertexOutput {
     31             float4 pos : SV_POSITION;
     32             float4 posWorld : TEXCOORD0;
     33             float3 normalDir : TEXCOORD1;
     34          };
     35  
     36          vertexOutput vert(vertexInput input) 
     37          {
     38             vertexOutput output;
     39  
     40             float4x4 modelMatrix = _Object2World;
     41             float3x3 modelMatrixInverse = _World2Object;
     42  
     43             output.posWorld = mul(modelMatrix, input.vertex);
     44             output.normalDir = normalize(mul(input.normal, modelMatrixInverse));
     45             output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
     46             return output;
     47          }
     48  
     49          float4 frag(vertexOutput input) : COLOR
     50          {
     51             float3 normalDirection = normalize(input.normalDir);
     52             float3 viewDirection = normalize(
     53                _WorldSpaceCameraPos - input.posWorld.xyz);
     54             float3 lightDirection;
     55             float attenuation;
     56  
     57             if (0.0 == _WorldSpaceLightPos0.w) // directional light?
     58             {
     59                attenuation = 1.0; // no attenuation
     60                lightDirection = normalize(_WorldSpaceLightPos0.xyz);
     61             } 
     62             else // point or spot light
     63             {
     64                float3 vertexToLightSource = 
     65                   _WorldSpaceLightPos0.xyz - input.posWorld.xyz;
     66                float distance = length(vertexToLightSource);
     67                attenuation = 1.0 / distance; // linear attenuation 
     68                lightDirection = normalize(vertexToLightSource);
     69             }
     70  
     71             float3 ambientLighting = 
     72                UNITY_LIGHTMODEL_AMBIENT.rgb * _Color.rgb;
     73  
     74             float3 diffuseReflection = 
     75                attenuation * _LightColor0.rgb * _Color.rgb
     76                * max(0.0, dot(normalDirection, lightDirection));
     77  
     78             float3 specularReflection;
     79             if (dot(normalDirection, lightDirection) < 0.0) 
     80                // light source on the wrong side?
     81             {
     82                specularReflection = float3(0.0, 0.0, 0.0); 
     83                   // no specular reflection
     84             }
     85             else // light source on the right side
     86             {
     87                float3 halfwayDirection = 
     88                   normalize(lightDirection + viewDirection);
     89                float w = pow(1.0 - max(0.0, 
     90                   dot(halfwayDirection, viewDirection)), 5.0);
     91                specularReflection = attenuation * _LightColor0.rgb 
     92                   * lerp(_SpecColor.rgb, float3(1.0, 1.0, 1.0), w) 
     93                   * pow(max(0.0, dot(
     94                   reflect(-lightDirection, normalDirection), 
     95                   viewDirection)), _Shininess);
     96             }
     97             return float4(ambientLighting 
     98                + diffuseReflection + specularReflection, 1.0);
     99          }
    100          ENDCG
    101       }
    102  
    103       Pass {    
    104          Tags { "LightMode" = "ForwardAdd" } 
    105             // pass for additional light sources
    106          Blend One One // additive blending
    107 
    108          CGPROGRAM
    109  
    110          #pragma vertex vert  
    111          #pragma fragment frag 
    112  
    113          #include "UnityCG.cginc"
    114          uniform float4 _LightColor0; 
    115             // color of light source (from "Lighting.cginc")
    116  
    117          // User-specified properties
    118          uniform float4 _Color; 
    119          uniform float4 _SpecColor; 
    120          uniform float _Shininess;
    121  
    122          struct vertexInput {
    123             float4 vertex : POSITION;
    124             float3 normal : NORMAL;
    125          };
    126          struct vertexOutput {
    127             float4 pos : SV_POSITION;
    128             float4 posWorld : TEXCOORD0;
    129             float3 normalDir : TEXCOORD1;
    130          };
    131  
    132          vertexOutput vert(vertexInput input) 
    133          {
    134             vertexOutput output;
    135  
    136             float4x4 modelMatrix = _Object2World;
    137             float4x4 modelMatrixInverse = _World2Object;
    138  
    139             output.posWorld = mul(modelMatrix, input.vertex);
    140             output.normalDir = normalize(
    141                mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
    142             output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
    143             return output;
    144          }
    145  
    146          float4 frag(vertexOutput input) : COLOR
    147          {
    148             float3 normalDirection = normalize(input.normalDir);
    149             float3 viewDirection = normalize(
    150                _WorldSpaceCameraPos - input.posWorld.xyz);
    151             float3 lightDirection;
    152             float attenuation;
    153  
    154             if (0.0 == _WorldSpaceLightPos0.w) // directional light?
    155             {
    156                attenuation = 1.0; // no attenuation
    157                lightDirection = normalize(_WorldSpaceLightPos0.xyz);
    158             } 
    159             else // point or spot light
    160             {
    161                float3 vertexToLightSource = 
    162                   _WorldSpaceLightPos0.xyz - input.posWorld.xyz;
    163                float distance = length(vertexToLightSource);
    164                attenuation = 1.0 / distance; // linear attenuation 
    165                lightDirection = normalize(vertexToLightSource);
    166             }
    167  
    168             float3 diffuseReflection = 
    169                attenuation * _LightColor0.rgb * _Color.rgb
    170                * max(0.0, dot(normalDirection, lightDirection));
    171  
    172             float3 specularReflection;
    173             if (dot(normalDirection, lightDirection) < 0.0) 
    174                // light source on the wrong side?
    175             {
    176                specularReflection = float3(0.0, 0.0, 0.0); 
    177                   // no specular reflection
    178             }
    179             else // light source on the right side
    180             {
    181                float3 halfwayDirection = 
    182                   normalize(lightDirection + viewDirection);
    183                float w = pow(1.0 - max(0.0, 
    184                   dot(halfwayDirection, viewDirection)), 5.0);
    185                specularReflection = attenuation * _LightColor0.rgb 
    186                   * lerp(_SpecColor.rgb, float3(1.0, 1.0, 1.0), w) 
    187                   * pow(max(0.0, dot(
    188                   reflect(-lightDirection, normalDirection), 
    189                   viewDirection)), _Shininess);
    190             } 
    191             return float4(diffuseReflection 
    192                + specularReflection, 1.0);
    193          }
    194          ENDCG
    195       }
    196    }
    197    Fallback "Specular"
    198 }
    Fresnel highlights

    Diffuse Reflection of Skylight (about hemisphere lighting)

     1 // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
     2 // Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
     3 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
     4 
     5 Shader "Custom/Cg per-vertex hemisphere lighting" {
     6    Properties {
     7       _Color ("Diffuse Material Color", Color) = (1,1,1,1) 
     8       _UpperHemisphereColor ("Upper Hemisphere Color", Color) 
     9          = (1,1,1,1) 
    10       _LowerHemisphereColor ("Lower Hemisphere Color", Color) 
    11          = (1,1,1,1) 
    12       _UpVector ("Up Vector", Vector) = (0,1,0,0) 
    13    }
    14    SubShader {
    15       Pass {      
    16          CGPROGRAM
    17  
    18          #pragma vertex vert  
    19          #pragma fragment frag 
    20  
    21          #include "UnityCG.cginc"
    22  
    23          // shader properties specified by users
    24          uniform float4 _Color; 
    25          uniform float4 _UpperHemisphereColor;
    26          uniform float4 _LowerHemisphereColor;
    27          uniform float4 _UpVector;
    28  
    29          struct vertexInput {
    30             float4 vertex : POSITION;
    31             float3 normal : NORMAL;
    32          };
    33          struct vertexOutput {
    34             float4 pos : SV_POSITION;
    35             float4 col : COLOR;
    36                // the hemisphere lighting computed in the vertex shader
    37          };
    38  
    39          vertexOutput vert(vertexInput input) 
    40          {
    41             vertexOutput output;
    42  
    43             float4x4 modelMatrix = unity_ObjectToWorld;
    44             float4x4 modelMatrixInverse = unity_WorldToObject; 
    45  
    46             float3 normalDirection = normalize(
    47                mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
    48             float3 upDirection = normalize(_UpVector);
    49  
    50             float w = 0.5 * (1.0 + dot(upDirection, normalDirection));
    51             output.col = (w * _UpperHemisphereColor 
    52                + (1.0 - w) * _LowerHemisphereColor) * _Color;
    53  
    54             output.pos = UnityObjectToClipPos(input.vertex);
    55             return output;
    56          }
    57  
    58          float4 frag(vertexOutput input) : COLOR
    59          {
    60             return input.col;
    61          }
    62  
    63          ENDCG
    64       }
    65    } 
    66 }
    Per-vertex hemisphere lighting

    Translucent Surfaces (about diffuse and forward-scattered transmission of backlight)

      1 // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
      2 // Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
      3 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
      4 
      5 Shader "Custom/Cg translucent surfaces" {
      6    Properties {
      7       _Color ("Diffuse Material Color", Color) = (1,1,1,1) 
      8       _SpecColor ("Specular Material Color", Color) = (1,1,1,1) 
      9       _Shininess ("Shininess", Float) = 10
     10       _DiffuseTranslucentColor ("Diffuse Translucent Color", Color) 
     11          = (1,1,1,1) 
     12       _ForwardTranslucentColor ("Forward Translucent Color", Color) 
     13          = (1,1,1,1) 
     14       _Sharpness ("Sharpness", Float) = 10
     15    }
     16    SubShader {
     17       Pass {      
     18          Tags { "LightMode" = "ForwardBase" } 
     19             // pass for ambient light and first light source
     20          Cull Off // show frontfaces and backfaces
     21  
     22          CGPROGRAM
     23  
     24          #pragma vertex vert  
     25          #pragma fragment frag 
     26  
     27          #include "UnityCG.cginc"
     28          uniform float4 _LightColor0; 
     29             // color of light source (from "Lighting.cginc")
     30  
     31          // User-specified properties
     32          uniform float4 _Color; 
     33          uniform float4 _SpecColor; 
     34          uniform float _Shininess;
     35          uniform float4 _DiffuseTranslucentColor; 
     36          uniform float4 _ForwardTranslucentColor; 
     37          uniform float _Sharpness;
     38  
     39          struct vertexInput {
     40             float4 vertex : POSITION;
     41             float3 normal : NORMAL;
     42          };
     43          struct vertexOutput {
     44             float4 pos : SV_POSITION;
     45             float4 posWorld : TEXCOORD0;
     46             float3 normalDir : TEXCOORD1;
     47          };
     48  
     49          vertexOutput vert(vertexInput input) 
     50          {
     51             vertexOutput output;
     52  
     53             float4x4 modelMatrix = unity_ObjectToWorld;
     54             float4x4 modelMatrixInverse = unity_WorldToObject; 
     55  
     56             output.posWorld = mul(modelMatrix, input.vertex);
     57             output.normalDir = normalize(
     58                mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
     59             output.pos = UnityObjectToClipPos(input.vertex);
     60             return output;
     61          }
     62  
     63          float4 frag(vertexOutput input) : COLOR
     64          {
     65             float3 normalDirection = normalize(input.normalDir);
     66             float3 viewDirection = normalize(
     67                _WorldSpaceCameraPos - input.posWorld.xyz);
     68  
     69             normalDirection = faceforward(normalDirection,
     70                -viewDirection, normalDirection);
     71                // flip normal if dot(-viewDirection, normalDirection)>0
     72  
     73             float3 lightDirection;
     74             float attenuation;
     75  
     76             if (0.0 == _WorldSpaceLightPos0.w) // directional light?
     77             {
     78                attenuation = 1.0; // no attenuation
     79                lightDirection = normalize(_WorldSpaceLightPos0.xyz);
     80             } 
     81             else // point or spot light
     82             {
     83                float3 vertexToLightSource = 
     84                   _WorldSpaceLightPos0.xyz - input.posWorld.xyz;
     85                float distance = length(vertexToLightSource);
     86                attenuation = 1.0 / distance; // linear attenuation 
     87                lightDirection = normalize(vertexToLightSource);
     88             }
     89  
     90             // Computation of the Phong reflection model:
     91  
     92             float3 ambientLighting = 
     93                UNITY_LIGHTMODEL_AMBIENT.rgb * _Color.rgb;
     94  
     95             float3 diffuseReflection = 
     96                attenuation * _LightColor0.rgb * _Color.rgb
     97                * max(0.0, dot(normalDirection, lightDirection));
     98  
     99             float3 specularReflection;
    100             if (dot(normalDirection, lightDirection) < 0.0) 
    101                // light source on the wrong side?
    102             {
    103                specularReflection = float3(0.0, 0.0, 0.0); 
    104                   // no specular reflection
    105             }
    106             else // light source on the right side
    107             {
    108                specularReflection = attenuation * _LightColor0.rgb 
    109                   * _SpecColor.rgb * pow(max(0.0, dot(
    110                   reflect(-lightDirection, normalDirection), 
    111                   viewDirection)), _Shininess);
    112             }
    113  
    114             // Computation of the translucent illumination:
    115  
    116             float3 diffuseTranslucency = 
    117                attenuation * _LightColor0.rgb 
    118                * _DiffuseTranslucentColor.rgb 
    119                * max(0.0, dot(lightDirection, -normalDirection));
    120  
    121             float3 forwardTranslucency;
    122             if (dot(normalDirection, lightDirection) > 0.0) 
    123                // light source on the wrong side?
    124             {
    125                forwardTranslucency = float3(0.0, 0.0, 0.0); 
    126                   // no forward-scattered translucency
    127             }
    128             else // light source on the right side
    129             {
    130                forwardTranslucency = attenuation * _LightColor0.rgb
    131                   * _ForwardTranslucentColor.rgb * pow(max(0.0, 
    132                   dot(-lightDirection, viewDirection)), _Sharpness);
    133             }
    134  
    135             // Computation of the complete illumination:
    136  
    137             return float4(ambientLighting 
    138                + diffuseReflection + specularReflection 
    139                + diffuseTranslucency + forwardTranslucency, 1.0);
    140          }
    141          ENDCG
    142       }
    143  
    144       Pass {      
    145          Tags { "LightMode" = "ForwardAdd" } 
    146             // pass for additional light sources
    147          Cull Off
    148          Blend One One // additive blending 
    149  
    150          CGPROGRAM
    151  
    152          #pragma vertex vert  
    153          #pragma fragment frag 
    154  
    155          #include "UnityCG.cginc"
    156          uniform float4 _LightColor0; 
    157             // color of light source (from "Lighting.cginc")
    158  
    159          // User-specified properties
    160          uniform float4 _Color; 
    161          uniform float4 _SpecColor; 
    162          uniform float _Shininess;
    163          uniform float4 _DiffuseTranslucentColor; 
    164          uniform float4 _ForwardTranslucentColor; 
    165          uniform float _Sharpness;
    166  
    167          struct vertexInput {
    168             float4 vertex : POSITION;
    169             float3 normal : NORMAL;
    170          };
    171          struct vertexOutput {
    172             float4 pos : SV_POSITION;
    173             float4 posWorld : TEXCOORD0;
    174             float3 normalDir : TEXCOORD1;
    175          };
    176  
    177          vertexOutput vert(vertexInput input) 
    178          {
    179             vertexOutput output;
    180  
    181             float4x4 modelMatrix = unity_ObjectToWorld;
    182             float4x4 modelMatrixInverse = unity_WorldToObject;
    183  
    184             output.posWorld = mul(modelMatrix, input.vertex);
    185             output.normalDir = normalize(
    186                mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
    187             output.pos = UnityObjectToClipPos(input.vertex);
    188             return output;
    189          }
    190  
    191          float4 frag(vertexOutput input) : COLOR
    192          {
    193             float3 normalDirection = normalize(input.normalDir);
    194             float3 viewDirection = normalize(
    195                _WorldSpaceCameraPos - input.posWorld.xyz);
    196  
    197             normalDirection = faceforward(normalDirection,
    198                -viewDirection, normalDirection);
    199                // flip normal if dot(-viewDirection, normalDirection)>0
    200  
    201             float3 lightDirection;
    202             float attenuation;
    203  
    204             if (0.0 == _WorldSpaceLightPos0.w) // directional light?
    205             {
    206                attenuation = 1.0; // no attenuation
    207                lightDirection = normalize(_WorldSpaceLightPos0.xyz);
    208             } 
    209             else // point or spot light
    210             {
    211                float3 vertexToLightSource = 
    212                   _WorldSpaceLightPos0.xyz - input.posWorld.xyz;
    213                float distance = length(vertexToLightSource);
    214                attenuation = 1.0 / distance; // linear attenuation 
    215                lightDirection = normalize(vertexToLightSource);
    216             }
    217  
    218             // Computation of the Phong reflection model:
    219  
    220             float3 diffuseReflection = 
    221                attenuation * _LightColor0.rgb * _Color.rgb
    222                * max(0.0, dot(normalDirection, lightDirection));
    223  
    224             float3 specularReflection;
    225             if (dot(normalDirection, lightDirection) < 0.0) 
    226                // light source on the wrong side?
    227             {
    228                specularReflection = float3(0.0, 0.0, 0.0); 
    229                   // no specular reflection
    230             }
    231             else // light source on the right side
    232             {
    233                specularReflection = attenuation * _LightColor0.rgb 
    234                   * _SpecColor.rgb * pow(max(0.0, dot(
    235                   reflect(-lightDirection, normalDirection), 
    236                   viewDirection)), _Shininess);
    237             }
    238  
    239             // Computation of the translucent illumination:
    240  
    241             float3 diffuseTranslucency = 
    242                attenuation * _LightColor0.rgb 
    243                * _DiffuseTranslucentColor.rgb 
    244                * max(0.0, dot(lightDirection, -normalDirection));
    245  
    246             float3 forwardTranslucency;
    247             if (dot(normalDirection, lightDirection) > 0.0) 
    248                // light source on the wrong side?
    249             {
    250                forwardTranslucency = float3(0.0, 0.0, 0.0); 
    251                   // no forward-scattered translucency
    252             }
    253             else // light source on the right side
    254             {
    255                forwardTranslucency = attenuation * _LightColor0.rgb
    256                   * _ForwardTranslucentColor.rgb * pow(max(0.0, 
    257                   dot(-lightDirection, viewDirection)), _Sharpness);
    258             }
    259  
    260             // Computation of the complete illumination:
    261  
    262             return float4(diffuseReflection + specularReflection 
    263                + diffuseTranslucency + forwardTranslucency, 1.0);
    264          }
    265          ENDCG
    266       }
    267    }
    268 }
    Translucent surfaces

    Translucent Bodies (about diffuse lighting with reduced contrast and transmission of diffuse backlight at silhouettes)

      1 Shader "Custom/Cg translucent bodies" {
      2    Properties {
      3       _Color ("Diffuse Color", Color) = (1,1,1,1) 
      4       _Waxiness ("Waxiness", Range(0,1)) = 0
      5       _SpecColor ("Specular Color", Color) = (1,1,1,1) 
      6       _Shininess ("Shininess", Float) = 10
      7       _TranslucentColor ("Translucent Color", Color) = (0,0,0,1)
      8    }
      9    SubShader {
     10       Pass {      
     11          Tags { "LightMode" = "ForwardBase" } // pass for 
     12             // ambient light and first light source on back faces
     13          Cull Front // render back faces only
     14          Blend One Zero // mark rasterized pixels in framebuffer 
     15             // with alpha = 0 (usually they should have alpha = 1)
     16  
     17          CGPROGRAM
     18  
     19          #pragma vertex vert  
     20          #pragma fragment frag 
     21  
     22          #include "UnityCG.cginc"
     23          uniform float4 _LightColor0; 
     24             // color of light source (from "Lighting.cginc")
     25  
     26          // User-specified properties
     27          uniform float4 _Color; 
     28          uniform float _Waxiness;
     29          uniform float4 _SpecColor; 
     30          uniform float _Shininess;
     31          uniform float4 _TranslucentColor; 
     32  
     33          struct vertexInput {
     34             float4 vertex : POSITION;
     35             float3 normal : NORMAL;
     36          };
     37          struct vertexOutput {
     38             float4 pos : SV_POSITION;
     39             float4 posWorld : TEXCOORD0;
     40             float3 normalDir : TEXCOORD1;
     41          };
     42  
     43          vertexOutput vert(vertexInput input) 
     44          {
     45             vertexOutput output;
     46  
     47             float4x4 modelMatrix = _Object2World;
     48             float4x4 modelMatrixInverse = _World2Object; 
     49  
     50             output.posWorld = mul(modelMatrix, input.vertex);
     51             output.normalDir = normalize(
     52                mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
     53             output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
     54             return output;
     55          }
     56  
     57          float4 frag(vertexOutput input) : COLOR
     58          {
     59             float3 normalDirection = normalize(input.normalDir);
     60  
     61             float3 viewDirection = normalize(
     62                _WorldSpaceCameraPos - input.posWorld.xyz);
     63             float3 lightDirection;
     64             float attenuation;
     65  
     66             if (0.0 == _WorldSpaceLightPos0.w) // directional light?
     67             {
     68                attenuation = 1.0; // no attenuation
     69                lightDirection = normalize(_WorldSpaceLightPos0.xyz);
     70             } 
     71             else // point or spot light
     72             {
     73                float3 vertexToLightSource = 
     74                   _WorldSpaceLightPos0.xyz - input.posWorld.xyz;
     75                float distance = length(vertexToLightSource);
     76                attenuation = 1.0 / distance; // linear attenuation 
     77                lightDirection = normalize(vertexToLightSource);
     78             }
     79  
     80             float3 ambientLighting = _TranslucentColor.rgb
     81                * UNITY_LIGHTMODEL_AMBIENT.rgb;
     82  
     83             float3 diffuseReflection = _TranslucentColor.rgb
     84                * attenuation * _LightColor0.rgb
     85                * max(0.0, dot(normalDirection, lightDirection));
     86  
     87  
     88             float silhouetteness = 
     89                1.0 - abs(dot(viewDirection, normalDirection));
     90  
     91             return float4(silhouetteness 
     92                * (ambientLighting + diffuseReflection), 0.0);
     93          }
     94  
     95          ENDCG
     96       }
     97  
     98       Pass {      
     99          Tags { "LightMode" = "ForwardAdd" } 
    100             // pass for additional light sources on back faces
    101          Cull Front // render back faces only
    102          Blend One One // additive blending 
    103  
    104          CGPROGRAM
    105  
    106          #pragma vertex vert  
    107          #pragma fragment frag 
    108  
    109          #include "UnityCG.cginc"
    110          uniform float4 _LightColor0; 
    111             // color of light source (from "Lighting.cginc")
    112  
    113          // User-specified properties
    114          uniform float4 _Color; 
    115          uniform float _Waxiness;
    116          uniform float4 _SpecColor; 
    117          uniform float _Shininess;
    118          uniform float4 _TranslucentColor; 
    119  
    120          struct vertexInput {
    121             float4 vertex : POSITION;
    122             float3 normal : NORMAL;
    123          };
    124          struct vertexOutput {
    125             float4 pos : SV_POSITION;
    126             float4 posWorld : TEXCOORD0;
    127             float3 normalDir : TEXCOORD1;
    128          };
    129  
    130          vertexOutput vert(vertexInput input) 
    131          {
    132             vertexOutput output;
    133  
    134             float4x4 modelMatrix = _Object2World;
    135             float4x4 modelMatrixInverse = _World2Object;
    136  
    137             output.posWorld = mul(modelMatrix, input.vertex);
    138             output.normalDir = normalize(
    139                mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
    140             output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
    141             return output;
    142          }
    143  
    144          float4 frag(vertexOutput input) : COLOR
    145          {
    146             float3 normalDirection = normalize(input.normalDir);
    147  
    148             float3 viewDirection = normalize(
    149                _WorldSpaceCameraPos - input.posWorld.xyz);
    150             float3 lightDirection;
    151             float attenuation;
    152  
    153             if (0.0 == _WorldSpaceLightPos0.w) // directional light?
    154             {
    155                attenuation = 1.0; // no attenuation
    156                lightDirection = normalize(_WorldSpaceLightPos0.xyz);
    157             } 
    158             else // point or spot light
    159             {
    160                float3 vertexToLightSource = 
    161                   _WorldSpaceLightPos0.xyz - input.posWorld.xyz;
    162                float distance = length(vertexToLightSource);
    163                attenuation = 1.0 / distance; // linear attenuation 
    164                lightDirection = normalize(vertexToLightSource);
    165             }
    166  
    167             float3 diffuseReflection = _TranslucentColor.rgb
    168                * attenuation * _LightColor0.rgb
    169                * max(0.0, dot(normalDirection, lightDirection));
    170  
    171             float silhouetteness = 
    172                1.0 - abs(dot(viewDirection, normalDirection));
    173  
    174             return float4(silhouetteness * diffuseReflection, 0.0);
    175          }
    176  
    177          ENDCG
    178       }
    179  
    180       Pass {    
    181          Tags { "LightMode" = "ForwardBase" } // pass for 
    182             // setting pixels that were not rasterized to black
    183          Cull Back // render front faces only (default behavior)
    184          Blend Zero OneMinusDstAlpha // set colors of pixels 
    185             // with alpha = 1 to black by multiplying with 1-alpha
    186  
    187          CGPROGRAM 
    188  
    189          #pragma vertex vert 
    190          #pragma fragment frag
    191  
    192          float4 vert(float4 vertexPos : POSITION) : SV_POSITION 
    193          {
    194             return mul(UNITY_MATRIX_MVP, vertexPos);
    195          }
    196  
    197          float4 frag(void) : COLOR 
    198          {
    199             return float4(0.0, 0.0, 0.0, 0.0); 
    200          }
    201          ENDCG  
    202       }
    203  
    204       Pass {      
    205          Tags { "LightMode" = "ForwardBase" } // pass for 
    206             // ambient light and first light source on front faces
    207          Cull Back // render front faces only
    208          Blend One SrcAlpha // multiply color in framebuffer 
    209             // with silhouetteness in fragment's alpha and add colors
    210  
    211          CGPROGRAM
    212  
    213          #pragma vertex vert  
    214          #pragma fragment frag 
    215  
    216          #include "UnityCG.cginc"
    217          uniform float4 _LightColor0; 
    218             // color of light source (from "Lighting.cginc")
    219  
    220          // User-specified properties
    221          uniform float4 _Color; 
    222          uniform float _Waxiness;
    223          uniform float4 _SpecColor; 
    224          uniform float _Shininess;
    225          uniform float4 _TranslucentColor; 
    226  
    227          struct vertexInput {
    228             float4 vertex : POSITION;
    229             float3 normal : NORMAL;
    230          };
    231          struct vertexOutput {
    232             float4 pos : SV_POSITION;
    233             float4 posWorld : TEXCOORD0;
    234             float3 normalDir : TEXCOORD1;
    235          };
    236  
    237          vertexOutput vert(vertexInput input) 
    238          {
    239             vertexOutput output;
    240  
    241             float4x4 modelMatrix = _Object2World;
    242             float4x4 modelMatrixInverse = _World2Object;
    243  
    244             output.posWorld = mul(modelMatrix, input.vertex);
    245             output.normalDir = normalize(
    246                mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
    247             output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
    248             return output;
    249          }
    250  
    251          float4 frag(vertexOutput input) : COLOR
    252          {
    253             float3 normalDirection = normalize(input.normalDir);
    254  
    255             float3 viewDirection = normalize(
    256                _WorldSpaceCameraPos - input.posWorld.xyz);
    257             float3 lightDirection;
    258             float attenuation;
    259  
    260             if (0.0 == _WorldSpaceLightPos0.w) // directional light?
    261             {
    262                attenuation = 1.0; // no attenuation
    263                lightDirection = normalize(_WorldSpaceLightPos0.xyz);
    264             } 
    265             else // point or spot light
    266             {
    267                float3 vertexToLightSource = 
    268                   _WorldSpaceLightPos0.xyz - input.posWorld.xyz;
    269                float distance = length(vertexToLightSource);
    270                attenuation = 1.0 / distance; // linear attenuation 
    271                lightDirection = normalize(vertexToLightSource);
    272             }
    273  
    274             float3 ambientLighting = 
    275                UNITY_LIGHTMODEL_AMBIENT.rgb * _Color.rgb;
    276  
    277             float3 diffuseReflection = 
    278                attenuation * _LightColor0.rgb * _Color.rgb
    279                * (_Waxiness + (1.0 - _Waxiness) 
    280                * max(0.0, dot(normalDirection, lightDirection)));
    281  
    282             float3 specularReflection;
    283             if (dot(normalDirection, lightDirection) < 0.0) 
    284                // light source on the wrong side?
    285             {
    286                specularReflection = float3(0.0, 0.0, 0.0); 
    287                   // no specular reflection
    288             }
    289             else // light source on the right side
    290             {
    291                specularReflection = attenuation * _LightColor0.rgb 
    292                   * _SpecColor.rgb * pow(max(0.0, dot(
    293                   reflect(-lightDirection, normalDirection), 
    294                   viewDirection)), _Shininess);
    295             }
    296  
    297             float silhouetteness = 
    298                1.0 - abs(dot(viewDirection, normalDirection));
    299  
    300             return float4(ambientLighting + diffuseReflection 
    301                + specularReflection, silhouetteness);
    302          }
    303  
    304          ENDCG 
    305       }
    306  
    307       Pass {      
    308          Tags { "LightMode" = "ForwardAdd" } 
    309             // pass for additional light sources on front faces
    310          Cull Back // render front faces only
    311          Blend One One // additive blending 
    312  
    313          CGPROGRAM
    314  
    315          #pragma vertex vert  
    316          #pragma fragment frag 
    317  
    318          #include "UnityCG.cginc"
    319          uniform float4 _LightColor0; 
    320             // color of light source (from "Lighting.cginc")
    321  
    322          // User-specified properties
    323          uniform float4 _Color; 
    324          uniform float _Waxiness;
    325          uniform float4 _SpecColor; 
    326          uniform float _Shininess;
    327          uniform float4 _TranslucentColor; 
    328  
    329          struct vertexInput {
    330             float4 vertex : POSITION;
    331             float3 normal : NORMAL;
    332          };
    333          struct vertexOutput {
    334             float4 pos : SV_POSITION;
    335             float4 posWorld : TEXCOORD0;
    336             float3 normalDir : TEXCOORD1;
    337          };
    338  
    339          vertexOutput vert(vertexInput input) 
    340          {
    341             vertexOutput output;
    342  
    343             float4x4 modelMatrix = _Object2World;
    344             float4x4 modelMatrixInverse = _World2Object;
    345  
    346             output.posWorld = mul(modelMatrix, input.vertex);
    347             output.normalDir = normalize(
    348                mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
    349             output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
    350             return output;
    351          }
    352  
    353          float4 frag(vertexOutput input) : COLOR
    354          {
    355             float3 normalDirection = normalize(input.normalDir);
    356  
    357             float3 viewDirection = normalize(
    358                _WorldSpaceCameraPos - input.posWorld.xyz);
    359             float3 lightDirection;
    360             float attenuation;
    361  
    362             if (0.0 == _WorldSpaceLightPos0.w) // directional light?
    363             {
    364                attenuation = 1.0; // no attenuation
    365                lightDirection = normalize(_WorldSpaceLightPos0.xyz);
    366             } 
    367             else // point or spot light
    368             {
    369                float3 vertexToLightSource = 
    370                   _WorldSpaceLightPos0.xyz - input.posWorld.xyz;
    371                float distance = length(vertexToLightSource);
    372                attenuation = 1.0 / distance; // linear attenuation 
    373                lightDirection = normalize(vertexToLightSource);
    374             }
    375  
    376             float3 diffuseReflection = 
    377                attenuation * _LightColor0.rgb * _Color.rgb
    378                * (_Waxiness + (1.0 - _Waxiness) 
    379                * max(0.0, dot(normalDirection, lightDirection)));
    380  
    381             float3 specularReflection;
    382             if (dot(normalDirection, lightDirection) < 0.0) 
    383                // light source on the wrong side?
    384             {
    385                specularReflection = float3(0.0, 0.0, 0.0); 
    386                   // no specular reflection
    387             }
    388             else // light source on the right side
    389             {
    390                specularReflection = attenuation * _LightColor0.rgb 
    391                   * _SpecColor.rgb * pow(max(0.0, dot(
    392                   reflect(-lightDirection, normalDirection), 
    393                   viewDirection)), _Shininess);
    394             }
    395  
    396             float silhouetteness = 
    397                1.0 - abs(dot(viewDirection, normalDirection));
    398  
    399             return float4(diffuseReflection 
    400                + specularReflection, silhouetteness);
    401          }
    402  
    403          ENDCG 
    404       }
    405    } 
    406    Fallback "Specular"
    407 }
    Translucent bodies

    Soft Shadows of Spheres (about rendering the umbra and penumbra of spheres)

      1 // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
      2 // Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
      3 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
      4 
      5 Shader "Custom/Cg shadow of sphere" {
      6    Properties {
      7       _Color ("Diffuse Material Color", Color) = (1,1,1,1) 
      8       _SpecColor ("Specular Material Color", Color) = (1,1,1,1) 
      9       _Shininess ("Shininess", Float) = 10
     10       _SpherePosition ("Sphere Position", Vector) = (0,0,0,1)
     11       _SphereRadius ("Sphere Radius", Float) = 1
     12       _LightSourceRadius ("Light Source Radius", Float) = 0.005
     13    }
     14    SubShader {
     15       Pass {      
     16          Tags { "LightMode" = "ForwardBase" } 
     17             // pass for ambient light and first light source
     18  
     19          CGPROGRAM
     20  
     21          #pragma vertex vert  
     22          #pragma fragment frag 
     23  
     24          #pragma target 3.0
     25  
     26          #include "UnityCG.cginc"
     27          uniform float4 _LightColor0; 
     28             // color of light source (from "Lighting.cginc")
     29  
     30          // User-specified properties
     31          uniform float4 _Color; 
     32          uniform float4 _SpecColor; 
     33          uniform float _Shininess;
     34          uniform float4 _SpherePosition; 
     35             // center of shadow-casting sphere in world coordinates
     36          uniform float _SphereRadius; 
     37             // radius of shadow-casting sphere
     38          uniform float _LightSourceRadius; 
     39             // in radians for directional light sources
     40  
     41          struct vertexInput {
     42             float4 vertex : POSITION;
     43             float3 normal : NORMAL;
     44          };
     45          struct vertexOutput {
     46             float4 pos : SV_POSITION;
     47             float4 posWorld : TEXCOORD0;
     48             float3 normalDir : TEXCOORD1;
     49          };
     50  
     51          vertexOutput vert(vertexInput input) 
     52          {
     53             vertexOutput output;
     54  
     55             float4x4 modelMatrix = unity_ObjectToWorld;
     56             float4x4 modelMatrixInverse = unity_WorldToObject;
     57  
     58             output.posWorld = mul(modelMatrix, input.vertex);
     59             output.normalDir = normalize(
     60                mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
     61             output.pos = UnityObjectToClipPos(input.vertex);
     62             return output;
     63          }
     64  
     65          float4 frag(vertexOutput input) : COLOR
     66          {
     67             float3 normalDirection = normalize(input.normalDir);
     68  
     69             float3 viewDirection = normalize(
     70                _WorldSpaceCameraPos - input.posWorld.xyz);
     71             float3 lightDirection;
     72             float lightDistance;
     73             float attenuation;
     74  
     75             if (0.0 == _WorldSpaceLightPos0.w) // directional light?
     76             {
     77                attenuation = 1.0; // no attenuation
     78                lightDirection = 
     79                   normalize(_WorldSpaceLightPos0.xyz);
     80                lightDistance = 1.0;
     81             } 
     82             else // point or spot light
     83             {
     84                lightDirection = 
     85                   _WorldSpaceLightPos0.xyz - input.posWorld.xyz;
     86                lightDistance = length(lightDirection);
     87                attenuation = 1.0 / lightDistance; // linear attenuation
     88                lightDirection = lightDirection / lightDistance;
     89             }
     90  
     91             // computation of level of shadowing w  
     92             float3 sphereDirection = 
     93                _SpherePosition.xyz - input.posWorld.xyz;
     94             float sphereDistance = length(sphereDirection);
     95             sphereDirection = sphereDirection / sphereDistance;
     96             float d = lightDistance 
     97                * (asin(min(1.0, 
     98                length(cross(lightDirection, sphereDirection)))) 
     99                - asin(min(1.0, _SphereRadius / sphereDistance)));
    100             float w = smoothstep(-1.0, 1.0, -d / _LightSourceRadius);
    101             w = w * smoothstep(0.0, 0.2, 
    102                dot(lightDirection, sphereDirection));
    103             if (0.0 != _WorldSpaceLightPos0.w) // point light source?
    104             {
    105                w = w * smoothstep(0.0, _SphereRadius, 
    106                   lightDistance - sphereDistance);
    107             }
    108  
    109             float3 ambientLighting = 
    110                UNITY_LIGHTMODEL_AMBIENT.rgb * _Color.rgb;
    111  
    112             float3 diffuseReflection = 
    113                attenuation * _LightColor0.rgb * _Color.rgb
    114                * max(0.0, dot(normalDirection, lightDirection));
    115  
    116             float3 specularReflection;
    117             if (dot(normalDirection, lightDirection) < 0.0) 
    118                // light source on the wrong side?
    119             {
    120                specularReflection = float3(0.0, 0.0, 0.0); 
    121                   // no specular reflection
    122             }
    123             else // light source on the right side
    124             {
    125                specularReflection = attenuation * _LightColor0.rgb 
    126                   * _SpecColor.rgb * pow(max(0.0, dot(
    127                   reflect(-lightDirection, normalDirection), 
    128                   viewDirection)), _Shininess);
    129             }
    130  
    131             return float4(ambientLighting 
    132                + (1.0 - w) * (diffuseReflection + specularReflection), 
    133                1.0);
    134          }
    135  
    136          ENDCG
    137       }
    138  
    139       Pass {      
    140          Tags { "LightMode" = "ForwardAdd" } 
    141             // pass for additional light sources
    142          Blend One One // additive blending 
    143  
    144          CGPROGRAM
    145  
    146          #pragma vertex vert  
    147          #pragma fragment frag 
    148  
    149          #pragma target 3.0
    150  
    151          #include "UnityCG.cginc"
    152          uniform float4 _LightColor0; 
    153             // color of light source (from "Lighting.cginc")
    154  
    155          // User-specified properties
    156          uniform float4 _Color; 
    157          uniform float4 _SpecColor; 
    158          uniform float _Shininess;
    159          uniform float4 _SpherePosition; 
    160             // center of shadow-casting sphere in world coordinates
    161          uniform float _SphereRadius; 
    162             // radius of shadow-casting sphere
    163          uniform float _LightSourceRadius; 
    164             // in radians for directional light sources
    165  
    166          struct vertexInput {
    167             float4 vertex : POSITION;
    168             float3 normal : NORMAL;
    169          };
    170          struct vertexOutput {
    171             float4 pos : SV_POSITION;
    172             float4 posWorld : TEXCOORD0;
    173             float3 normalDir : TEXCOORD1;
    174          };
    175  
    176          vertexOutput vert(vertexInput input) 
    177          {
    178             vertexOutput output;
    179  
    180             float4x4 modelMatrix = unity_ObjectToWorld;
    181             float4x4 modelMatrixInverse = unity_WorldToObject;
    182  
    183             output.posWorld = mul(modelMatrix, input.vertex);
    184             output.normalDir = normalize(
    185                mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
    186             output.pos = UnityObjectToClipPos(input.vertex);
    187             return output;
    188          }
    189  
    190          float4 frag(vertexOutput input) : COLOR
    191          {
    192             float3 normalDirection = normalize(input.normalDir);
    193  
    194             float3 viewDirection = normalize(
    195                _WorldSpaceCameraPos - input.posWorld.xyz);
    196             float3 lightDirection;
    197             float lightDistance;
    198             float attenuation;
    199  
    200             if (0.0 == _WorldSpaceLightPos0.w) // directional light?
    201             {
    202                attenuation = 1.0; // no attenuation
    203                lightDirection = normalize(_WorldSpaceLightPos0.xyz);
    204                lightDistance = 1.0;
    205             } 
    206             else // point or spot light
    207             {
    208                lightDirection =
    209                   _WorldSpaceLightPos0.xyz - input.posWorld.xyz;
    210                lightDistance = length(lightDirection);
    211                attenuation = 1.0 / lightDistance; // linear attenuation
    212                lightDirection = lightDirection / lightDistance;
    213             }
    214  
    215             // computation of level of shadowing w  
    216             float3 sphereDirection = 
    217                _SpherePosition.xyz - input.posWorld.xyz;
    218             float sphereDistance = length(sphereDirection);
    219             sphereDirection = sphereDirection / sphereDistance;
    220             float d = lightDistance 
    221                * (asin(min(1.0, 
    222                length(cross(lightDirection, sphereDirection)))) 
    223                - asin(min(1.0, _SphereRadius / sphereDistance)));
    224             float w = smoothstep(-1.0, 1.0, -d / _LightSourceRadius);
    225             w = w * smoothstep(0.0, 0.2, 
    226                dot(lightDirection, sphereDirection));
    227             if (0.0 != _WorldSpaceLightPos0.w) // point light source?
    228             {
    229                w = w * smoothstep(0.0, _SphereRadius, 
    230                   lightDistance - sphereDistance);
    231             }
    232  
    233             float3 diffuseReflection = 
    234                attenuation * _LightColor0.rgb * _Color.rgb
    235                * max(0.0, dot(normalDirection, lightDirection));
    236  
    237             float3 specularReflection;
    238             if (dot(normalDirection, lightDirection) < 0.0) 
    239                // light source on the wrong side?
    240             {
    241                specularReflection = float3(0.0, 0.0, 0.0); 
    242                   // no specular reflection
    243             }
    244             else // light source on the right side
    245             {
    246                specularReflection = attenuation * _LightColor0.rgb 
    247                   * _SpecColor.rgb * pow(max(0.0, dot(
    248                   reflect(-lightDirection, normalDirection), 
    249                   viewDirection)), _Shininess);
    250             }
    251  
    252             return float4((1.0 - w) * (diffuseReflection 
    253                + specularReflection), 1.0);
    254          }
    255  
    256          ENDCG
    257       }
    258    } 
    259    Fallback "Specular"
    260 }
    Shadow of sphere

    Toon Shading (about non-photorealistic rendering)

      1 // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
      2 // Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
      3 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
      4 
      5 Shader "Custom/Cg shader for toon shading" {
      6    Properties {
      7       _Color ("Diffuse Color", Color) = (1,1,1,1) 
      8       _UnlitColor ("Unlit Diffuse Color", Color) = (0.5,0.5,0.5,1) 
      9       _DiffuseThreshold ("Threshold for Diffuse Colors", Range(0,1)) 
     10          = 0.1 
     11       _OutlineColor ("Outline Color", Color) = (0,0,0,1)
     12       _LitOutlineThickness ("Lit Outline Thickness", Range(0,1)) = 0.1
     13       _UnlitOutlineThickness ("Unlit Outline Thickness", Range(0,1)) 
     14          = 0.4
     15       _SpecColor ("Specular Color", Color) = (1,1,1,1) 
     16       _Shininess ("Shininess", Float) = 10
     17    }
     18    SubShader {
     19       Pass {      
     20          Tags { "LightMode" = "ForwardBase" } 
     21             // pass for ambient light and first light source
     22  
     23          CGPROGRAM
     24  
     25          #pragma vertex vert  
     26          #pragma fragment frag 
     27  
     28          #include "UnityCG.cginc"
     29          uniform float4 _LightColor0; 
     30             // color of light source (from "Lighting.cginc")
     31  
     32          // User-specified properties
     33          uniform float4 _Color; 
     34          uniform float4 _UnlitColor;
     35          uniform float _DiffuseThreshold;
     36          uniform float4 _OutlineColor;
     37          uniform float _LitOutlineThickness;
     38          uniform float _UnlitOutlineThickness;
     39          uniform float4 _SpecColor; 
     40          uniform float _Shininess;
     41  
     42          struct vertexInput {
     43             float4 vertex : POSITION;
     44             float3 normal : NORMAL;
     45          };
     46          struct vertexOutput {
     47             float4 pos : SV_POSITION;
     48             float4 posWorld : TEXCOORD0;
     49             float3 normalDir : TEXCOORD1;
     50          };
     51  
     52          vertexOutput vert(vertexInput input) 
     53          {
     54             vertexOutput output;
     55  
     56             float4x4 modelMatrix = unity_ObjectToWorld;
     57             float4x4 modelMatrixInverse = unity_WorldToObject; 
     58  
     59             output.posWorld = mul(modelMatrix, input.vertex);
     60             output.normalDir = normalize(
     61                mul(float4(input.normal, 0.0), modelMatrixInverse).xyz);
     62             output.pos = UnityObjectToClipPos(input.vertex);
     63             return output;
     64          }
     65  
     66          float4 frag(vertexOutput input) : COLOR
     67          {
     68             float3 normalDirection = normalize(input.normalDir);
     69  
     70             float3 viewDirection = normalize(
     71                _WorldSpaceCameraPos - input.posWorld.xyz);
     72             float3 lightDirection;
     73             float attenuation;
     74  
     75             if (0.0 == _WorldSpaceLightPos0.w) // directional light?
     76             {
     77                attenuation = 1.0; // no attenuation
     78                lightDirection = normalize(_WorldSpaceLightPos0.xyz);
     79             } 
     80             else // point or spot light
     81             {
     82                float3 vertexToLightSource = 
     83                   _WorldSpaceLightPos0.xyz - input.posWorld.xyz;
     84                float distance = length(vertexToLightSource);
     85                attenuation = 1.0 / distance; // linear attenuation 
     86                lightDirection = normalize(vertexToLightSource);
     87             }
     88   
     89             // default: unlit 
     90             float3 fragmentColor = _UnlitColor.rgb; 
     91  
     92             // low priority: diffuse illumination
     93             if (attenuation 
     94                * max(0.0, dot(normalDirection, lightDirection)) 
     95                >= _DiffuseThreshold)
     96             {
     97                fragmentColor = _LightColor0.rgb * _Color.rgb; 
     98             }
     99  
    100             // higher priority: outline
    101             if (dot(viewDirection, normalDirection) 
    102                < lerp(_UnlitOutlineThickness, _LitOutlineThickness, 
    103                max(0.0, dot(normalDirection, lightDirection))))
    104             {
    105                fragmentColor = _LightColor0.rgb * _OutlineColor.rgb; 
    106             }
    107  
    108             // highest priority: highlights
    109             if (dot(normalDirection, lightDirection) > 0.0 
    110                // light source on the right side?
    111                && attenuation *  pow(max(0.0, dot(
    112                reflect(-lightDirection, normalDirection), 
    113                viewDirection)), _Shininess) > 0.5) 
    114                // more than half highlight intensity? 
    115             {
    116                fragmentColor = _SpecColor.a 
    117                   * _LightColor0.rgb * _SpecColor.rgb
    118                   + (1.0 - _SpecColor.a) * fragmentColor;
    119             }
    120             return float4(fragmentColor, 1.0);
    121          }
    122          ENDCG
    123       }
    124  
    125       Pass {      
    126          Tags { "LightMode" = "ForwardAdd" } 
    127             // pass for additional light sources
    128          Blend SrcAlpha OneMinusSrcAlpha 
    129             // blend specular highlights over framebuffer
    130  
    131          CGPROGRAM
    132  
    133          #pragma vertex vert  
    134          #pragma fragment frag 
    135  
    136          #include "UnityCG.cginc"
    137          uniform float4 _LightColor0; 
    138             // color of light source (from "Lighting.cginc")
    139  
    140          // User-specified properties
    141          uniform float4 _Color; 
    142          uniform float4 _UnlitColor;
    143          uniform float _DiffuseThreshold;
    144          uniform float4 _OutlineColor;
    145          uniform float _LitOutlineThickness;
    146          uniform float _UnlitOutlineThickness;
    147          uniform float4 _SpecColor; 
    148          uniform float _Shininess;
    149  
    150          struct vertexInput {
    151             float4 vertex : POSITION;
    152             float3 normal : NORMAL;
    153          };
    154          struct vertexOutput {
    155             float4 pos : SV_POSITION;
    156             float4 posWorld : TEXCOORD0;
    157             float3 normalDir : TEXCOORD1;
    158          };
    159  
    160          vertexOutput vert(vertexInput input) 
    161          {
    162             vertexOutput output;
    163  
    164             float4x4 modelMatrix = unity_ObjectToWorld;
    165             float4x4 modelMatrixInverse = unity_WorldToObject;
    166  
    167             output.posWorld = mul(modelMatrix, input.vertex);
    168             output.normalDir = normalize(
    169                mul(float4(input.normal, 0.0), modelMatrixInverse).rgb);
    170             output.pos = UnityObjectToClipPos(input.vertex);
    171             return output;
    172          }
    173  
    174          float4 frag(vertexOutput input) : COLOR
    175          {
    176             float3 normalDirection = normalize(input.normalDir);
    177  
    178             float3 viewDirection = normalize(
    179                _WorldSpaceCameraPos - input.posWorld.rgb);
    180             float3 lightDirection;
    181             float attenuation;
    182  
    183             if (0.0 == _WorldSpaceLightPos0.w) // directional light?
    184             {
    185                attenuation = 1.0; // no attenuation
    186                lightDirection = normalize(_WorldSpaceLightPos0.xyz);
    187             } 
    188             else // point or spot light
    189             {
    190                float3 vertexToLightSource = 
    191                   _WorldSpaceLightPos0.xyz - input.posWorld.xyz;
    192                float distance = length(vertexToLightSource);
    193                attenuation = 1.0 / distance; // linear attenuation 
    194                lightDirection = normalize(vertexToLightSource);
    195             }
    196  
    197             float4 fragmentColor = float4(0.0, 0.0, 0.0, 0.0);
    198             if (dot(normalDirection, lightDirection) > 0.0 
    199                // light source on the right side?
    200                && attenuation *  pow(max(0.0, dot(
    201                reflect(-lightDirection, normalDirection), 
    202                viewDirection)), _Shininess) > 0.5) 
    203                // more than half highlight intensity? 
    204             {
    205                fragmentColor = 
    206                   float4(_LightColor0.rgb, 1.0) * _SpecColor;
    207             }
    208             return fragmentColor;
    209          }
    210          ENDCG
    211       }
    212    } 
    213    Fallback "Specular"
    214 }
    Shader for toon shading

    Non-Standard Vertex Transformations

    Screen Overlays (about a direct transformation from object space to screen space)

     1 Shader "Custom/Cg shader for screen overlays" {
     2    Properties {
     3       _MainTex ("Texture", Rect) = "white" {}
     4       _Color ("Color", Color) = (1.0, 1.0, 1.0, 1.0)
     5       _X ("X", Float) = 0.0
     6       _Y ("Y", Float) = 0.0
     7       _Width ("Width", Float) = 128
     8       _Height ("Height", Float) = 128
     9    }
    10    SubShader {
    11       Tags { "Queue" = "Overlay" } // render after everything else
    12  
    13       Pass {
    14          Blend SrcAlpha OneMinusSrcAlpha // use alpha blending
    15          ZTest Always // deactivate depth test
    16  
    17          CGPROGRAM
    18  
    19          #pragma vertex vert  
    20          #pragma fragment frag
    21 
    22          #include "UnityCG.cginc" 
    23            // defines float4 _ScreenParams with x = width;  
    24            // y = height; z = 1 + 1.0/width; w = 1 + 1.0/height
    25            // and defines float4 _ProjectionParams 
    26            // with x = 1 or x = -1 for flipped projection matrix;
    27            // y = near clipping plane; z = far clipping plane; and
    28            // w = 1 / far clipping plane
    29  
    30          // User-specified uniforms
    31          uniform sampler2D _MainTex;
    32          uniform float4 _Color;
    33          uniform float _X;
    34          uniform float _Y;
    35          uniform float _Width;
    36          uniform float _Height;
    37  
    38          struct vertexInput {
    39             float4 vertex : POSITION;
    40             float4 texcoord : TEXCOORD0;
    41          };
    42          struct vertexOutput {
    43             float4 pos : SV_POSITION;
    44             float4 tex : TEXCOORD0;
    45          };
    46  
    47          vertexOutput vert(vertexInput input) 
    48          {
    49             vertexOutput output;
    50  
    51             float2 rasterPosition = float2(
    52                _X + _ScreenParams.x / 2.0 
    53                + _Width * (input.vertex.x + 0.5),
    54                _Y + _ScreenParams.y / 2.0 
    55                + _Height * (input.vertex.y + 0.5));
    56             output.pos = float4(
    57                2.0 * rasterPosition.x / _ScreenParams.x - 1.0,
    58                _ProjectionParams.x * (2.0 * rasterPosition.y / _ScreenParams.y - 1.0),
    59                _ProjectionParams.y, // near plane is at -1.0 or at 0.0
    60                1.0);
    61  
    62             output.tex = float4(input.vertex.x + 0.5, 
    63                input.vertex.y + 0.5, 0.0, 0.0);
    64                // for a cube, vertex.x and vertex.y 
    65                // are -0.5 or 0.5
    66             return output;
    67          }
    68  
    69          float4 frag(vertexOutput input) : COLOR
    70          {
    71             return _Color * tex2D(_MainTex, input.tex.xy);   
    72          }
    73  
    74          ENDCG
    75       }
    76    }
    77 }
    Shader for screen overlays

    Billboards (about view-aligned projection of objects)

     1 Shader "Custom/Cg  shader for billboards" {
     2    Properties {
     3       _MainTex ("Texture Image", 2D) = "white" {}
     4       _ScaleX ("Scale X", Float) = 1.0
     5       _ScaleY ("Scale Y", Float) = 1.0
     6    }
     7    SubShader {
     8       Pass {   
     9          CGPROGRAM
    10  
    11          #pragma vertex vert  
    12          #pragma fragment frag
    13 
    14          // User-specified uniforms            
    15          uniform sampler2D _MainTex;        
    16          uniform float _ScaleX;
    17          uniform float _ScaleY;
    18 
    19          struct vertexInput {
    20             float4 vertex : POSITION;
    21             float4 tex : TEXCOORD0;
    22          };
    23          struct vertexOutput {
    24             float4 pos : SV_POSITION;
    25             float4 tex : TEXCOORD0;
    26          };
    27  
    28          vertexOutput vert(vertexInput input) 
    29          {
    30             vertexOutput output;
    31 
    32             output.pos = mul(UNITY_MATRIX_P, 
    33               mul(UNITY_MATRIX_MV, float4(0.0, 0.0, 0.0, 1.0))
    34               + float4(input.vertex.x, input.vertex.y, 0.0, 0.0)
    35               * float4(_ScaleX, _ScaleY, 1.0, 1.0));
    36  
    37             output.tex = input.tex;
    38 
    39             return output;
    40          }
    41  
    42          float4 frag(vertexOutput input) : COLOR
    43          {
    44             return tex2D(_MainTex, float2(input.tex.xy));   
    45          }
    46  
    47          ENDCG
    48       }
    49    }
    50 }
    Shader for billboards

    Nonlinear Deformations (about vertex blending)

     1 Shader "Custom/Cg shader for vertex blending" {
     2    SubShader {
     3       Pass {   
     4          CGPROGRAM
     5  
     6          #pragma vertex vert  
     7          #pragma fragment frag 
     8  
     9          #include "UnityCG.cginc"
    10  
    11          // Uniforms set by a script
    12          uniform float4x4 _Trafo0; // model transformation of bone0
    13          uniform float4x4 _Trafo1; // model transformation of bone1
    14  
    15          struct vertexInput {
    16             float4 vertex : POSITION;
    17          };
    18          struct vertexOutput {
    19             float4 pos : SV_POSITION;
    20             float4 col : COLOR;
    21          };
    22  
    23          vertexOutput vert(vertexInput input) 
    24          {
    25             vertexOutput output;
    26  
    27             float weight0 = input.vertex.z + 0.5; 
    28                // depends on the mesh
    29             float4 blendedVertex = 
    30                weight0 * mul(_Trafo0, input.vertex) 
    31                + (1.0 - weight0) * mul(_Trafo1, input.vertex);
    32  
    33             output.pos = mul(UNITY_MATRIX_VP, blendedVertex);
    34  
    35             output.col = float4(weight0, 1.0 - weight0, 0.0, 1.0); 
    36                // visualize weight0 as red and weight1 as green
    37             return output;
    38          }
    39  
    40          float4 frag(vertexOutput input) : COLOR
    41          {
    42             return input.col;
    43          }
    44  
    45          ENDCG
    46       }
    47    }
    48 }
    Shader for vertex blending

    Shadows on Planes (about projecting shadows onto planes)

      1 // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
      2 // Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
      3 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
      4 
      5 Shader "Custom/Cg planar shadow" {
      6    Properties {
      7       _Color ("Object's Color", Color) = (0,1,0,1)
      8       _ShadowColor ("Shadow's Color", Color) = (0,0,0,1)
      9    }
     10    SubShader {
     11       Pass {      
     12          Tags { "LightMode" = "ForwardBase" } // rendering of object
     13  
     14          CGPROGRAM
     15  
     16          #pragma vertex vert 
     17          #pragma fragment frag
     18  
     19          // User-specified properties
     20          uniform float4 _Color; 
     21  
     22          float4 vert(float4 vertexPos : POSITION) : SV_POSITION 
     23          {
     24             return UnityObjectToClipPos(vertexPos);
     25          }
     26  
     27          float4 frag(void) : COLOR
     28          {
     29             return _Color; 
     30          }
     31  
     32          ENDCG 
     33       }
     34  
     35       Pass {   
     36          Tags { "LightMode" = "ForwardBase" } 
     37             // rendering of projected shadow
     38          Offset -1.0, -2.0 
     39             // make sure shadow polygons are on top of shadow receiver
     40  
     41          CGPROGRAM
     42  
     43          #pragma vertex vert 
     44          #pragma fragment frag
     45  
     46          #include "UnityCG.cginc"
     47  
     48          // User-specified uniforms
     49          uniform float4 _ShadowColor;
     50          uniform float4x4 _World2Receiver; // transformation from 
     51             // world coordinates to the coordinate system of the plane
     52  
     53          float4 vert(float4 vertexPos : POSITION) : SV_POSITION
     54          {
     55             float4x4 modelMatrix = unity_ObjectToWorld;
     56             float4x4 modelMatrixInverse = unity_WorldToObject; 
     57             float4x4 viewMatrix = 
     58                mul(UNITY_MATRIX_MV, modelMatrixInverse);
     59  
     60             float4 lightDirection;
     61             if (0.0 != _WorldSpaceLightPos0.w) 
     62             {
     63                // point or spot light
     64                lightDirection = normalize(
     65                   mul(modelMatrix, vertexPos - _WorldSpaceLightPos0));
     66             } 
     67             else 
     68             {
     69                // directional light
     70                lightDirection = -normalize(_WorldSpaceLightPos0); 
     71             }
     72  
     73             float4 vertexInWorldSpace = mul(modelMatrix, vertexPos);
     74             float4 world2ReceiverRow1 = 
     75                float4(_World2Receiver[1][0], _World2Receiver[1][1], 
     76                _World2Receiver[1][2], _World2Receiver[1][3]);
     77             float distanceOfVertex = 
     78                dot(world2ReceiverRow1, vertexInWorldSpace); 
     79                // = (_World2Receiver * vertexInWorldSpace).y 
     80                // = height over plane 
     81             float lengthOfLightDirectionInY = 
     82                dot(world2ReceiverRow1, lightDirection); 
     83                // = (_World2Receiver * lightDirection).y 
     84                // = length in y direction
     85  
     86             if (distanceOfVertex > 0.0 && lengthOfLightDirectionInY < 0.0)
     87             {
     88                lightDirection = lightDirection 
     89                   * (distanceOfVertex / (-lengthOfLightDirectionInY));
     90             }
     91             else
     92             {
     93                lightDirection = float4(0.0, 0.0, 0.0, 0.0); 
     94                   // don't move vertex
     95             }
     96  
     97             return mul(UNITY_MATRIX_VP,  
     98                vertexInWorldSpace + lightDirection);
     99          }
    100  
    101          float4 frag(void) : COLOR 
    102          {
    103             return _ShadowColor;
    104          }
    105  
    106          ENDCG 
    107       }
    108    }
    109 }
    Planar shadow

    Image Effects and Compute Shaders

    Minimal Image Effect (about basic image post-processing with fragment shaders)

     1 // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
     2 
     3 Shader "Custom/tintImageEffectShader"
     4 {
     5    Properties
     6    {
     7       _MainTex ("Source", 2D) = "white" {}
     8       _Color ("Tint", Color) = (1,1,1,1)
     9    }
    10    SubShader
    11    {
    12       Cull Off 
    13       ZWrite Off 
    14       ZTest Always
    15 
    16       Pass
    17       {
    18          CGPROGRAM
    19          #pragma vertex vertexShader
    20          #pragma fragment fragmentShader
    21             
    22          #include "UnityCG.cginc"
    23 
    24          struct vertexInput
    25          {
    26             float4 vertex : POSITION;
    27             float2 texcoord : TEXCOORD0;
    28          };
    29 
    30          struct vertexOutput
    31          {
    32             float2 texcoord : TEXCOORD0;
    33             float4 position : SV_POSITION;
    34          };
    35 
    36          vertexOutput vertexShader(vertexInput i)
    37          {
    38             vertexOutput o;
    39             o.position = UnityObjectToClipPos(i.vertex);
    40             o.texcoord = i.texcoord;
    41             return o;
    42          }
    43             
    44          sampler2D _MainTex;
    45          float4 _MainTex_ST;
    46          float4 _Color;
    47 
    48          float4 fragmentShader(vertexOutput i) : COLOR
    49          {
    50             float4 color = tex2D(_MainTex, 
    51                UnityStereoScreenSpaceUVAdjust(
    52                i.texcoord, _MainTex_ST));        
    53             return color * _Color;
    54          }
    55          ENDCG
    56       }
    57    }
    58    Fallback Off
    59 }
    TintImageEffectShader

    Miscellaneous

    General Cg Topics

    Overview of the Programmable Graphics Pipeline

    Vertex Transformations (Modeling, Viewing, Projection, and Viewport Transformations)

    Vector and Matrix Operations in Cg (includes references about Cg syntax)

    Applying Matrix Transformations to Points, Directions, and Normals in Cg

    Rasterization (Interpolation of Per-Fragment Varying Parameters)

    Per-Fragment Operations (Stencil Test, Depth Test and Blending, etc.)

    Anti-Aliasing Techniques

    Phong Reflection Model

  • 相关阅读:
    带色彩恢复的多尺度视网膜增强算法(MSRCR)的原理、实现及应用。
    索引图像的那些事啊
    调整图像 自动对比度、自动色阶算法
    图像处理界双线性插值算法的优化
    共享收集的图像处理方面的一些资源和网站。
    Wellner 自适应阈值二值化算法
    基于灰度世界、完美反射、动态阈值等图像自动白平衡算法的原理、实现及效果
    VB6.0用GDI+保存图像为BMP\JPG\PNG\GIF格式终结版。
    关于.net中获取图像缩略图的函数GetThumbnailImage的一些认识。
    限制对比度自适应直方图均衡化算法原理、实现及效果
  • 原文地址:https://www.cnblogs.com/revoid/p/7890276.html
Copyright © 2011-2022 走看看