【Unity Shader】3.Unity Shader基本知識學習(剔除 & 深度測試 )

1.剔除(Culling)的概念


  對於實時交互的3D環境而言,現實的速度和效率是非常重要的。雖然現在的硬件能力非常的快,但是要想保持30FPS的同時處理數十萬的三角形,還是有些困難的。
 
 

爲了解決這種問題,人們提出了很多方法,其中有LOD,有Culling。這兩種方法並不矛盾,而且我們往往需要在culling(剔除)的基礎上再使用LOD進一步解決pipeline的負擔。

在此,博主也把LOD技術解釋一下:LOD技術即Levels of Detail的簡稱,意爲多細節層次。LOD技術指根據物體模型的節點在顯示環境中所處的位置和重要度,決定物體渲染的資源分配,降低非重要物體的面數和細節度,從而獲得高效率的渲染運算。

Culling:剔除是一種通過避免渲染背對觀察者的幾何體面來提高性能的優化措施。所有幾何體都包含正面和反面。剔除基於大多數對象都是封閉的事實;如果你有一個立方體,你不會看到背離你的那一面(總是隻有一面在你的前方),因此我們不需要繪製出背面。因此也被稱做背面剔除。

總之,所謂剔除,就是被擋住或視角以外的我們看不到的物體,因爲它們無關緊要,所以我們就不去繪製,以節省資源,提高場景的運行效率。

2.深度測試(DepthTesting)概念


我們在複雜的場景中,通常有多個物體需要繪製,這些物體之間會存在遮擋關係,離觀察點較遠的物體會因爲近處物體的者的遮擋而不可見或只有部分可見。深度測試可以簡化複雜場景的繪製,確保只有場景內的對象的最靠近的表面參與繪製。

3.相關語法


Cull Back | Front | off

作用:控制多邊形的哪一面應該被剔除
- Cull Back : 不繪製 背離觀察者的面
- Cull Front : 不繪製 面對觀察者的面
- Cull off :剔除關閉,繪製所有的面

Zwrite on | off

作用:控制是否將對象寫入深度緩存(默認爲 on)

  • 如果要繪製實心的物體,則使其處於開啓狀態(on)
  • 如果要繪製半透明的物體,則使其處於關閉狀態(off)
ZTest Less|Greater|LEqual|GEqual|Equal|NotEqual|Always|Never

作用:用於控制深度測試如何執行

默認爲 LEqual ,LEqual就是繪製現有對象前面的對象或與現有對象有一段距離的對象。隱藏現有對象後面的對象(把自己和別人做對比)

系統中存在一個顏色緩衝區和一個深度緩衝區,分別存儲顏色值和深度值,來決定畫面上應該顯示什麼顏色。

深度值是物體在世界空間中距離攝像機的遠近。距離越近,深度值越小;距離越遠,深度值越大。

- Greater  只渲染深度大於當前對象的像素
- GEqual   只渲染深度大於等於當前對象的像素
- Less     只渲染深度小於當前對象的像素
- LEqual   只渲染深度小於等於當前對象的像素
- Equal    只渲染深度等於當前對象的像素
- NotEqual 只渲染深度不等於當前對象的像素
- Always   渲染所有像素,等於關閉深度測試
- Never    不渲染任何像素

4.實戰


4.1 剔除(Culling) Cull Back | Front


這裏寫圖片描述

這是一張對比圖(相同的角度),創建一個plane,在shader中設置,左邊爲Cull off,右邊爲Cull Back


這裏寫圖片描述

這也是一張對比圖(相同角度),創建一個plane,在shader中設置,左邊爲Cull off 右邊爲Cull Front

下面給出部分代碼,請讀者自行修改設置

Shader "Custom/testCull" {
    Properties {
        _Color ("Color", Color) = (1,1,1,1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200
        Cull off
        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf Standard fullforwardshadows

        // Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 3.0

        sampler2D _MainTex;

        struct Input {
            float2 uv_MainTex;
        };

        half _Glossiness;
        half _Metallic;
        fixed4 _Color;

        void surf (Input IN, inout SurfaceOutputStandard o) {
            // Albedo comes from a texture tinted by color
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
            o.Albedo = c.rgb;
            // Metallic and smoothness come from slider variables
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

4.2 Zwrite on | off

這裏寫圖片描述

相同角度下的對比圖,左邊的爲Zwrite on 爲實心會被遮擋,右邊的爲 Zwrite off 爲透明,不會被遮擋
正如我們之前說的那樣,繪製實心物體Zwrite on,繪製半透明物體爲Zwrite off

下面給出具體代碼,請讀者自行修改體會:

Shader "Custom/testZwrite" {
    Properties {
        _Color ("Color", Color) = (1,1,1,1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200
        Zwrite off
        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf Standard fullforwardshadows

        // Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 3.0

        sampler2D _MainTex;

        struct Input {
            float2 uv_MainTex;
        };

        half _Glossiness;
        half _Metallic;
        fixed4 _Color;

        void surf (Input IN, inout SurfaceOutputStandard o) {
            // Albedo comes from a texture tinted by color
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
            o.Albedo = c.rgb;
            // Metallic and smoothness come from slider variables
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

4.3 ZTest

我們先來看一張圖
這裏寫圖片描述

這是一個plane下面放了一個Cube,當我們從這個角度看過去的時候,Cube是看不到的。。


再來一張換個角度,
這裏寫圖片描述

當我們從從上往下看的時候,由於plane在上面先渲染,也就是顏色緩衝區和深度緩衝區中先存入plane的顏色值和深度值,我們在Cube上面設置的ZTest爲Ztest Greater,也就是大於深度緩衝區的會被渲染,Cube在plane的下面,也就是Cube深度大於plane的深度,Cube會被看到。。

ps:由於是初學者,碰到這個問題查了很多的資料,加上自己的理解所寫,若有錯誤請大神們留言指點,我會及時的改正

下面看源代碼:

Shader "Custom/Ztest" {
    Properties {
        _Color ("Color", Color) = (1,1,1,1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200

        ZTest Greater
        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf Standard fullforwardshadows

        // Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 3.0

        sampler2D _MainTex;

        struct Input {
            float2 uv_MainTex;
        };

        half _Glossiness;
        half _Metallic;
        fixed4 _Color;

        void surf (Input IN, inout SurfaceOutputStandard o) {
            // Albedo comes from a texture tinted by color
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
            o.Albedo = c.rgb;
            // Metallic and smoothness come from slider variables
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
            o.Alpha = c.a;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

好了,本篇到此爲止,若有不對請大神們及時留言指點。。謝謝大家

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章