【Unity Shaders】Mobile Shader Adjustment —— 為手機定製Shader

來源:互聯網
上載者:User

標籤:shader   unity   移動平台   

本系列主要參考《Unity Shaders and Effects Cookbook》一書(感謝原書作者),同時會加上一點個人理解或拓展。

這裡是本書所有的插圖。這裡是本書所需的代碼和資源(當然你也可以從官網下載)。

========================================== 分割線 ==========================================



寫在前面


在上一篇裡,我們學習了一些技巧來初步最佳化Shader。這次,我們學習更多的技術來實現一個更複雜的Shader:Normal-Mapped Specular Shader。這些技術包括:使用光照函數的兩個新變數halfasview或者approxview,減少使用的貼圖數量,以及對貼圖進行更好的壓縮。



準備工作


  1. 建立一個新的情境和一個球體,添加一個平行光。
  2. 建立一個新的Shader和Material,可以命名為MobileShader。
  3. 把Shader賦給Material,把Material賦給球體。

實現
  1. 首先,還是修改Properties塊。本節我們需要一張diffuse貼圖,它的alpha通道值對應像素的光滑度(Gloss);以及一張法線貼圖,和高光指數的滑動條。
    Properties {_Diffuse ("Base (RGB) Specular Amount (A)", 2D) = "white" {}_NormalMap ("Normal Map", 2D) = "bump"{}_SpecIntensity ("Specular Width", Range(0.01, 1)) = 0.5}

    解釋:一直沒有徹底搞懂Unity SurfaceOutput裡面各變數的計算細節。這裡再詳細解釋下。SurfaceOutput裡面的內建變數可以見這篇,如下:
    struct SurfaceOutput {      half3 Albedo;      // 該像素的反射率,反應了像素的基色     half3 Normal;     // 該像素的法線方向    half3 Emission;   // 該像素的自發光顏色,使得即便沒有光照也可以物體本身也可以發出光    half Specular;     // 該像素的高光指數      half Gloss;         // 該像素的高光光滑度,值越大高光反射越清晰,反之越模糊      half Alpha;         // 該像素的不透明度 };

  2. 下面是建立#pragma聲明。這可以控制Surface Shader各屬性的開關,使得Shader更高效或者更低效:
    CGPROGRAM#pragma surface surf MobileBlinnPhong exclude_path:prepass nolightmap noforwardadd halfasview

    解釋:忽略延遲光照,不支援光照貼圖,只接受一個單一的平行光光源作為逐像素光源。最後,使用halfasview聲明告訴Unity,我們使用一個介於光照方向和觀察方向之間的half vector來代替真正的觀察方向viewDir來計算光照函數。這將加速Shader的處理時間,因為這是基於逐頂點而非逐像素計算而得的。雖然這樣得到的結果是近似值,但對於移動平台來說足夠了。

  3. 建立和Properties塊中各變數的聯絡。和之前不同,我們這次使用fixed來得到高光指數滑條的值:
    sampler2D _Diffuse;sampler2D _NormalMap;fixed _SpecIntensity;

  4. 得到貼圖的UV座標。在上一篇就提過,為了節省變數空間,我們僅使用一個UV值:
    struct Input {half2 uv_Diffuse;};

  5. 由於我們在聲明中添加了新的變數,我們可以在光照函數中使用新的參數:
    inline fixed4 LightingMobileBlinnPhong (SurfaceOutput s, fixed3 lightDir, fixed3 halfDir, fixed atten){fixed diff = max (0, dot (s.Normal, lightDir));fixed nh = max (0, dot (s.Normal, halfDir));fixed spec = pow (nh, s.Specular * 128) * s.Gloss;fixed4 c;c.rgb = (s.Albedo * _LightColor0.rgb * diff + _LightColor0.rgb * spec) * (atten * 2);c.a = 0.0;return c;}

  6. 最後,我們在surf函數中完成對像素顏色的計算:
    void surf (Input IN, inout SurfaceOutput o) {fixed4 diffuseTex = tex2D (_Diffuse, IN.uv_Diffuse);o.Albedo = diffuseTex.rgb;o.Gloss = diffuseTex.a;o.Alpha = 0.0;o.Specular = _SpecIntensity;o.Normal = UnpackNormal(tex2D(_NormalMap, IN.uv_Diffuse));}


最後,得到的效果如下:


解釋
我們最後總結一下使用過的所有技術:最佳化變數類型,共用UV座標,減少處理的光源個數,讓Shader只工作在特定的渲染器上,使用近似值代替精確值,以及減少或壓縮貼圖。








聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.