首页 > 其他分享 >unity URP前向渲染流程以及获取屏幕空间UV和深度

unity URP前向渲染流程以及获取屏幕空间UV和深度

时间:2023-01-30 17:05:36浏览次数:43  
标签:UV 渲染 裁剪 获取 unity 前向 深度 空间 屏幕


前向渲染流程

cpu上进行剔除和排序,剔除为,相机的视椎体剔除,将相机视角外的模型剔除掉,不再渲染。遮挡剔除,将视椎体内不可见的模型剔除掉,不再渲染。排序为了保证性能,不透明为从近到远,减少不必要的渲染,半透明物体为了保证正确性,从远到近。

cpu上获取到所需的相关模型数据:顶点数据 贴图数据 还有材质属性,将数据提交给gpu,并调用gpu进行渲染,每调用渲染一次,为一次drawcall。

在gpu上,分为两部分,一部分是顶点着色器,另一部分是片元着色器。
在顶点着色器里,主要是位置变换,将顶点的位置,依次是 模型空间 世界空间 视线空间 裁剪空间 这个过程是 MVP矩阵变换。

在顶点着色器到片元着色器中间还有一个过程,这个过程中,将进行裁剪剔除,将不在屏幕中的片元裁剪到只在裁剪显示空间内的,显示范围为[-w, w],在这里得到的四维变量 xy是裁剪空间下的xy坐标,z是深度,w就是w,注意这里,因为获取屏幕uv也需要在这一步操作,而且不同平台的兼容的问题也需要从这一步开始出现,因为深度也就是z从这一步根据平台也不同。然后进行NDC(归一化设备坐标系),归一化操作,在unity里面,xy限制在0到w之间,而深度z,根据平台不同,则为-w到w或者0-w。NDC操作完成之后,将进行背面剔除,将一些无法看到图元(主要是三角形面,点和线不需要)给剔除掉。图元三角形的三个点如果是顺时针渲染的为背面,将被剔除,逆时针渲染的面为正面,将被渲染。

背面剔除完成以后,将要转换到屏幕空间(或者缓冲区空间),这里将根据渲染的宽高进行转换,转换完成后,将进行图元装配,然后进行光栅化,光栅化可以理解为获取到图元占用屏幕的像素(一般叫片元),占用多少像素,将调用多少次的片元着色器进行运算颜色。这个步骤是图元的所有的片元结果同步计算的。

片元着色器运算完成,就到了最后输出合并阶段。你计算完成后,也不一定能够给像素填充颜色,我们还需要进行多个测试,通过这些测试以后,才可以将颜色写入帧缓冲区。这些步骤分别是:

  1. 半透明测试 根据透明度,将多少透明度以下的颜色直接放弃写入。unity里面函数是clip,内部如果传入的值小于0,则不会写入颜色。
  2. 模板测试 根据之前设置的模板,对比,如果通过将继续下一步。
  3. 深度测试 对比帧缓冲区的深度,通过继续下一步。
  4. 混合测试 这一步主要针对于半透明物体的,当前的颜色和帧缓冲区的像素颜色按比例进行混合,得到最终颜色。
    最后,完成后,可以顺利的将颜色写入到缓冲区。注意,缓冲区不单单只存储了像素的颜色,还有深度信息,以及模板信息。

获取屏幕空间UV

前面渲染流程说了这么多,那么大家应该能清楚如何去获取屏幕uv了吧。肯定是NDC空间的xy坐标就是了,那么怎么获取,在urp里面,有两种方式,先说一下最简单的:

unity URP前向渲染流程以及获取屏幕空间UV和深度_uv


如下,直接使用urp内置的GetVertexPositionInputs函数,传入模型空间下的顶点坐标,即可获取到包含世界空间,视线空间,裁剪空间,NDC空间下的所有信息。我们可以看一下结构体:

unity URP前向渲染流程以及获取屏幕空间UV和深度_游戏引擎_02


第二种方式呢,就是我们通过裁剪空间下的坐标自己去计算,unity也内置了相关方法,

unity URP前向渲染流程以及获取屏幕空间UV和深度_uv_03


可以看到,其实就是修改了xy的坐标,zw根本没动。将xy从-w到w,变换到了0到w的区间。

unity URP前向渲染流程以及获取屏幕空间UV和深度_着色器_04


_ProjectionParams的x项是为了兼容平台,dx的y坐标0是上面,而opengl平台的0到1是从下向上。

我还找到了屏幕的宽高常量:

unity URP前向渲染流程以及获取屏幕空间UV和深度_游戏引擎_05


还有时间相关的

unity URP前向渲染流程以及获取屏幕空间UV和深度_着色器_06


再列一下其它的吧

unity URP前向渲染流程以及获取屏幕空间UV和深度_贴图_07


这些都在UnityInput.hlsl文件中,大家可以自己去看看。回归正题,既然我们得到NDC空间的xy,它们现在的区间范围是[0, w],那么就好办了,只要我们除以w,那么就得到了屏幕空间下的UV坐标了。

unity URP前向渲染流程以及获取屏幕空间UV和深度_unity_08

获取深度

