Unity3D 成神之路Unity Shader分享Unity教程合集

Shader编程(三)纹理贴图、法线映射与Alpha透明度

2017-08-22  本文已影响18人  _凉笙

Shader"Texture"{
    properties{
        _Color("Color",Color) = (1,1,1,1)
        _MainText("Main Tex",2D) = "White"{}
        _Specular("Specular Color",Color) = (1,1,1,1)//控制高光颜色
       _Gloss("Gloss",Range(8,200)) = 10//控制高光强度

    }
        SubShader{

        Pass {

            //定义正确的LightMode得到内置的光照变量
            Tags{"LightMode" = "ForwardBase"}

            CGPROGRAM
            //包含unity的内置的文件,才可以使用unity内置的一些变量  相当于引入内置的光照模型
            #include "Lighting.cginc"//取得第一个直射光的颜色  _LightColor0第一个值是光的位置_WorldSpaceLightPos0

            #pragma vertex vert
            #pragma fragment frag

                      // fixed4 _Diffuse;
                  sampler2D _MainText;
                  fixed4 _Color;
                  float4 _MainText_ST;//固定写法定义UV贴图偏移值缩放值
                   half _Gloss;
                   fixed4 _Specular;

            struct a2v {
               float4 vertex:POSITION;
               float3 normal:NORMAL; 
               float2 texcoord:TEXCOORD0;
              };
        struct v2f {
        
            float4 position:SV_POSITION;
            float3 WorldNomormal : TEXCOORD0;
            float3 WorldVertex:TEXCOORD1;
            float2 uv:TEXCOORD2;


        }; 
        v2f vert(a2v v) {
                v2f f;
                //UNITY_MATRIX_MVP 这个矩阵用来把一个坐标从模型空间转换到剪裁空间
                f.position = mul(UNITY_MATRIX_MVP, v.vertex);
    
                f.WorldNomormal = mul(v.normal, (float3x3)unity_WorldToObject);
                f.WorldVertex = mul(v.vertex,unity_WorldToObject).xyz;
                f.uv = v.texcoord.xy* _MainText_ST.xy+ _MainText_ST.zw;//计算纹理的偏移值和缩放值
                return f;
        };

        fixed4 frag(v2f f) :SV_Target{

    
         //_World2Object 这个矩阵用来把一个方向从世界空间转换到模型空间
        fixed3 normalDir = normalize(f.WorldNomormal);//相当于把模型空间转换到世界空间

        fixed3 lightDir = normalize(_WorldSpaceLightPos0.xyz);//对于每一个顶点来说 光的位置就是光的方向  因为光是平行光

         fixed3 texColor=tex2D(_MainText,f.uv.xy)*_Color.rgb;

        fixed3 diffuse = _LightColor0.rgb*texColor*max(dot(normalDir, lightDir),0);//取得漫反射的颜色

        fixed3 reflectDir = normalize(reflect(-lightDir, normalDir));
        fixed3 vlewDir = normalize(_WorldSpaceCameraPos.xyz - f.WorldVertex);

        fixed3 specular = _LightColor0.rgb*_Specular.rgb*pow(max(dot(reflectDir, vlewDir), 0), _Gloss);//计算高光

        fixed3 tempColor = diffuse +  specular+ UNITY_LIGHTMODEL_AMBIENT.rgb*texColor;

            return fixed4(tempColor,1);

        }
            ENDCG
       }
    }
        Fallback"Diffuse"
}
Paste_Image.png
纹理材质.gif

法线贴图与凹凸映射的强度

