1. 程式人生 > >[UnityShader2]頂點片段著色器例項(三)

[UnityShader2]頂點片段著色器例項(三)

原文連結:http://www.cnblogs.com/Esfog/default.html?page=2

1.漫反射

Shader "Esfog/Diffuse" 
{
    Properties 
    {
        _MainTex ("Base (RGB)", 2D) = "white" {}
    }
    SubShader 
    {
        Pass
        {
            Tags { "RenderType"="Opaque" "LightMode"="ForwardBase"}
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            uniform sampler2D _MainTex;
            uniform float4    _LightColor0;
            struct VertexOutput 
            {
                float4 pos:SV_POSITION;
                float2 uv_MainTex:TEXCOORD0;
                float3 normal:TEXCOORD1;
            };

            VertexOutput vert(appdata_base input)
            {
                VertexOutput o;
                o.pos = mul(UNITY_MATRIX_MVP,input.vertex);
                o.uv_MainTex = input.texcoord.xy;
                o.normal = normalize(mul(float4(input.normal,0),_World2Object));
                return o;
            }

            float4 frag(VertexOutput input):COLOR
            {
                float3 normalDir = normalize(input.normal);
                float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
                float3 Kd = tex2D(_MainTex,input.uv_MainTex).xyz;
                float3 diffuseReflection = Kd * _LightColor0.rgb * max(0,dot(normalDir,lightDir));
                return float4(diffuseReflection,1);
            }
            ENDCG
        }
    } 
    FallBack "Diffuse"
}

2.鏡面反射
Shader "Esfog/SpecularReflection"
{
    Properties 
    {
        _MainTex ("Base (RGB)", 2D) = "white" {}
        _SpecColor("SpecularColor",Color) = (1,1,1,1)
        _Shininess("Shininess",Float) = 10
    }
    SubShader 
    {
        Pass
        {
            Tags { "RenderType"="Opaque" "LightMode"="ForwardBase"}
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            #pragma target 5.0
            uniform float4 _LightColor0;
            uniform sampler2D _MainTex;
            uniform float _Shininess;
            uniform float4 _SpecColor;
            struct VertexOutput 
            {
                float4 pos:SV_POSITION;
                float4 posWorld:TEXCOORD0;
                float3 normal:TEXCOORD1;
                float2 uv:TEXCOORD2;
            };

            VertexOutput vert(appdata_base input)
            {
                VertexOutput o;
                o.pos = mul(UNITY_MATRIX_MVP,input.vertex);
                o.posWorld = mul(_Object2World,input.vertex);
                o.normal = normalize(mul(float4(input.normal,0.0),_World2Object).xyz);
                o.uv = input.texcoord.xy;
                return o;
            }

            float4 frag(VertexOutput input):COLOR
            {
                float3 normalDir = normalize(input.normal);
                float3 viewDir = normalize(float3(_WorldSpaceCameraPos - input.posWorld));
                float4 Kd = tex2D(_MainTex,input.uv);
                float4 Ks = _SpecColor;
                float4 Ka = Kd;
                float3 lightDir = normalize(_WorldSpaceLightPos0.xyz);
                float3 ambientLighting = Ka.rgb * UNITY_LIGHTMODEL_AMBIENT.rgb;
                float3 diffuseReflection = Kd.rgb * _LightColor0.rgb * max(0.0,dot(normalDir,lightDir));
                float facing;
                if(dot(normalDir,lightDir)<=0)
                {
                    facing = 0;
                }
                else
                {
                    facing = 1;
                }
                float3 SpecularReflection = facing * _LightColor0.rgb * _SpecColor.rgb * pow(max(0,dot(reflect(-lightDir,normalDir),viewDir)),_Shininess);
                return float4(ambientLighting + diffuseReflection + SpecularReflection,1);
            }
            ENDCG    
        }
    } 
    FallBack "Diffuse"
}

