剔除(Culling)
剔除是一种通过避免渲染背对观察者的几何体面来提高性能的优化措施。所有几何体都包含正面和反面。剔除基于大多数对象都是封闭的事实;如果你有一个立方体,你不会看到背离你的那一面(总是只有一面在你的前方),因此我们不需要绘制出背面。因此也被称做背面剔除。
一言以蔽之,所谓剔除,就是被挡住或视角以外的我们看不到的物体,因为它们无关紧要,所以我们就不去绘制,以节省资源,提高场景的运行效率。
深度测试(Depth Testing)
在复杂的场景中,通常有多个物体需要绘制,这些物体之间通常会存在遮挡关系,离观察点较远的物体会因为近处物体的者的遮挡而不可见或只有部分可见,Direct3D图形系统提供了深度测试功能来实现这种效果。深度测试可以简化复杂场景的绘制,确保只有场景内的对象的最靠近的表面参与绘制。
Alpha测试(Alpha Testing)
Unity中,Alpha测试(Alpha Testing)是阻止像素被写到屏幕的最后机会。在Pineline中Alpha测试的位置如下:
在最终渲染出的颜色被计算出来之后,可选择通过将颜色的透明度值和一个固定值比较。如果比较的结果失败,像素将不会被写到显示输出中。
Alpha测试在渲染凹形物体的透明部分时非常有用。显卡上有着每个像素写到屏幕上的深度记录。如果一个新的像素比原来的像素的深度深,那么新的像素就不会被写到屏幕中。
用剔除操作渲染对象背面
1 Shader "Shader学习/剔除操作渲染对象背面"
2 {
3 //--------------------------------【子着色器】--------------------------------
4 SubShader
5 {
6 Pass
7 {
8 //【1】设置顶点光照
9 Material
10 {
11 Emission(0.3,0.3,0.3,0.3)
12 Diffuse (1,1,1,1)
13 }
14 //【2】开启光照
15 Lighting On
16
17 //【3】剔除正面(不绘制面向观察者的几何面)
18 Cull Front
19 }
20 }
21 }
剔除掉正面的面。可以看到对象背面。
可以定义第二个通道,采用亮蓝色来渲染物体的背面。
1 Shader "Shader学习/渲染对象背面_2"
2 {
3 //-------------------------------【属性】---------------------------------------
4 Properties
5 {
6 _Color ("主颜色", Color) = (1,1,1,0)
7 _SpecColor ("高光颜色", Color) = (1,1,1,1)
8 _Emission ("光泽颜色", Color) = (0,0,0,0)
9 _Shininess ("光泽度", Range (0.01, 1)) = 0.7
10 _MainTex ("基础纹理 (RGB)-透明度(A)", 2D) = "white" {}
11 }
12
13 //--------------------------------【子着色器】--------------------------------
14 SubShader
15 {
16
17 //---------------------------【通道一】------------------------------
18 // 说明:绘制对象的前面部分,使用简单的白色材质,并应用主纹理
19 //----------------------------------------------------------------------
20 Pass
21 {
22 //【1】设置顶点光照
23 Material
24 {
25 Diffuse [_Color]
26 Ambient [_Color]
27 Shininess [_Shininess]
28 Specular [_SpecColor]
29 Emission [_Emission]
30 }
31
32 //【2】开启光照
33 Lighting On
34
35 // 【3】将顶点颜色混合上纹理
36 SetTexture [_MainTex]
37 {
38 Combine Primary * Texture
39 }
40
41 }
42
43 //--------------------------【通道二】-------------------------------
44 // 说明:采用亮蓝色来渲染背面
45 //----------------------------------------------------------------------
46 Pass
47 {
48 Color (0,0,1,1)
49 Cull Front
50 }
51 }
52 }
靠近会显示剔除部分的蓝色。
用剔除实现玻璃效果
可以用于凸物体(球,立方体,车窗)
1 Shader "浅墨Shader编程/Volume4/14.用剔除实现玻璃效果"
2 {
3 //-------------------------------【属性】---------------------------------------
4 Properties
5 {
6 _Color ("主颜色", Color) = (1,1,1,0)
7 _SpecColor ("高光颜色", Color) = (1,1,1,1)
8 _Emission ("光泽颜色", Color) = (0,0,0,0)
9 _Shininess ("光泽度", Range (0.01, 1)) = 0.7
10 _MainTex ("基础纹理 (RGB)-透明度(A)", 2D) = "white" {}
11 }
12
13 //--------------------------------【子着色器】--------------------------------
14 SubShader
15 {
16 //【1】定义材质
17 Material
18 {
19 Diffuse [_Color]
20 Ambient [_Color]
21 Shininess [_Shininess]
22 Specular [_SpecColor]
23 Emission [_Emission]
24 }
25 //【2】开启光照
26 Lighting On
27 //【3】开启独立镜面反射
28 SeparateSpecular On
29
30 //【4】开启透明度混合(alpha blending)
31 Blend SrcAlpha OneMinusSrcAlpha
32
33 //--------------------------【通道一】-------------------------------
34 // 说明:渲染对象的背面部分
35 //----------------------------------------------------------------------
36 Pass
37 {
38 // 如果对象是凸型, 那么总是离镜头离得比前面更远
39 Cull Front //不绘制面向观察者的几何面
40 SetTexture [_MainTex]
41 {
42 Combine Primary * Texture
43 }
44 }
45
46 //----------------------------【通道二】-----------------------------
47 // 说明:渲染对象背对我们的部分
48 //----------------------------------------------------------------------
49 Pass
50 {
51 // 如果对象是凸型,那么总是离镜头离得比背面更远
52 Cull Back //不绘制背离观察者的几何面
53 SetTexture [_MainTex]
54 {
55 Combine Primary * Texture
56 }
57 }
58 }
59 }
基本Alpha测试
使用一张带透明度通道的纹理,对象只会在透明度大于60%时显示
1 Shader "浅墨Shader编程/Volume4/15.基本Alpha测试"
2 {
3 //-------------------------------【属性】-----------------------------------------
4 Properties
5 {
6 _MainTex ("基础纹理 (RGB)-透明度(A)", 2D) = "white" {}
7 }
8
9 //--------------------------------【子着色器】--------------------------------
10 SubShader
11 {
12 //----------------------------【通道】-------------------------------
13 // 说明:进行Alpha测试操作,且只渲染透明度大于60%的像素
14 //----------------------------------------------------------------------
15 Pass
16 {
17 // 只渲染透明度大于60%的像素
18 AlphaTest Greater 0.6
19 SetTexture [_MainTex] { combine texture }
20 }
21 }
22 }
给上面的Shader基础上增加一些光照,并让alpha的阈值可以调节。
1 Shader "浅墨Shader编程/Volume4/16.顶点光照+可调透明度"
2 {
3 //-------------------------------【属性】-----------------------------------------
4 Properties
5 {
6 _Color ("主颜色", Color) = (1,1,1,0)
7 _SpecColor ("高光颜色", Color) = (1,1,1,1)
8 _Emission ("光泽颜色", Color) = (0,0,0,0)
9 _Shininess ("光泽度", Range (0.01, 1)) = 0.7
10 _MainTex ("基础纹理 (RGB)-透明度(A)", 2D) = "white" { }
11 _Cutoff ("Alpha透明度阈值", Range (0,1)) = 0.5
12 }
13
14 //--------------------------------【子着色器】--------------------------------
15 SubShader
16 {
17 Pass
18 {
19 // 【1】使用Cutoff参数定义能被渲染的透明度阈值
20 AlphaTest Greater [_Cutoff]
21
22 //【2】设置顶点光照参数值
23 Material
24 {
25 Diffuse [_Color]
26 Ambient [_Color]
27 Shininess [_Shininess]
28 Specular [_SpecColor]
29 Emission [_Emission]
30 }
31
32 //【3】开启光照
33 Lighting On
34
35 // 【4】进行纹理混合
36 SetTexture [_MainTex] { combine texture * primary }
37 }
38 }
39 }
简单的植被Shader
1 Shader "浅墨Shader编程/Volume4/17.简单的植被Shader"
2 {
3 //-------------------------------【属性】-----------------------------------------
4 Properties
5 {
6 _Color ("主颜色", Color) = (.5, .5, .5, .5)
7 _MainTex ("基础纹理 (RGB)-透明度(A)", 2D) = "white" {}
8 _Cutoff ("Alpha透明度阈值", Range (0,.9)) = .5
9 }
10
11 //--------------------------------【子着色器】--------------------------------
12 SubShader
13 {
14 //【1】定义材质
15 Material
16 {
17 Diffuse [_Color]
18 Ambient [_Color]
19 }
20
21 //【2】开启光照
22 Lighting On
23
24 //【3】关闭裁剪,渲染所有面,用于接下来渲染几何体的两面
25 Cull Off
26
27 //--------------------------【通道一】-------------------------------
28 // 说明:渲染所有超过[_Cutoff] 不透明的像素
29 //----------------------------------------------------------------------
30 Pass
31 {
32 AlphaTest Greater [_Cutoff]
33 SetTexture [_MainTex] {
34 combine texture * primary, texture
35 }
36 }
37
38 //----------------------------【通道二】-----------------------------
39 // 说明:渲染半透明的细节
40 //----------------------------------------------------------------------
41 Pass
42 {
43 // 不写到深度缓冲中
44 ZWrite off
45
46 // 不写已经写过的像素
47 ZTest Less
48
49 // 深度测试中,只渲染小于或等于的像素值
50 AlphaTest LEqual [_Cutoff]
51
52 // 设置透明度混合
53 Blend SrcAlpha OneMinusSrcAlpha
54
55 // 进行纹理混合
56 SetTexture [_MainTex]
57 {
58 combine texture * primary, texture
59 }
60 }
61 }
62 }