Shader"Rock"{
    properties{
        _Color("Color",Color) = (1,1,1,1)
        _MainTex("Main Tex",2D) = "White"{}
        _NormalMap("Normal Map",2D) = "bump"{}//bump使用顶点里面自带的法线贴图
        _BumpScale("Bump Scale",Float)=1
    }
        SubShader{

        Pass {

            //定义正确的LightMode得到内置的光照变量
            Tags{"LightMode" = "ForwardBase"}

            CGPROGRAM


#include "Lighting.cginc"//取得第一个直射光的颜色  _LightColor0第一个值是光的位置_WorldSpaceLightPos0


        
            

            #pragma vertex vert
            #pragma fragment frag

                  fixed4 _Color;
                  sampler2D _MainTex;
                  float4 _MainTex_ST;//固定写法定义UV贴图偏移值缩放值
                  sampler2D _NormalMap;
                  float4 _NormalMap_ST;//固定写法定义UV贴图偏移值缩放值
                  float _BumpScale;

            struct a2v {
               float4 vertex:POSITION;
               //切线空间的确定是通过(存储到模型里面的)法线和(存储到模型里面的)切线确定的
               float3 normal:NORMAL; 
               float4 tangent:TANGENT;//tangent.w是用来确定切线空间中坐标轴的方向的

               float2 texcoord:TEXCOORD0;
              };
        struct v2f {
        
            float4 position:SV_POSITION;
            //float3 WorldNomormal : TEXCOORD0;

            float3 lightDir : TEXCOORD0;//切线空间下 平行光的方向
            
            float4 uv:TEXCOORD1;//xy用来存储MainTex的纹理坐标, zw用来存储法线贴图的纹理坐标


        }; 
        v2f vert(a2v v) {
                v2f f;
                //UNITY_MATRIX_MVP 这个矩阵用来把一个坐标从模型空间转换到剪裁空间
                f.position = mul(UNITY_MATRIX_MVP, v.vertex);
    
                /*f.WorldNomormal = mul(v.normal, (float3x3)unity_WorldToObject);*/
                
                f.uv.xy = v.texcoord.xy * _MainTex_ST.xy+ _MainTex_ST.zw;//计算纹理的偏移值和缩放值
                f.uv.zw = v.texcoord.xy * _NormalMap_ST.xy + _NormalMap_ST.zw;
                
                TANGENT_SPACE_ROTATION;//调用这个后,会得到一个矩阵 rotation 这个矩阵用来把模型空间下的方向装换成切线空间下

                //ObjspaceLightDir(v.vertex)//得到模型空间下的平行光方向

                f.lightDir = mul(rotation, ObjSpaceLightDir(v.vertex));

                return f;
        };
        //把所有的跟法线方向有关的运算都放在切线空间下
        //从法线贴图里面取得的法线方向是在切线空间下的
        fixed4 frag(v2f f) :SV_Target{

    
         //_World2Object 这个矩阵用来把一个方向从世界空间转换到模型空间
        //fixed3 normalDir = normalize(f.WorldNomormal);//相当于把模型空间转换到世界空间

        fixed4 normalColor= tex2D(_NormalMap,f.uv.zw);


        //pixel = (normal + 1) / 2

        //normal = pixel * 2 - 1
        
        fixed3 tangentNormal = UnpackNormal( normalColor);  //切线空间下的法线

        tangentNormal.xy = tangentNormal.xy*_BumpScale;

        tangentNormal = normalize(tangentNormal);

        fixed3 lightDir = normalize(f.lightDir);//对于每一个顶点来说 光的位置就是光的方向  因为光是平行光

        fixed3 texColor=tex2D(_MainTex,f.uv.xy)*_Color.rgb;

        fixed3 diffuse = _LightColor0.rgb*texColor*max(dot(tangentNormal, lightDir),0);//取得漫反射的颜色

        fixed3 tempColor = diffuse + UNITY_LIGHTMODEL_AMBIENT.rgb*texColor;

    return fixed4(tempColor,1);

        }
            ENDCG
       }
    }
        Fallback"Spacular"
}
凹凸贴图.gif

编写透明的Shader