3.法線貼圖(環境光+漫反射光+鏡面反射光+法線貼圖)
Shader "Esfog/NormalMap" 
{
    Properties 
    {
        _MainTex ("Base (RGB)", 2D) = "white" {}
        _NormalMap("NormalMap",2D) = "Bump"{}
        _SpecColor("SpecularColor",Color) = (1,1,1,1)
        _Shininess("Shininess",Float) = 10
    }
    SubShader 
    {
        
        Pass
        {
            Tags { "LightMode"="ForwardBase" }
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            uniform sampler2D _MainTex;
            uniform sampler2D _NormalMap;
            uniform float4 _SpecColor;
            uniform float _Shininess;
            uniform float4 _LightColor0;

            struct VertexOutput 
            {
                float4 pos:SV_POSITION;
                float2 uv:TEXCOORD0;
                float3 lightDir:TEXCOORD1;
                float3 viewDir:TEXCOORD2;
            };

            VertexOutput vert(appdata_tan v)
            {
                VertexOutput o;
                o.pos = mul(UNITY_MATRIX_MVP,v.vertex);
                o.uv = v.texcoord.xy;

                //float3 normal = v.normal;
                //float3 tangent = v.tangent;
                //float3 binormal= cross(v.normal,v.tangent.xyz) * v.tangent.w;
                //float3x3 Object2TangentMatrix = float3x3(tangent,binormal,normal);
                //o.lightDir = mul(Object2TangentMatrix,ObjSpaceLightDir(v.vertex));
                //o.viewDir = mul(Object2TangentMatrix,ObjSpaceViewDir(v.vertex));
                //上面註釋掉的等價於下面的
                //將本地空間的光線方向,觀察方向轉換為切線空間,方便與切線空間的法線進行計算
                TANGENT_SPACE_ROTATION;
                o.lightDir = mul(rotation,ObjSpaceLightDir(v.vertex));
                o.viewDir = mul(rotation,ObjSpaceViewDir(v.vertex));

                return o;
            }

            float4 frag(VertexOutput input):COLOR
            {
                float3 lightDir = normalize(input.lightDir);
                float3 viewDir = normalize(input.viewDir);

                //float4 encodedNormal = tex2D(_NormalMap,input.uv);
                //float3 normal = float3(2.0*encodedNormal.ag - 1,0.0);
                //normal.z = sqrt(1 - dot(normal,normal));
                //上面註釋掉的等價於下面的
                float3 normal = UnpackNormal(tex2D(_NormalMap, input.uv));

                float4 texColor = tex2D(_MainTex,input.uv);
                float3 ambient = texColor.rgb * UNITY_LIGHTMODEL_AMBIENT.rgb;
                float3 diffuseReflection = texColor.rgb * _LightColor0.rgb * max(0,dot(normal,lightDir));
                float facing;
                if(dot(normal,lightDir)<0)
                {
                    facing = 0;
                }
                else
                {
                    facing = 1;
                }
                float3 specularRelection = _SpecColor.rgb * _LightColor0.rgb * facing * pow(max(0,dot(reflect(-lightDir,normal),viewDir)),_Shininess);

                return float4(ambient + diffuseReflection + specularRelection,1);
            }
            ENDCG
        }
        
    } 
    FallBack "Diffuse"
}

4.幀動畫

Shader "Esfog/SpriteUV" 
{
    Properties 
    {
        _SpriteTex ("SpriteTexture (RGB)", 2D) = "white" {}
        _SpriteRowCount ("RowCounts",float) = 0
        _SpriteColumnCount ("ColumnCounts",float) = 0
        _Speed ("AnimationSpeed",Range(0.01,10)) = 4
    }
    SubShader 
    {
        Pass
        {
            Tags { "RenderType"="Opaque" }
            
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            
            uniform sampler2D _SpriteTex;
            uniform float _SpriteRowCount;
            uniform float _SpriteColumnCount;
            uniform float _Speed;
            
            struct VertexOutput
            {
                float4 pos:SV_POSITION;
                float2 uv:TEXCOORD0;
            };

            VertexOutput vert(appdata_base input)
            {
                VertexOutput o;
                o.pos = mul(UNITY_MATRIX_MVP,input.vertex);
                o.uv = input.texcoord.xy;
                return o;
            }
            
            float4 frag(VertexOutput input):COLOR
            {
				float perSecondFrame = 1 / _Speed;//每秒幀數
				int frameNum = _Time.y / perSecondFrame;//當前幀數
                float totalSpriteCount = _SpriteRowCount * _SpriteColumnCount;//總幀數
				frameNum = fmod(frameNum,totalSpriteCount);

				int rowIndex = frameNum / _SpriteColumnCount;//第幾行
				int columnIndex = fmod(frameNum,_SpriteColumnCount);//第幾列
				rowIndex = _SpriteRowCount - rowIndex - 1;//因為uv跟播放動畫的順序不一致

                float rowAvgPercent = 1 / _SpriteColumnCount;//每行單個sprited的uv比例
                float columnAvgPercent = 1 / _SpriteRowCount;//每列單個sprited的uv比例
				
				float2 spriteUV = input.uv;
				spriteUV.x = (spriteUV.x + columnIndex) * rowAvgPercent;
                spriteUV.y = (spriteUV.y + rowIndex) * columnAvgPercent; 
				 
				float4 col = tex2D(_SpriteTex,spriteUV);
                return col; 
            }           
            ENDCG
        }
    } 
    FallBack "Diffuse"
}