Pass的通用指令開關


LOD:

設置:單個設置Shader.maximumLOD、全局設置Shader.globalMaximumLOD、QualitySettings里面的Maximum LODLevel
原理:小於指定值的shader和subshader才能被使用。
應用:有時候一些顯卡雖然支持很多特性,但是效率很低,此時就可以用LOD來進行控制。
內置shader的LOD值:
  VertexLit kind of shaders = 100
  Decal, Reflective VertexLit = 150
  Diffuse = 200
  Diffuse Detail, Reflective Bumped Unlit, Reflective Bumped VertexLit = 250
  Bumped, Specular = 300
  Bumped Specular = 400
  Parallax = 500
  Parallax Specular = 600

注釋:Shader自身的LOD會覆蓋全局的LOD。

    public Shader targetShader;

    private void Start () 
    {
        // 全局的值會被Shader本地址覆蓋
        Shader.globalMaximumLOD = 300;
        if (targetShader != null)
        {
            targetShader.maximumLOD = 600;
        }
    }

RenderQueue:

    mtrl.renderQueue = 1000;

  shader中使用ZTest Always,可以讓被遮住的物體也渲染。

AlphaTest:

  固定管線:使用AlphaTest命令

  動態管線:使用clip(alpha - cutoff)指令來實現

  Alpha檢測在ps完成計后,即將寫入幀之前,通過和一個固定的數值比較,來決定當前ps的計算結果到底要不要寫入幀中。

// inside SubShader
Tags { "Queue"="AlphaTest" "RenderType"="TransparentCutout" "IgnoreProjector"="True" }

// inside CGPROGRAM in the fragment Shader:
clip(textureColor.a - alphaCutoffValue);

  AlphaTest抗鋸齒:

// inside SubShader
Tags { "Queue"="AlphaTest" "RenderType"="TransparentCutout" "IgnoreProjector"="True" }

// inside Pass
AlphaToMask On

AlphaBlend:

  shader渲染的最后一步,決定怎樣將當前計算結果寫入到幀緩存中。

  命令集:

  Blend BlendOp AlplaToMask

// inside SubShader
Tags { "Queue"="Transparent" "RenderType"="Transparent" "IgnoreProjector"="True" }

// inside Pass
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha

   AlphaBlend會有一系列和繪制順序相關的問題,涉及到的知識點如下:

  (1)Unity通過Queue保證所有的不透明物體Geometry都會在半透明物體Transparent之前被渲染,(Queue標簽決定了這個對象的渲染隊列);

  (2)Unity保證所有Transparent隊列的物體,按distance(物體的遠近,不是像素的)從后往前渲染;

  (3)distance的計算方式:使用網格的幾何中心點來進行半透明物體的排序。

  對於部分遮擋的物體,還是會產生不正確的遮擋效果。因此我們要么分割網格,要么使用Alpha Test或者開啟ZWrite來替代。

AlphaTest和AlphaBlend的性能比較:

  官方文檔在這里:https://docs.unity3d.com/Manual/SL-ShaderPerformance.html

  翻譯如下:

  固定管線的AlphaTest和可編程管線的clip()函數,在不同平台有不同性能表現:

  (1)多數平台上,AlphaTest這種整個剔除透明像素的做法能獲得一點點性能優勢;

  (2)在ios和android這樣基於PowerVR GUPs的設備上,AlphaTest是非常耗資源的,不要企圖使用它來做性能優化,因為它會讓游戲更慢(是因為直接丟掉像素,讓GPUs的某些優化策略沒法執行了)。

  所以結論是:手機上盡量使用AlphaBlend而不是AlphaTest。

 ColorMask:

  ColorMask RGB | A | 0 | any combination of R, G, B, A

  ColorMask也是耗費比較大的操作,只在確實需要時使用。

 ZWrite/ZTest:

  ZWrite On | Off

  ZTest Less | Greater | LEqual | GEqual | Equal | NotEqual | Always

  關於相機的深度貼圖_CameraDepthTexture:

  (1)默認材質都自帶RenderType的Tag;

  (2)自定義sahder只有添加RenderType標簽才會將深度寫到_CameraDepthTexture。

 Offset:

  對Z深度的偏移。

  可以讓像素看起來更靠前或更靠后,當兩個面重疊時,可以手動指定誰相對靠前一些,而且不會戰勝z-fitting。

  Offset只會對ZTest的條件做修正,但是並不會改變最后的Z緩沖。

 GrabPass:

  抓取當前屏幕當做貼圖使用。

