ShaderLab: 剔除和深度测试(Culling and ZTest)

概述:

不渲染视野内不可见的多边形的操作称之为剔除。
所有的多边形都有正面和背面,视野永远看不见背面,因此Unity也不需要渲染背面。这个过程用专业术语称之为:背面剔除(Backface culling)
另外有一项技术,保证渲染的永远是离视野最近的面,从容让渲染出的效果看起来更真实,这项技术被深度检测(Depth testing)

工作时机:

剔除时机

语法:

Cull

Cull Back | Front | Off 

控制剔除多边形的那些边?

  • Back Don't render polygons that are facing away from the viewer. default: back-facing polygons are culled.
    背面,背对着观察者的面,这是默认选项
  • Front Don't render polygons that are facing towards the view.Used for turning objects inside-out.
    前面,朝向观察者的面,通常用于表现翻转效果
  • Off Disable culling-all faces are drawn.Used for special effects.
    关闭剔除,所有朝向都绘制。通常用于特殊效果。

样例:


Shader "Unlit/CullingTest"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        [Header(Cull)]
        // https://docs.unity3d.com/ScriptReference/Rendering.CullMode.html
        // default need to be Front, because we need to make sure decal render correctly even if camera goes into decal cube
        [Enum(UnityEngine.Rendering.CullMode)]_Cull("_Cull (default = Front) _____to improve GPU performance, Set to Back if camera never goes into cube volume, else set to Front", Float) = 1 //1 = Front
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" "Queue"="Geometry" }
        Cull [_Cull]
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work
            #pragma multi_compile_fog
            
            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;
            
            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                UNITY_TRANSFER_FOG(o,o.vertex);
                return o;
            }
            
            fixed4 frag (v2f i) : SV_Target
            {
                // sample the texture
                fixed4 col = tex2D(_MainTex, i.uv);
                // apply fog
                UNITY_APPLY_FOG(i.fogCoord, col);
                return col;
            }
            ENDCG
        }
    }
}


Cull [_Cull]  //从外面读取数据

效果:

Cull Back | Front | Off 效果

ZTest

ZTest  Less  |  LEqual | GEqual | NotEqual | Always

How should depth testing be perfromed.Default is LEqual(draw objects in from or at the distance as existing objects;hide objects behind them).
深度测试执行方式,默认为 LEqual(小于等于)。Unity中离摄像机越近深度越小,越大离得越远。LEqual 表示执行深度测试时,像素点与缓存中的进行比较,如果小于缓存值,便能通过测试。
除了LEqual 外,还有下面这些参数可用:

函数名 描述
Never 1 从不渲染
Less 2 当小于缓存值时执行
Equal 3 当等于缓存值时执行
LEqual 4 当小于等于缓存值时执行
Greater 5 当大于缓存值时执行
NoEqual 6 当不等于缓存值时执行
GEqual 7 当大于等于缓存值时执行
Alaways 8 一直执行

ZWrite

ZWrite On | Off

Controls whether pixels from this object are written to the depth buffer(default is On).if you're drawing solid objects,leave this on .if you're drawing semitransparent effects,switch to Zwrite off.
控制物体的像素点是否写入深度缓存,如果绘制是固体(不透明)保持它为打开状态,如果是透明,关闭它。
设置在渲染过程中是否更新深度缓冲区内容。通常,ZWrite 对不透明对象启用,对半透明对象禁用。
禁用 ZWrite 会导致不正确的深度排序。这种情况下,您需要在 CPU 上对几何体进行排序。

当且仅当 ZTest 通过和 ZWrite 开启时,像素点的深度才会被写入 ```depth buffer`` 中

Offset

Offset Factor, Units

Allows you specify a depth offset with two parameters.factor and units.Factor scales the maximum Z slop,with respect to X or Y of the polygon,and units scale the minimum resolvable depth buffer value.This allows you to force one polygon to be drawn on top of another although they are actually in the same position.
For example Offset 0,-1 pulls the polygon closer to the camera ignoring the polygon's slope,whereas Offset -1,-1 will pull the polygon even closer when looking at a grazing angle.

允许通过 Factor 和 Units 来指定深度偏移。Factor 是多边形 Z 轴基于 X 或者 Y 的最大斜率的缩放量,Units 是深度缓存中最小可分值的缩放量。通过调整参数,你可以强制使同一位置的多边形绘制在其它多边形之上。
例如:Offset 0, -1 可以忽略多边形的斜率,将其推进摄像机。Offset -1, -1 从波动角(grazing angle)观察,多边形被拉得更靠近。

grazing_angle

Offset 主要用来解决 Z-fighting 问题

  • Z-fighting:当多边形共面时,深度缓存无法分离它们,导致深度不稳定,从而会出现图像在帧间来回穿插闪烁。

如下效果:

Z-fighting

能解决这种问题的shader:

Shader "Test/Quad"
{
    Properties
    {
        _OffsetFactor("Offset Factor",Float) = 0
        _OffsetUnits("Offset Units",Float) = 0
        _Color ("Main Color", Color) = (1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        Offset [_OffsetFactor],[_OffsetUnits]
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            // make fog work

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 normal : NORMAL;
            };

            struct v2f
            {
                float2 wnormal : NORMAL;
                float4 vertex : SV_POSITION;
            };
            fixed4 _Color;
            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.wnormal = UnityObjectToWorldNormal((v.normal,1));
                return o;
            }

            fixed4 frag (v2f i) : SV_Target
            {
                return _Color * (dot(normalize(_WorldSpaceLightPos0.xyz),i.wnormal) * 0.5 + 0.5);
            }
            ENDCG
        }
    }
}

关键在下面两段代码:

  _OffsetFactor("Offset Factor",Float) = 0 // Factor 属性面板可设置,默认0
  _OffsetUnits("Offset Units",Float) = 0 // Units 属性面板可设置,默认0
  Offset [_OffsetFactor],[_OffsetUnits]
调整后的

引用:

https://docs.unity3d.com/2020.1/Documentation/Manual/SL-CullAndDepth.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容