【Unity Shaders and Effects Cookbook】Diffuse Shading

1. 基礎的shader 寫法

Shader "CookbookShaders/BasicDiffuse" 
{
    Properties     
    {
           _MainTex(“Base(RGB)”,2D) = “white”{}
    }
    
    SubShader 
    {
        Tags { "RenderType"="Opaque" }
        LOD 200
        
        CGPROGRAM
        #pragma surface surf Lambert
         sampler2D _MainTex;
         struct Input
        {
             float2 uv_MainTex;
         };
        
        void surf (Input IN, inout SurfaceOutput o) 
        {
            float4 c;
            c =  tex2D((_MainTex, IN.uv_MainTex);
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }
        
        ENDCG
    } 
    
    FallBack "Diffuse"
}



Adding Properties to a Surface Shader

1 Properties 塊創建UI模塊,從而在UI 中控制輸入Shader中的變量,就像D3D 中的set


比如 EmissiveColor ("Emissive Color", Color) = (1,1,1,1) 表示顏色,默認值(1,1,1,1)

2 接下來在Subshader中CGPROGRAM下面聲明 properties 中的變量

        float4 _EmissiveColor;
        float4 _AmbientColor;
        float _MySliderValue;

3 把放射光(Emissivecolor)+ 環境光(Ambientcolor)  相加,用pow 函數處理,指數來自UI的滑動slider

        void surf (Input IN, inout SurfaceOutput o)
        {
            float4 c;
            c =  pow((_EmissiveColor + _AmbientColor), _MySliderValue);
           
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }

創建一個自定義的漫反射光照模型

1. 修改#pragma,告訴Shader 使用BasicDiffu 光照模型

      # pragma surface surf BasicDiffuse

2. 在SubShder中 添加下面的代碼

  inline float4 LightingBasicDiffuse(Surfaceoutput s, fixed3 lightDir, fixed atten)
{
   float difLight = max(0, dot(s.Normal, lightDir));
  float4  col;
   col.rgb = s.Albedo * _LightColor0.rgb * (difLight * atten * 2);
   col.a = s.Alpha;
    return col; 
}

   其中,創建一個新的光照模型函數,有三種光照模型可以使用,如下

   half4 LightingName(SurfaceOutput s, half3 lightDir, half atten) {}  不要使用viewDir

   half4 LightingName(SurfaceOutput s, half3 lightDir, half3 viewDir, half atten) 需要使用view

   half4 LightingName(SurfanceOutput s, half4 light){}

 

  dot 函數判斷兩個空間向量的方向是平行(1)還是垂直(-1)

創建 Half Lambert 光照模型

Half Lambert 是通過閾值調整低光區的表面光照(as a way of getting the lighting to show the surface

of an object in low-light areas)。Half Lambert光照模型是Valve公司在製作”半條命“遊戲時發明的,用來給在比較暗的區域顯示物體。總體來說,該光照模型提高了物體表面的漫反射光。

        inline float4 LightingBasicDiffuse (SurfaceOutput s, fixed3 lightDir, fixed atten)
        {
            float difLight = dot (s.Normal, lightDir);
            float hLambert = difLight * 0.5 + 0.5; 
            
            float4 col;
            col.rgb = s.Albedo * _LightColor0.rgb * (hLambert * atten * 2);
            col.a = s.Alpha;
            return col;
        }

     如上,Half Lambert 技術,通過 乘以0.5 ,加上0.5 , 實現把範圍調整到0.5 ~ 1.0


Shader "CookbookShaders/Chapter1/HalfLambertDiffuse" 
{
    Properties     
    {
        _EmissiveColor ("Emissive Color", Color) = (1,1,1,1)
        _AmbientColor  ("Ambient Color", Color) = (1,1,1,1)
        _MySliderValue ("This is a Slider", Range(0,10)) = 2.5
    }
    
    SubShader 
    {
        Tags { "RenderType"="Opaque" }
        LOD 200
        
        CGPROGRAM
        #pragma surface surf BasicDiffuse
        #pragma target 3.0
        float4 _EmissiveColor;
        float4 _AmbientColor;
        float _MySliderValue;
        
        inline float4 LightingBasicDiffuse (SurfaceOutput s, fixed3 lightDir, fixed atten)
        {
            float difLight = dot (s.Normal, lightDir);
            float hLambert = difLight * 0.5 + 0.5; 
            
            float4 col;
            col.rgb = s.Albedo * _LightColor0.rgb * (hLambert * atten * 2);
            col.a = s.Alpha;
            return col;
        }
        struct Input 
        {
            float2 uv_MainTex;
        };
        void surf (Input IN, inout SurfaceOutput o) 
        {
            float4 c;
            c =  pow((_EmissiveColor + _AmbientColor), _MySliderValue);
            
            o.Albedo = c.rgb;
            o.Alpha = c.a;
        }
        
        ENDCG
    } 
    
    FallBack "Diffuse"
}





發佈了95 篇原創文章 · 獲贊 14 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章