Shader "James/VP Shader/GrabPass"
{
    Properties 
    {
        _MainTex("MainTex", 2D) = "white" {}
    }
    SubShader 
    {
        // 在所有不透明幾何體之后自畫,這一點很重要
        Tags { "Queue" = "Transparent" }
        GrabPass { "_MyGrab" }
        Pass
        {
            CGPROGRAM
            #pragma vertex vs
            #pragma fragment ps
            #include "UnityCG.cginc"

            struct v2f
            {
                float4 pos : SV_POSITION;
                float3 color : COLOR0;
                float2 uv : TEXCOORD0;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            sampler2D _MyGrab;

            v2f vs(appdata_base v)
            {
                v2f o;
                o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
                o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
                return o;
            }

            float4 ps(v2f i):COLOR
            {
                float4 texColor = tex2D(_MainTex, i.uv);
                float4 grabColor = tex2D(_MyGrab, i.uv);
                return texColor * grabColor;
            }
            ENDCG
        }
    } 
    FallBack "Diffuse"
}

 Fog:

  霧效實現的三種方式:

  (1)全局霧

  RenderSettings.fog = true;
  RenderSettings.fogColor = Color.red;
  RenderSettings.fogMode = FogMode.Linear;
  RenderSettings.fogStartDistance = 0;
  RenderSettings.fogEndDistance = 10;

  (2)Fog指令

  Fog{ Mode Linear Color(1, 0, 0) Range 0, 10 }

  (3)Shader計算方式

Shader "James/VP Shader/Fog"
{
    Properties {
        _MainTex ("Base (RGB)", 2D) = "white" {}
        _FogColor("FogColor", Color) = (1, 1, 1, 1)
        _Density("Density", Range(0, 10)) = 1
        _NearDistance("NearDistance", Float) = 0
        _FarDistance("FarDistance", Float) = 10
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        Fog { Mode Off }
        Pass
        {
            CGPROGRAM
            #pragma vertex vs
            #pragma fragment ps
            #include "UnityCG.cginc"

            struct v2f
            {
                float4 pos : SV_POSITION;
                float3 color : COLOR0;
                float2 uv : TEXCOORD0;
                float4 depth : TEXCOORD1;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            float4 _FogColor;
            float _Density;
            float _NearDistance;
            float _FarDistance;

            v2f vs(appdata_base v)
            {
                v2f o;
                o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
                o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
                o.depth = mul(UNITY_MATRIX_MV, v.vertex);
                o.depth.z = -o.depth.z;
                o.depth.w = (_FarDistance - _NearDistance) * o.depth.w;
                return o;
            }

            float4 ps(v2f i):COLOR
            {
                float4 texColor = tex2D(_MainTex, i.uv);
                float fg = 0;
                if(i.depth.z > _NearDistance && i.depth.z < _FarDistance)
                {
                    fg = i.depth.z / i.depth.w;
                }
                else if(i.depth.z > _FarDistance)
                {
                    fg = _FarDistance / i.depth.w;
                }
                return fg * _Density * _FogColor * texColor;
            }
            ENDCG
        }
    } 
    FallBack "Diffuse"
}

 Stencil:

  Stencil-Test在Z-Test和Alpha-Test之前,如果模板檢測不通過,則像素直接被丟掉而不會執行fragment函數。

Shader "James/VP Shader/Stencil"
{
    Properties {
        _MainTex ("Base (RGB)", 2D) = "white" {}
        _refVal("Stencil Ref Value",int)=0
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        ZTest Always
        Stencil
        {
            Ref [_refVal]
            Comp GEqual
            Pass Replace
            Fail keep
            ZFail keep
        }
        Pass
        {
            CGPROGRAM
            #pragma vertex vs
            #pragma fragment ps
            #include "UnityCG.cginc"

            struct v2f
            {
                float4 pos : SV_POSITION;
                float3 color : COLOR0;
                float2 uv : TEXCOORD0;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vs(appdata_base v)
            {
                v2f o;
                o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
                o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
                return o;
            }

            float4 ps(v2f i):COLOR
            {
                float4 texColor = tex2D(_MainTex, i.uv);
                return texColor;
            }
            ENDCG
        }
    } 
    FallBack "Diffuse"
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM