【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"
}

好了,本篇到此为止,若有不对请大神们及时留言指点。。谢谢大家

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