美文网首页Unity3D 成神之路Unity Shader分享Unity教程合集
Shader编程(三)纹理贴图、法线映射与Alpha透明度

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

作者: _凉笙 | 来源:发表于2017-08-22 14:23 被阅读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

    相关文章

      网友评论

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

        本文链接:https://www.haomeiwen.com/subject/bfxldxtx.html