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

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

  • ZTest(深度测试)和ZWrite(深度写入)
    • ZTest Less(深度小于当前缓存则通过)
    • ZTest Greater(深度大于当前缓存则通过)
    • ZTest LEqual(深度小于等于当前缓存则通过)
    • ZTest GEqual (深度大于等于当前缓存则通过)
    • ZTest Equal (深度等于当前缓存则通过)
    • ZTest NotEqual(深度不等于当前缓存则通过)
    • ZTest Always(不论如何都通过)
    • 注意,ZTest Off等同于ZTest Always,关闭深度测试等于完全通过。
    • 方法一:让绿色的对象不被前面的立方体遮挡,一种方式是关闭前面的蓝色立方体深度写入:
    • 方法二:另一种方式是让绿色强制通过深度测试:
    • 那么如果红色的也开了ZTest Always会怎么样?
    • 再看一下Greater相关的部分有什么作用,这次我们其他的都是用默认的渲染状态,绿色的立方体shader中ZTest设置为Greater:
    • 有一个好玩的效果其实就可以考ZTest Greater来实现,就是游戏里面经常出现的,当玩家被其他场景对象遮挡时,遮挡的部分会呈现出X-光的效果;其实是在渲染玩家时,增加了一个Pass,默认的Pass正常渲染,而增加的一个Pass就使用Greater进行深度测试,这样,当玩家被其他部分遮挡时,遮挡的部分才会显示出来,用一个描边的效果渲染,其他部分仍然使用原来的Pass即可。

ZTest(深度测试)和ZWrite(深度写入)

之前一篇渲染队列的例子中,虽然渲染的顺序反了过来,但是物体之间的遮挡关系仍然是正确的,这就是z-buffer的功劳,不论我们的渲染顺序怎样,遮挡关系仍然能够保持正确。而我们对z-buffer的调用就是通过ZTest和ZWrite来实现的。

首先看一下ZTest,ZTest即深度测试,所谓测试,就是针对当前对象在屏幕上(更准确的说是framebuffer)对应的像素点,将对象自身的深度值与当前该像素点缓存的深度值进行比较,如果通过了,本对象在该像素点才会将颜色写入颜色缓冲区,否则不会写入颜色缓冲。ZTest提供的状态较多。

ZTest Less(深度小于当前缓存则通过)

ZTest Greater(深度大于当前缓存则通过)

ZTest LEqual(深度小于等于当前缓存则通过)

ZTest GEqual (深度大于等于当前缓存则通过)

ZTest Equal (深度等于当前缓存则通过)

ZTest NotEqual(深度不等于当前缓存则通过)

ZTest Always(不论如何都通过)

注意,ZTest Off等同于ZTest Always,关闭深度测试等于完全通过。

下面再看一下ZWrite,ZWrite比较简单,只有两种状态,ZWrite On(开启深度写入)和ZWrite Off(关闭深度写入)。当我们开启深度写入的时候,物体被渲染是针对物体在屏幕(更准确的说是frame buffer)上每个像素的深度都写入到深度缓冲区;反之,如果是ZWrite Off,name物体的深度就不会写入深度缓冲区。但是,物体是否会写入深度,除了ZWrite这个状态之外,更重要的是需要深度则是通过,也就是说ZTest通过,如果ZTest都没通过,那么也就不会写入深度了。就好比默认的渲染状态是ZWrite On和ZTest LEqual,如果当前深度测试失败,说明这个像素对应的位置,已经有一个更靠前的东西占坑了,即使写入了,也没有原来的更靠前,那么也就没有必要再去写入深度了。所以上面的ZTest分为通过和不通过两种情况,ZWrite分为开启和关闭两种情况的话,一共四种情况:
1.深度测试通过,深度写入开启;写入深度缓冲区,写入颜色缓冲区;
2.深度测试通过,深度写入关闭;不写入深度缓冲区,写入颜色缓冲区;
3.深度测试不通过,深度写入开启;不写入深度缓冲区,不写入颜色缓冲区;
4.深度测试不通过,深度写入关闭;不写入深度缓冲区,不写入颜色缓冲区;
在这里插入图片描述
写几个简单的小例子来看一下ZTest,ZWrite以及Render Queue这几个状态对渲染结果的控制。

方法一:让绿色的对象不被前面的立方体遮挡,一种方式是关闭前面的蓝色立方体深度写入:

在这里插入图片描述
通过上面的实验结果,我们知道,按照从前到后的渲染顺序,首先渲染蓝色物体,蓝色物体深度测试通过,颜色写入缓存,但是关闭了深度写入,蓝色部分的深度缓存值仍然是默认的Max,后面渲染的绿色立方体,进行深度测试仍然会成功,写入颜色缓存,并且写入了深度,因此蓝色立方体没有起到遮挡的作用。

方法二:另一种方式是让绿色强制通过深度测试:

在这里插入图片描述
这个例子中其他立方体的shader使用默认的渲染方式,绿色的将ZTest设置为Always,也就是说不管怎样,深度测试都通过,将绿色立方体的颜色写入缓存,如果没有其他覆盖了,那么最终的输出就是绿色的了。

那么如果红色的也开了ZTest Always会怎么样?

在这里插入图片描述
在红色立方体也用了ZTest Always后,红色遮挡了绿色的部分显示为了红色。如果我们换一下渲染队列,让绿色在红色之前渲染,结果就又不一样了:
在这里插入图片描述
更换了渲染队列,让绿色的渲染队列+1,在默认队列Geometry之后渲染,最终重叠部分又变回了绿色。可见,当ZTest都通过时,上一个写入颜色缓存的会覆盖上一个,也就是说最终输出的是最后一个渲染的对象颜色。

