[UnityShader学习笔记] UnityShader中透明效果及相关原理(深度缓存、深度测试、深度写入和面片剔除等)

Unity 透明物体渲染 深度图景深 默认不论是URP还是buildin都不会渲染深度的,这时候 景深 是不会显示的 URP 渲染物体的时候增加一个材质(size改为2) 然后加入下面的shader Shader "URP_Custom/RenderDepth" { SubShader { Pass { Name "DepthOnly" Tags{"LightMode" = "DepthOnly"} . 阅读详情

前言

  • 此文章为笔者学习《UnityShader入门精要》书籍的学习笔记,因此大部分内容均出自此书;
  • 笔者尽量进行总结,并会补充相关的知识例如片元、深度缓存、帧缓存的概念;
  • 在一些地方如光照模型的计算不会过多涉及,因此需要有一定的光照和图形学基础;
  • 此文章目前没有提供源码。如果你需要源码,请在评论区或者私信我,我会准备源码后放在github上!

渲染顺序

  • 注意:
  • 这部分内容属于理论部分,如果你只想知道如何在UnityShader中实现透明效果,此部分可以省略;
  • 但是为了更好的理解透明效果的原理,笔者认为这部分理论知识是需要掌握的;

如果你曾经使用过绘图软件进行绘画,同一个图层下,如果使用不透明的画笔进行绘画,那么下一笔绘制的肯定会覆盖掉前一笔绘制过的东西。由此可见,绘制顺序在绘制中起到的作用。

图形学中,也需要考虑这个绘制顺序,不然即使A物体在B物体的后面,如果按照先绘制B后绘制A的话,仍然会出现A遮挡住B的情况出现。如下图所示,AB两个物体,会有两种渲染顺序,且它们的渲染结果是截然不同的:
渲染AB两个物体,有两种渲染顺序
然而在渲染管线中,一般是不需要刻意注意绘制顺序的,这是因为GPU中有一个称为深度缓存(z-buffer) 的东西。

深度缓存、深度测试和深度写入

o 深度缓存

所谓深度缓存,和帧缓存(frame-buffer) 一样,是一个二维纹素矩阵,只是上面存储的不是RGBA颜色值,而只存储了一个深度值(z)。

这个深度缓存是为了深度测试(depth-test)服务的,深度测试是片元测试中的其中一部分,发生在渲染管线中片元着色器后面(感兴趣可以了解渲染管线,了解顶点渲染到输出的过程会对图形学的学习有很大帮助)。

o 深度测试

所谓深度测试,简单来说就是将当前需要绘制的内容,和已经绘制的内容的深度进行比较——如果需要绘制的离得更远,就丢弃,否则不丢弃。
假设z越小表示离得越近,将当前要渲染的片元的深度值 Zsrc,与深度缓存中相同位置的深度值 Zdst进行比较,如果:

  • Zsrc > Zdst,说明当前片元更远,被遮挡,即片元被丢弃
  • Zsrc <= Zdst,说明当前偏远更近,可以被渲染

(至于什么是片元,会在后面进行补充)

o 深度写入

最后就是深度写入,顾名思义,就是将一个片元的深度值写入深度缓存当中。
至于写入的时机,一般就是这个片元通过深度测试的时候,也就是说当此片元离得更近时,会将此片元的深度值更新到深度缓存当中。

片元(补充部分)

渲染管线中,当顶点经过图元装配、光栅化以后,得到的内容称为片元(fragment)。片元最后会成为像素,但不是全部的片元都会成为像素,换一句话说,片元有可能会被丢弃。
至于为什么会被丢弃,前面已经说过其中一个原因了,那就是没有通过深度测试。当然深度测试只是片元测试中的一个部分,其他的还有透明度测试等。如下图所示:
片元测试示意图

透明物体对渲染顺序的影响

虽然前面说过,因为有神奇的深度缓存,因此一般来说不用考虑渲染顺序的问题,因为片元会根据自己的深度和已有的深度进行比较后自动丢弃,但这是针对不透明物体而言的。一旦场景中有不透明物体,那么深度缓存、深度测试就“不灵”了。

为什么这么说呢?我们可以进行场景假设,模拟一下实际的渲染。

不透明物体+半透明物体

假设场景中,有物体A和B,且假定A在B的前面,其中A是半透明物体B是不透明物体,如下图所示(其中灰色条纹是背景图,方便效果显式):

在这里插入图片描述


  • 如果我们先渲染B,后渲染A,那么流程是这样的(假定深度缓存为空):
  1. 渲染不透明物体B,进行深度测试;
  2. 由于此时深度缓存为空,所有的片元都通过了深度测试,可以进行渲染、同时将B的深度写入深度缓存中;
  3. 渲染半透明物体A,进行深度测试,从深度缓存中没有发现比自己更靠近的物体,因此A可以进行渲染;

那么渲染结果如下图所示,这样绘制的结果(先绘制不透明物体,后绘制透明物体)是正确的:
在这里插入图片描述


  • 如果我们先渲染A,后渲染B,那么流程是这样的(假定深度缓存为空):
  1. 渲染半透明物体A,进行深度测试;
  2. 由于此使深度缓存为空,所有的片元都通过了深度测试,可以进行渲染,同时将A的深度写入深度缓存中;
  3. 渲染不透明物体B,进行深度测试,从深度缓存中发现已经有比自己更近的物体(即A),因此丢弃物体B;

(*注: 这里的“物体B”丢弃并不完全准确,准确来说是丢弃被A遮挡的B的部分)

那么渲染结果如下图所示。渲染结果是错误的,因为被A遮挡的B的部分完全消失了:
在这里插入图片描述

但我们希望的渲染效果是能透过半透明物体A看到后面的物体B。出现这样的原因,是因为错误的深度测试所造成的,也就是说若只依赖于深度缓存而不管渲染顺序,就会出现这样的情况。

对于渲染顺序,除非引擎内部进行了排序(如 cocos2d-x 3.0以后,会按照局部z和全局z坐标进行一个排序后,再进行渲染),ff否则一般就会按照物体的访问顺序进行渲染,因此上面先渲染A后渲染B是完全有可能的。

从这个场景的两种渲染顺序,我们

Unity Shader透明度测试、透明度混合、开启深度写入的半透明效果、双面渲染的透明效果 Unity中,我们通常使用两种方式来实现透明效果:1.使用透明度测试 2.透明度混合. 透明度测试:只要一个片元的透明度不满足条件,它对应的片元就会被舍弃。被舍弃的片元将不会再进行任何处理,也不会对颜色缓冲产生任何英雄,不需要关闭深度写入. 透明度混合: 使用当前片元的透明度作为混合因子,与以及存储在颜色缓冲中的颜色值进行混合,得到新的颜色。需要关闭深度写入,要非常小心物体的渲染顺序. 问题1... 阅读详情

相关推荐

SCRFD算法解读及环境安装实践

SCRFD检测算法及环境安装

lishanlu136的博客 975

unity获取Transparent的深度信息

unity获取Transparent 材质的深度信息

深度学习入门:使用CMSIS-NN在微控制器上部署模型的完整指南与Python Jupyter实践

CMSIS-NN是ARM为Cortex-M系列微控制器设计的神经网络库。它旨在提供一套高效、轻量级的神经网络API,使得开发者可以在资源受限的微控制器上运行深度学习模型。CMSIS-NN优化了各种常见的神经网络层,如卷积层、全连接层等,确保它们在微控制器上的运行效率。# 定义模型])# 编译模型# 训练模型这样,我们就得到了一个简单的手写数字识别模型。注意:为了简洁清晰,本文中的代码可能不是最优的或最完整的实现。为了获得完整的项目更多的优化技巧,请下载完整项目。

m0_57781768的博客 5848

Unity半透明特效原理讲解(为什么半透明设置渲染顺序深度写入这么重要)

Unity半透明特效原理讲解(为什么半透明设置渲染顺序深度写入这么重要)

iiiiiiimp的博客 6265

Unity 入门精要》第8章 透明效果

透明效果

m0_37979033的博客 2365

Unity Shader入门精要 第8章】透明效果(四)

前面提到过,在进行半透物体的渲染时需要关闭深度写入,但是如果物体本身存在复杂的遮挡关系时,关闭深度写入的渲染就会出现问题。如上图红框中的部分,这种情况下,可以使用开启深度写入的半透渲染方式。这里我们通过 ZWrite On 开启深度写入

zhiai315的博客 1000

Unity Shader入门精要 第八章——透明效果

透明度测试:只要有一个片元的透明度不满足条件(通常是小于某个阈值),那么其对应的片元将会被舍弃。被舍弃的片元将不会再进行任何处理,也不会对颜色缓冲产生任何影响,否则就会按照普通的不透明物体的处理方式来处理它。根据描述,我们发现透明度测试是不需要关闭深度写入,但产生的效果也很极端,要么完全透明,要么完全不透明。我们一般使用clip函数来进行透明度测试。clip是CG当中的一个函数:void clip(float4 x),里面的参数还可以是float3、float2、float2、float1、float。

buzhengli的博客 3110

Unity Shader学习3:透明效果

如图8.1中,若先渲染A,由于关闭了半透明物体的深度写入,此时深度缓冲中不会写入A的深度值,再渲染B的时候,由于B是不透明物体,且深度缓冲中没有值,那么B的片元则会通过深度测试写入深度值,同时覆盖颜色缓冲中A之前渲染得到的颜色值,效果就变成了A被B遮挡。如图8.2中,若先渲染A, 那么A的颜色会先写入颜色缓冲,再渲染B,B片元的颜色值颜色缓冲的值混合时,混合后的效果会反过来,看起来像B覆盖在A上。它会使用当前片元的透明度做为混合因子,与已经存储在颜色缓冲中的颜色值进行混合,得到新的颜色。

Little_Double_E的博客 2635

《Shader入门精要》透明效果

在实时渲染中要实现透明效果,通常会在渲染模型时控制它的。当开启透明混合后,当一个物体被渲染到屏幕上时,每个片元除了颜色值深度值之外,它还有另一个属性——透明度。当透明度为1时,表示该像素是完全不透明的,而当其为0时,则表示该像素完全不会显示。我们通常使用两种方法来实现透明效果:第一种是使用​,这种方法其实无法得到真正的半透明效果;另一种是​。在实时渲染中,,它可以决定哪个物体的哪些部分会被渲染在前面,而哪些部分会被其他物体遮挡。它的。

zaizai1007的博客 1417

UnityShader入门精要-透明效果

unityshader 透明效果:透明度测试、透明度混合、开启深度缓存的透明度混合,双面渲染

weixin_58624886的博客 837

第七章 透明效果(1)

1.透明效果 透明是游戏中经常要使用的一种效果,在实时渲染中要实现透明效果,通常会在渲染模型时控制它的透明通道(Alpha Channel)。当开启透明混合后,当一个物体被渲染到屏幕上时,每个片元除了颜色值深度值外,它还有另一个属性——透明度。当透明度为1时,表示该像素是完全不透明的,而当其为0时,则表示该像素完全不会显示。 在Unity中,我们通常使用两种方式来实现透明效果:第一种是使用透明度...

御坂御坂001的博客 548

[UnityShader入门精要读书笔记]18.开启深度写入的半透明效果

当模型本身有复杂的遮挡关系或是包含了复杂的非凸网格的时候,就会有各种各样因为排序错误而产生的错误的透明效果。由于关闭了深度写入,无法对模型进行像素级别的深度排序。一种解决方法是使用两个pass来渲染模型:第一个Pass开启深度写入,但不输出颜色,它的目的仅仅是为了把该模型的深度写入深度缓冲中;第二个Pass进行正常的透明度混合,由于上一个Pass已经得到了逐像素的正确的深度信息,该Pass就可以...

songtianqi123的专栏 479

UnityShader】透明度混合

快速浏览总述透明度混合基本原理透明度混合的实现Blend 命令关闭深度写入带来的问题开启深度写入的半透明效果ColorMaskShaderLab的混合命令注意Blend命令详述混合因子BnendOp BlendOperation(混合操作命令)常见的混合类型透明度混合代码实现开启深度写入的半透明效果代码实现 总述 关闭深度写入,ZWrite Off,不会修改深度缓冲中的值,但不影响修改颜色缓冲中的值。原因:如果不关闭深度写入,就无法透过半透明表面看到后面的物体了。 不需要关闭深度测试Unity 在使用

小蜗牛 1650

第8章 透明效果

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接本声明。 ...

m1234567q的专栏 585

Unity Shader入门精要学习笔记 - 第8章 透明效果

转载自 冯乐乐的 《Unity Shader入门精要》 透明是游戏中经常要使用的一种效果。在实时渲染中要实现透明效果,通常会在渲染模型时控制它的透明通道。当开启透明混合后,当一个物体被渲染到屏幕上时,每个片元出了颜色值深度值之外,它还有另一个属性——透明度。当透明度为1时,表示该像素是完全不透明的,而当其为0时,则表示该像素完全不会显示。 在Unity中,我们通常使用两种方法来实现透明效果:...

miaobeihai的博客 431

UnityShader学习

知识补充 Subshader 可以在subshader下定义多个TagsState 定义对所有Pass都生效 如果需要可以单独对逐个Pass进行生效 Tags 可以定义n个标签 用键值对的形式来实现 Queue队列标签 用队列标签来确定物体的渲染顺序 Background最先进行渲染Skybox或者背景,队列号1000 Geometry,渲染非透明的几何体所采用的队列,没有声明渲染队列的时候,unity默认使用此队列,队列号2000 AlphaTest,Alpha测试的几何体使用的队列,在所有几何体

TongOuO的博客 637

Unity Shader入门

文章目录前言环境Unity的帧调试器Unity Shader 概述详解基于Unity编写的Blinn-Phong Shader 前言 本文对应《Unity Shader入门精要》一书的初级篇,为自己的学习笔记与思考补充。 环境 Unity版本:2020.1.6f1c1 编写shader:VS2019+ShaderlabVS 其中ShaderlabVS为VS的一个插件,安装地址: https://marketplace.visualstudio.com/items?itemName=ShaderlabVS20

weixin_47652005的博客 1029

深度写入Depth Write深度测试Depth Test 黑洞效果

深度写入深度写入的功能是判断该材质是否会剔除后面的像素,所以只要开启的Depth Write不管是否为透明物体,都会根据Z来遮挡后面的物体。 深度测试:是通过比较深度值,判断该材质如何去被剔除像素。 虽然透明的材质不会开启Depth Write,但深度值Z不管是否为透明材质都会有,所以透明物体才会被前面开启了深度写入的材质给挡住。 通过深度写入ColorMask的功能可以实现一些特殊的效果,比如:黑洞的效果 Depth Write On 写入深度并在地面上,这样可以遮挡地面 ...

weixin_43879652的博客 5861

Unity Shader】实现透明度测试透明度混合

Unity中实现透明度测试透明度混合。

qq_41835314的博客 4636

Unity URP】2种描边方案:模板测试正面剔除

Unity URP下双Pass实现描边方案概述

qq_41835314的博客 6587

公开整理-面板数据-城投公司基本信息及地方债、城投债数据(1999-2024年).txt

因文件较多,数据存放网盘,txt文件内包含下载链接及提取码,永久有效。失效会第一时间进行补充。样例数据及详细介绍参见文章:https://blog.csdn.net/T0620514/article/details/153393387

上一篇: 从图形学认识Unity中的Mesh
下一篇: 「Unity」时间记录小工具
Atelier_01
博客等级 码龄9年 14粉丝 5原创
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值