当前位置:网站首页>@[TOC](【TA-霜狼_may-《百人计划》】图形3.1 深度测试与模板测试
@[TOC](【TA-霜狼_may-《百人计划》】图形3.1 深度测试与模板测试
2022-07-20 03:22:00 【zczplus】
2.8.1 模板测试
通过自定义规则,对片元的输出进行自定义
模板测试是什么
- 从渲染管线出发
- Pixel Ownership Test:屏幕上不是所有的像素都是可用的(例如在打开unity只有 games 和 sense窗口有图像)
- Scissor Test:可以选择控制仅部分像素进行成像
- Alpha Test:只能实现全透明或者不透明的效果
Stencil Test: 模板测试
- Depth Test:深度测试
- 透明度混合:可以实现半透明效果
- Dithering
- Logic Op
- 最后输出到 Framebuffer,再输出屏幕
- 逻辑理解
if ( referenceValue&readMask comparisonFunction stencilBufferValue&readMask)
通过像素
else
抛弃像素 - 概念理解
模板需要模板缓冲区,模板缓冲区与颜色缓冲区类似;
模板缓冲区可以为屏幕上的每个像素点保存一个无符号整数值(通常为8位整数)。这个值的具体意义视程序的具体应用而定;
在渲染的过程中,可以用这个值与一个预先设定的参考值相比较,根据比较的结果来决定是否更新相应的像素点的颜色值;
这个比较的过程被称为模板测试。
Unity Shader中的模板测试结构:
Ref:参考值
ReadMask:读掩码
WriteMask:写掩码
Comp:比较操作
Pass:模板测试若通过,则进行何种自定义操作
Fail:模板测试若未通过,则需要进行的操作
ZFail:若模板测试通过了,但是深度测试没有通过,则需要进行的操作
2.8.2 模板测试在Unity中的实现
通过改变渲染顺序,调整模板缓冲区中的值,达到模板测试的目的
- 以上图为例,首先渲染橙色方框的掩膜部分,并对模板缓冲区中的值进行更改,为1;
- 可以想象,此时模板缓冲区中,只有屏幕中间橘色方框的部分为1,而其余部分为0,如下图:
- 接着渲染后面的所有物体,所有物体的MaskID均设置为1,并将stencil的Comp值设置为equal,可以发现,此时只有上图中橘色方框位置的MaskID值与模板缓冲区中的MaskID相同都为1,所以最终效果只有这一部分通过测试,显示在屏幕上;
模板测试总结
使用模板缓冲区最重要的两个值:当前模板缓冲值和模板参考值;
模板测试主要就是对这两个值使用特定的比较操作:Never,Always,Less,LEqual,Greater,Equal等;
模板测试之后要对模板缓冲区的值进行更新操作,更新操作包括Keep,Zero,Replace,IncrSat,DecrSat,Invert等等;
模板测试之后可以根据结果对模板缓冲区做不同的更新操作,分成多种情况Pass,Fail,ZFail,还有正对正面和背面精确更新操作PassBack,PassFront,FailBack等
模板测试扩展
- 描边
- 多边形填充
- 反射区域控制
- shadow volume阴影渲染
- 等等等
模板测试作业
结合上次的flowmap,做了一个流动放大镜的效果,鼠标悬停的位置部分区域有流动,其余区域不动。
2.8.3 深度测试
渲染管线理解
CPU(模型数据,法线、顶点位置) GPU
=》顶点着色器 =》 几何阶段【细分着色器 =》 几何着色器】 =》 裁剪 =》 屏幕映射
=》 光栅化阶段【三角形设置 =》 三角形遍历】 =》 early-z =》 片元着色器
=》 逐片元操作【裁剪测试 =》 透明度测试 =》 模板测试 =》 深度测试 =》 透明度混合】
=》 屏幕图像
逻辑理解
对当前深度与深度缓冲区进行比较,从而判断是否写入深度
ZWrite
紧接着对颜色缓冲区进行比较,判断是否改变颜色缓冲区中的值
两者差异在于前者有关ZWrite
定义理解
所谓深度测试,就是针对当前对象在屏幕上(更准确的说是frame buffer)对应的像素点,将对象自身的深度值与当前该像素点缓存的深度值进行比较,如果通过了,本对象在该像素点才会将颜色写入颜色缓冲区,否则不会写入颜色缓冲区。
发展过程
控制渲染顺序:1. 画家算法;2. Z-Buffer算法
控制Z-Buffer对深度的存储:1.Z Test; 2. Z Write
控制不同类型物体的渲染顺序:1. 透明物体;2.不透明物体;3. 渲染队列
减少overdraw:1. Early-Z;2. Z cull; 3. Z Check
深度缓冲区(Z-Buffer)
深度缓冲就像颜色缓冲(储存所有的片段颜色:视觉输出)一样,在每个片段中储存了信息,通常与颜色缓冲有同样的长宽。深度缓冲由窗口系统自动创建,它会以16、24或32位float的形式储存它的深度值。在大部分的系统中,深度缓冲的精度都是24位。z-Buffer中存储的是当前的深度信息,对于每个像素存储一个深度值。
通过Z Write 和 Z Test 来调用 Z-Buffer,实现想要的渲染结果
Z Write 和 Z Test
深度写入包括两种状态: ZWrite On 和 ZWrite Off
只有处在 ZWrite On模式下,并且通过ZTest,才会写入深度缓冲区。
2.8.4 渲染队列
渲染队列分类:
- Background (1000) 最早被渲染的;
- Geometry (2000) 不透明物体的渲染队列;Unity中:从前往后;
- AlphaTest (2450) 有Alpha通道,需要进行AlphaTest,比直接放在Geometry中效率更高;从后往前;
- Transparent (3000) 半透明物体的渲染队列。一般是不写入深度的物体,Alpha Blend等操作在该队列进行渲染;
- Overlay (4000) 覆盖效果,例如屏幕光晕,屏幕贴片之类的;
Early-Z技术
在片元着色器之前,光栅化之后,进行一次深度测试,如果深度测试失败,就不必进行fragment阶段的计算,从而使得性能提升;
但是最终的ZTest不能省略,保证最终的遮挡效果关系结果正确。
深度值
模型空间:无深度值
世界空间:存储在Z分量
视图空间:存储在Z分量(线性深度)
裁剪空间:深度缓冲中存储 z/w (透视投影非线性)
屏幕空间:
为什么深度缓冲区中药存储非线性的深度?
在实践过程中存储的一般都是非线性深度缓冲区。正确的投影特性的非线性深度方程是和1/z成正比的。这样做是为了在z很近的时候保持高精度,z较远的时候低精度。充分考虑了深度的问题重要性的问题。
1/z函数的图形表示:
深度缓冲区的值不是线性的屏幕空间(他们在视图空间投影矩阵应用之前是线性的)
深度冲突
两个平面或三角形紧密相互平行深度缓冲区不具有足够的精度以至于无法得到哪一个靠前,导致两个平面反复交替顺序的问题。我们将这种现象称作:深度冲突。
防止深度冲突
- 尽量分离两个平面;
- 把近平面尽量靠近物体,使得各个物体的深度值精度更高;
- 放弃部分性能,提高深度值的精度范围;
深度测试排序
不透明物体中:
先对渲染队列进行排序,再对深度值进行排序,从前往后
注意
Subshader中的Pass按顺序从上到下渲染,无论为pass设置了什么队列
深度测试总结
两个重要的值:当前深度缓冲值(ZBufferValue)和深度参考值(referenceValue)
Unity中的渲染顺序:先不透明,从前往后;再透明,从后往前
通过Zwrite和Z Test组合使用控制半透明物体的渲染
引入early-z技术提高性能
深度缓冲区中存储的深度值为0到1范围的浮点值,且为非线性
深度测试扩展
- 基于深度值的着色器(湖水渲染)
- 阴影贴图(ShadowMap)
- 透明物体、粒子渲染
- 透视X-Ray效果
- 切边效果
- 等等
深度测试作业
浅浅地试了一下XRay效果
贴一下XRay的代码 方便查找:
Shader "Custom/100 learning/MyXRay"
{
Properties
{
_MainTex("Base 2D", 2D) = "white" {
}
_XRayColor ("XRay Color", Color) = (1,1,1,1)
}
SubShader
{
Tags {
"RenderType"="Opaque" }
// 利用CGINCLUDE直接定义所有vertex 和 fragment 这样可以共用 struct
CGINCLUDE
#include "UnityCG.cginc"
fixed4 _XRayColor;
struct v2f{
float4 pos:SV_POSITION;
float3 normal:NORMAL;
float3 viewDir:TEXCOORD0;
fixed4 color : COLOR;
};
v2f vertXray(appdata_base v){
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.viewDir = ObjSpaceViewDir(v.vertex);
o.normal = v.normal;
float3 normal = normalize(v.normal);
float3 viewDir = normalize(o.viewDir);
// 通过1 - 计算视角与当前法线的夹角,来对被遮挡的部分赋予颜色权重
float rim = 1 - dot(normal, viewDir);
o.color = _XRayColor * rim;
return o;
}
fixed4 fragXray(v2f i) : SV_Target{
return i.color;
}
sampler2D _MainTex;
float4 _MainTex_ST;
struct v2fRegular{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD;
};
v2fRegular vertRegular(appdata_base v){
v2fRegular o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
return o;
}
fixed4 fragRegular(v2fRegular i) : SV_Target{
return tex2D(_MainTex, i.uv);
}
ENDCG
// XRay 绘制
Pass{
Tags{
"RenderType" = "Transparent"
"Queue" = "Transparent"
}
Blend SrcAlpha one
ZTest Greater
ZWrite Off
Cull Back
CGPROGRAM
#pragma vertex vertXray
#pragma fragment fragXray
ENDCG
}
// 正常绘制
Pass{
Tags{
"RenderType" ="Opaque"
}
ZTest LEqual
ZWrite On
CGPROGRAM
#pragma vertex vertRegular
#pragma fragment fragRegular
ENDCG
}
}
FallBack Off
}
之后做一下湖水颜色渲染和护盾的切边效果!再想想有什么好玩的。
边栏推荐
- 技术干货 | 基于 MindSpore 实现 CosineSimilarity
- [leetcode] sword finger offer 52 The first common node of two linked lists
- [R language text mining]: emotion analysis and word cloud mapping
- SparkCore算子及案例,220719,
- 视频25-7章2节VGG 26-NiN 27-GooLeNet
- MindSpore开源周年狂欢,量子机器学习与深度分子模拟等巨量新特性来袭!
- ARM裸板调试之JTAG调试命令行调试
- matlab-微分方程求解方法汇总
- 亮点抢先看!2022开放原子全球开源峰会定于7月25-29日在北京举办
- [noi simulation] Simen Nong number (number theory, linked list)
猜你喜欢
Matlab summary of differential equation solving methods
【Pygame 学习笔记】8.精灵
Grouping convolution and deep separable convolution
The common loss function in the field of hyper Division
编译+链接和预处理
Understanding and applying continuous integration Tekton
深度学习1-感知器
Unity shader implements the image with rounded corners and edge borders
Harbor high availability cluster design and deployment (offline installation, including video)
通过例子学C标准库<assert.h>
随机推荐
DenseNet学习笔记(核心与resnet进行对比):
美国议员倡导打击加密挖矿 敲响加密警钟?减少碳足迹才能发挥真正价值
MySQL C language connection
【webrtc】ImportError: No module named win32file
A good resume can always brighten people's eyes during the interview of the testing post
Chromeoptions common configuration and webui practice
fruit loops studio音乐宿主软件daw水果软件20.9中文版
[LeetCode]剑指 Offer 58 - II. 左旋转字符串
如何通过CMake为QML创建插件
[leetcode] sword finger offer 53 - ii Missing numbers from 0 to n-1
利用正则表达式绕过
What do 1U, 2U and 4U of the server mean?
网站引用百度地图,乱码及无图标
【NOI模拟赛】思门弄数(数论,链表)
[server data recovery] data recovery of a brand ProLiant server raid paralysis database file damage
ICMP - echo / echo reply (Ping) message
编译+链接和预处理
Go daily Gore
【AD学习记录】为什么原理图和PCB都在同一个文件夹下面了却,无法生成PCB?
scala 函数&方法、函数&方法的实现原理