再看一下Greater相关的部分有什么作用,这次我们其他的都是用默认的渲染状态,绿色的立方体shader中ZTest设置为Greater:

这个效果就比较好玩了,虽然我们发现在比较深度时,前面被蓝色立方体遮挡的部分,绿色的最终覆盖了蓝色,是想要的结果,不过其他部分哪里去了呢?简单分析一下,渲染顺序是从前到后,也就是说蓝色最先渲染,默认深度为Max,蓝色立方体的深度满足LEqual条件,就写入了深度缓存,然后绿色开始渲染,重叠的部分的深度缓存是蓝色立方体写入的,而绿色的深度值满足大于蓝色深度的条件,所以深度测试通过,重叠部分颜色更新为绿色;而与红色立方体重合的部分,红色立方体最后渲染,与前面的部分进行深度测试,小于前面的部分,深度测试失败,重叠部分不会更新为红色,所以重叠部分最终为绿色。而绿色立方体没有与其他部分重合的地方为什么消失了呢?其实是因为绿色立方体渲染时,除了蓝色立方体渲染的地方是有深度信息的,其他部分的深度信息都为Max,蓝色部分用Greater进行判断,肯定会失败,也就不会有颜色更新。

有一个好玩的效果其实就可以考ZTest Greater来实现,就是游戏里面经常出现的,当玩家被其他场景对象遮挡时,遮挡的部分会呈现出X-光的效果;其实是在渲染玩家时,增加了一个Pass,默认的Pass正常渲染,而增加的一个Pass就使用Greater进行深度测试,这样,当玩家被其他部分遮挡时,遮挡的部分才会显示出来,用一个描边的效果渲染,其他部分仍然使用原来的Pass即可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/298240.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux--Shell脚本应用实战

实验环境 随着业务的不断发展,某公司所使用的Linux服务器也越来越多。在系统管理和维护过程中,经 常需要编写一些实用的小脚本,以辅助运维工作,提高工作效率。 需求描述 > 编写一个名为getarp.sh的小脚本,记录局域…

宝塔面板Linux服务器CentOS 7数据库mysql5.6升级至5.7版本教程

近段时间很多会员问系统更新较慢,也打算上几个好的系统,但几个系统系统只支持MYSQL5.7版本,服务器一直使用较低的MYSQL5.6版本,为了测试几个最新的系统打算让5.6和5.7并存使用,参考了多个文档感觉这种并存问题会很多。…

第十一节TypeScript Array(数组)

1、描述 数组对象是使用单独的变量名来存储一系列的值。 比如,你现在有一组数据,存单独变量如下: var data1"Android"; var data2"Java"; var data3"Harmony"; 那如果有10、100个这种变量呢,那…

指法练习软件TT

1、说明 这个是90年代后期读书时写的C语言练习软件,模仿当时的打字练习软件。 在技能上使用屏幕直接输出,支持彩色,能够在DOS和Windows98的窗口下运行。 2、主要界面 支持多用户档案,以键盘操作。 进入具体用户档案后&#xff0c…

路由器介绍和命令操作

先来回顾一下上次的内容: ip地址就是由32位二进制数组 二进位数就是只有数字0和1组成 网络位:类似于区号,表示区域作用 主机位:类似于号码,表示区域中编号 网络名称:网络位不变,主机位全为0 …

java IO

主要内容 java.io.File类的使用 IO原理及流的分类 文件流 FileInputStream / FileOutputStream / FileReader / FileWriter 缓冲流 BufferedInputStream / BufferedOutputStream / BufferedReader / BufferedWriter 转换流 InputStreamReader / OutputStreamWriter 标准…

树莓派,opencv,Picamera2利用舵机云台追踪人脸(PID控制)

一、需要准备的硬件 Raspiberry Pi 4b两个SG90 180度舵机(注意舵机的角度,最好是180度且带限位的,切勿选360度舵机)二自由度舵机云台(如下图)Raspiberry CSI 摄像头 组装后的效果: 二、项目目…

MP3音乐播放器搜索引擎-窗口实现

在Headers里面添加新文件 想在mainwindow里面通过点击按钮出现这个新的对话框我们应该将新的对话框的头文件添加到mainwindow.h 然后我们可以创建一个AboutADialog对象,模态对话框就是只能对模态对话框进行操作点不了主窗口,非模态对话框则可以&#xff…

tensorboard可视化——No dashboards are active for the current data set.

No dashboards are active for the current data set. 出现问题的原因是事件的路径未用绝对路径,tensorboard --logdir./runs --port6007 改为tensorboard --logdirD:\Code\Python\Study\CL\hat-master\hat-master\run s\one --port6007就好了

论文阅读:Blind Super-Resolution Kernel Estimation using an Internal-GAN

这是发表在 2019 年 NIPS 上的一篇文章,那个时候还叫 NIPS,现在已经改名为 NeurIPS 了。文章中的其中一个作者 Michal Irani 是以色 Weizmann Institute of Science (魏茨曼科学研究学院) 的一名教授,对图像纹理的内在统计规律有着很深入的研…

yolo实现数据增强(数据集不够,快速增加数据集)

目录结构 附上数据增强的全部代码 # -*- codingutf-8 -*-import time import random import copy import cv2 import os import math import numpy as np from skimage.util import random_noise from lxml import etree, objectify import xml.etree.ElementTree as ET imp…

leetcode 1576. 替换所有的问号(easy)(优质解法)

链接&#xff1a;1576. 替换所有的问号 代码&#xff1a; class Solution {public String modifyString(String s) {char[] charSs.toCharArray();int lengthcharS.length;//遍历找到 &#xff1f;for(int i0;i<length;i){if(charS[i]?){//遍历 a ~ z 选择一个合适的字符来…