Unity Shader学习日志六:认识深度测试、深度写入、模板测试,简单制作魔镜世界


前言

本章学习深度测试、深度写入、模板测试,简单制作魔镜世界,感谢Kerry大佬的教学

一、渲染顺序

Unity在决定渲染顺序时采用了深度缓冲技术

当渲染物体时,每个所生成的 pixel 产生的深度数据会存储在 z-buffer(或称为 depth buffer),buffer 为二维矩阵,其尺寸大小与最后渲染尺寸相同。

如果渲染场景中其他物体时,并在同一个 pixel 位置渲染结果时,会检查 z-buffer 所存储的深度数据与当前Pixel的深度数据进行比较,决定是否将渲染结果覆盖原来的 pixel(Z-test),并且将新的深度速度写入到 z-buffer(Z-write)。通常条件会设定为深度数据比原本更接近摄像机时,就能够覆盖原本结果。

有 z-buffering 机制,不管物体渲染顺序(rendering order),使得离摄像机越近的物体,永远会渲染在其他离摄像机越远的物体之前。


二、深度测试(Z-test)与 深度写入(Z-write)

深度测试,所谓测试,就是针对当前对象在屏幕上(更准确的说是frame buffer)对应的像素点,将对象自身的深度值与当前该像素点缓存的深度值进行比较,如果通过了,本对象在该像素点才会将颜色写入颜色缓冲区,否则否则不会写入颜色缓冲。ZTest提供的状态较多。 ZTest Less(深度小于当前缓存则通过, ZTest Greater(深度大于当前缓存则通过),ZTest LEqual(深度小于等于当前缓存则通过),ZTest GEqual(深度大于等于当前缓存则通过),ZTest Equal(深度等于当前缓存则通过),ZTest NotEqual(深度不等于当前缓存则通过),ZTest Always(不论如何都通过)。注意,ZTest Off等同于ZTest Always,关闭深度测试等于完全通过。

ZWrite比较简单,只有两种状态, ZWrite On(开启深度写入)和ZWrite Off(关闭深度写入) 。当我们开启深度写入的时候,物体被渲染时针对物体在屏幕(更准确地说是frame buffer)上每个像素的深度都写入到深度缓冲区;反之,如果是ZWrite Off,那么物体的深度就不会写入深度缓冲区。

下面进行测试,默认z-write打开,每个物体在最开始的深度默认最大,最先开始渲染背景
在这里插入图片描述

(1)less
双色Z-test Mode 均为less

先渲染红色,红色与背景重叠,红色均less背景,所以红色部分所有都显示。
在这里插入图片描述

接下来渲染绿色,绿色有一部分与红色重叠,进行深度测试,重叠部分深度greater红色,所以不渲染,显示被红色遮挡,其余部分均less于背景,所以显示。
在这里插入图片描述

(2)greater
绿色为greater,红色为less

当渲染绿色时,进行深度测试,由于绿色深度测试mod为greater,所以与红色重叠部分显示,与背景(深度为MAX)部分不显示
在这里插入图片描述
(3)always
绿色开启always
在这里插入图片描述
虽然绿色重叠部分比红色greater,但是always则默认绿色通过,所以全部显示

我们在绿色后面添加一个白色,白色为greater

在这里插入图片描述
在渲染白色时,依旧会判断为Greater把绿色覆盖掉。

(4)关闭Z-write
红色绿色均为less,关闭红色的z-write
在这里插入图片描述
红色与背景进行Z-test后完成渲染,由于Z-write关闭,红色的深度不会被记录,默认为MAX,当渲染绿色时,重叠部分经过Z-test,便会覆盖红色。

三、模板测试(Stencil Test)

当片段着色器处理完片段之后,模板测试(Stencil Test) 就开始执行了,和深度测试一样,它能丢弃一些片段。仍然保留下来的片段进入深度测试阶段,深度测试可能丢弃更多。模板测试基于另一个缓冲,这个缓冲叫做模板缓冲(Stencil Buffer),我们被允许在渲染时更新它来获取有意思的效果。

模板缓冲中的模板值(Stencil Value)通常是8位的,因此每个片段/像素共有256种不同的模板值(译注:8位就是1字节大小,因此和char的容量一样是256个不同值)。这样我们就能将这些模板值设置为我们链接的,然后在模板测试时根据这个模板值,我们就可以决定丢弃或保留它了。

s
模板测试代码
在这里插入图片描述
模板测试的位置
在这里插入图片描述

四、简单制作魔镜世界

在这里插入图片描述
仅可以通过魔镜看到里面的世界

摆放模型,魔镜前放一个平面
在这里插入图片描述

开启平面的模板测试,测试值为1,让该平面总是通过任何模板测试,ColorMask 0让其完全透明

ColorMask 0
Stencil {
    Ref 1
    comp always
    pass replace
}

在这里插入图片描述
此时移动摄像机会出现闪烁的问题,这是因为排序不明确,该平面设置为2460,魔镜世界设置为2470,让平面一直比魔镜世界先渲染,此时上图不会闪烁,但会一直挡住魔镜世界,此时关闭Z-write即可

ColorMask 0
Stencil {
    Ref 1
    comp always
    pass replace
}
ZWrite off

在这里插入图片描述
此时给魔镜世界开启模板测试,此时模板值为一,只有通过平面才能看到

 //开启模板测试
 Stencil
 {
     Ref 1
     Comp EQUAL
     
 }

接下来解决魔镜世界可以看到其他物件的问题
在这里插入图片描述

给场景添加一个天空盒,这个天空盒非常大且远
在这里插入图片描述

给天空盒开启模板测试,开启ZTest Always

 //开启模板测试
 ZTest Always
 Stencil
 {
     Ref 1
     Comp equal
    
 }

天空盒会为我们剔除没有开启模板测试的外面物件,而保留通过模板测试的物件
在这里插入图片描述

补充

在这里插入图片描述
大家可以用模板测试试着实现以下非欧几里得立方体

参考文献

Unity Shader-渲染队列,ZTest,ZWrite,Early-Z

模板测试(Stencil Test)基本概念

评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值