Shader"Rock Alpha" {
    properties{
        _Color("Color",Color) = (1,1,1,1)
        _MainTex("Main Tex",2D) = "White"{}
        _NormalMap("Normal Map",2D) = "bump"{}//bump使用顶点里面自带的法线贴图
        _BumpScale("Bump Scale",Float)=1
        _Alpha("Alpha",Float)=1
    }
        SubShader{

            Tags{"Queue"="Transparent""IngnoreProjector"="True""RanderType"="Transparent"}//"Queue"="Transparent"透明的渲染队列  "IngnoreProjector"="True"是否忽略投影 "RanderType"="Transparent"类型

        Pass {

            //定义正确的LightMode得到内置的光照变量
            Tags{"LightMode" = "ForwardBase"}

            ZWrite off//写入透明深度
            Blend SrcAlpha OneMinusSrcAlpha//透明混合参数


            CGPROGRAM


            #include "Lighting.cginc"//取得第一个直射光的颜色  _LightColor0第一个值是光的位置_WorldSpaceLightPos0
            #pragma vertex vert
            #pragma fragment frag

                  fixed4 _Color;
                  sampler2D _MainTex;
                  float4 _MainTex_ST;//固定写法定义UV贴图偏移值缩放值
                  sampler2D _NormalMap;
                  float4 _NormalMap_ST;//固定写法定义UV贴图偏移值缩放值
                  float _BumpScale;
                  float _Alpha;

            struct a2v {
               float4 vertex:POSITION;
               //切线空间的确定是通过(存储到模型里面的)法线和(存储到模型里面的)切线确定的
               float3 normal:NORMAL; 
               float4 tangent:TANGENT;//tangent.w是用来确定切线空间中坐标轴的方向的

               float2 texcoord:TEXCOORD0;
              };
        struct v2f {
        
            float4 position:SV_POSITION;
            //float3 WorldNomormal : TEXCOORD0;

            float3 lightDir : TEXCOORD0;//切线空间下 平行光的方向
            
            float4 uv:TEXCOORD1;//xy用来存储MainTex的纹理坐标, zw用来存储法线贴图的纹理坐标


        }; 
        v2f vert(a2v v) {
                v2f f;
                //UNITY_MATRIX_MVP 这个矩阵用来把一个坐标从模型空间转换到剪裁空间
                f.position = mul(UNITY_MATRIX_MVP, v.vertex);
    
                /*f.WorldNomormal = mul(v.normal, (float3x3)unity_WorldToObject);*/
                
                f.uv.xy = v.texcoord.xy * _MainTex_ST.xy+ _MainTex_ST.zw;//计算纹理的偏移值和缩放值
                f.uv.zw = v.texcoord.xy * _NormalMap_ST.xy + _NormalMap_ST.zw;
                
                TANGENT_SPACE_ROTATION;//调用这个后,会得到一个矩阵 rotation 这个矩阵用来把模型空间下的方向装换成切线空间下

                //ObjspaceLightDir(v.vertex)//得到模型空间下的平行光方向

                f.lightDir = mul(rotation, ObjSpaceLightDir(v.vertex));

                return f;
        };
        //把所有的跟法线方向有关的运算都放在切线空间下
        //从法线贴图里面取得的法线方向是在切线空间下的
        fixed4 frag(v2f f) :SV_Target{

    
         //_World2Object 这个矩阵用来把一个方向从世界空间转换到模型空间
        //fixed3 normalDir = normalize(f.WorldNomormal);//相当于把模型空间转换到世界空间

        fixed4 normalColor= tex2D(_NormalMap,f.uv.zw);


        //pixel = (normal + 1) / 2

        //normal = pixel * 2 - 1
        
        fixed3 tangentNormal = UnpackNormal( normalColor);  //切线空间下的法线

        tangentNormal.xy = tangentNormal.xy*_BumpScale;

        tangentNormal = normalize(tangentNormal);

        fixed3 lightDir = normalize(f.lightDir);//对于每一个顶点来说 光的位置就是光的方向  因为光是平行光

        fixed4 texColor=tex2D(_MainTex,f.uv.xy)*_Color;

        fixed3 diffuse = _LightColor0.rgb*texColor.rgb*max(dot(tangentNormal, lightDir),0);//取得漫反射的颜色

        fixed3 tempColor = diffuse + UNITY_LIGHTMODEL_AMBIENT.rgb*texColor;

    return fixed4(tempColor, _Alpha*texColor.a);

        }
            ENDCG
       }
    }
        Fallback"Spacular"
}
写入透明度.gif
上一篇下一篇

猜你喜欢

热点阅读