上面,我们获取到屏幕的UV,是通过NDC空间下的坐标xy获取的,其实z的值就是深度,我们获取深度,首先限制到0-1或者根据平台不同,在-1到1之间,其实就是处于w就好了。

unity URP前向渲染流程以及获取屏幕空间UV和深度_着色器_09


这样,可以获得,距离相机越近的物体,颜色越量,越远的,就越暗。

unity URP前向渲染流程以及获取屏幕空间UV和深度_unity_10


为什么要这么写呢,因为unity里面已经内置好了各个平台的近裁剪面和远裁剪面的值,我们只需要判断一下即可

unity URP前向渲染流程以及获取屏幕空间UV和深度_贴图_11


unity URP前向渲染流程以及获取屏幕空间UV和深度_着色器_12


unity URP前向渲染流程以及获取屏幕空间UV和深度_贴图_13


上面列举了几个,平台的远裁剪面和近裁剪面归一化后的值,我们就可以以此来计算出统一的深度渲染效果,剩下的你可以自己在unity库里面搜索一下,名字在下面列出来了。

unity URP前向渲染流程以及获取屏幕空间UV和深度_贴图_14

获取深度贴图内的深度

情绪都到这了,那么再写一下如何实现获取深度贴图内的深度吧。

首先,你要在urp Pipeline Asset里面,开启深度纹理渲染。

unity URP前向渲染流程以及获取屏幕空间UV和深度_uv_15


开启了以后,你可以在shader里面声明纹理_CameraDepthTexture,就可以获取到深度贴图了。

然后拿着上面获取到的屏幕uv,你就能够获取到深度贴图上的深度了。

unity URP前向渲染流程以及获取屏幕空间UV和深度_游戏引擎_16


就这么简单,你就获取到了深度,渲染出来,就是这样的

unity URP前向渲染流程以及获取屏幕空间UV和深度_游戏引擎_17


最后,还有一个问题,现在深度贴图里面的深度和你获取到的深度,它不是线性的,我们需要转成线性的,unity也有内置方法

unity URP前向渲染流程以及获取屏幕空间UV和深度_着色器_18


根据自己需求用,一个是从近裁剪面开始算的,一个是从相机位置开始算的。1就是远裁剪面。

第一个值就传入你计算出来的深度,或者从深度贴图里面获取到的深度。

第二个值 _ZBufferParams,我上面也截图了,你可以从上面找。

结束。


标签:UV,渲染,裁剪,获取,unity,前向,深度,空间,屏幕
From: https://blog.51cto.com/u_15948039/6027339

相关文章

  • unity urp 实现车漆效果
    车漆的效果除了基础的pbr效果,上面还可以添加两层额外的效果。一层是清漆的效果,另一层就是薄膜干涉的效果。这个就是薄膜干涉的效果,可以明显的看出来颜色被分散开来。这里......
  • unity urp 实现衣服上面片的效果
    在看模特秀的时候,有时候身上会有那种布灵布灵的面片效果。下面两张是我在丝绸的时装秀里面截取的两张模糊图,凑合看一下吧。如果需要在渲染里面去实现这种效果,该如何实现呢......
  • 在unity 2020 urp版本中实现 LensFlare功能
    这个官方里面没有支持,只能自己去解决。效果请查看地址:https://www.bilibili.com/video/BV1w24y1o7pY/下面说一下我的实现过程。找来找去,我找到了一篇不错的解决方案,还带源......
  • unity中实现ue眼球的渲染
    此图取至ue官方网站在shader里面我们还是需要使用英文,中英文对照:巩膜:sclera角膜缘:limbus虹膜:iris瞳孔:pupil角膜:cornea渲染效果。模型方面:使用一个突出的眼球模型来......
  • Unity 热更新方案
    一、Lua:内置一个Lua虚拟机。典型的框架有xLua,uLua。 二、ILRuntime:内置一个.net字节码解释器,解释执行.net字节码。三、puerts:内置一个JavaScript/TypeScrip......
  • uView2.0 对http进行封装
    request.js://此vm参数为页面的实例,可以通过它引用vuex中的变量import{$config}from'@/config/config';module.exports=(vm)=>{//初始化请求配置uni.$......
  • The GPG keys listed for the "MySQL 5.7 Community Server" repository are already
    报错TheGPGkeyslistedforthe"MySQL5.7CommunityServer"repositoryarealreadyinstalledbuttheyarenotcorrectforthispackage.Checkthatthecorrec......
  • uv值显示为颜色
     UVColor.shaderShader"My/UVColor"{Properties{}SubShader{Tags{"RenderType"="Opaque"}......
  • 关于blender导入到unity……
    我快被该死的左右手坐标轴搞疯了,于是做了个实验:我在blender里建了个箭头,让箭头朝向z轴,再在y轴正方向上写了个y,x轴正方向写了个x,然后ctrl+a应用全部。然后直接以blender文......
  • 3-reg model构建篇-uvm_reg_block
    1. uvm_reg_block的特点(1) 一个寄存器模型必须包含一个reg_block; 一般DUT内具有相同的基地址的所有寄存器,会放在一个reg_block中.(2) uvm_reg_block可以包含任意......