unity shader之基础 一二三:渲染简介

一:渲染流水线:

应用阶段:主要在CPU执行,准备好需要渲染的数据,输出渲染图元

几何阶段:在GPU执行,主要处理顶点的坐标空间转换,把这些处理过的数据传递给下一阶段

光栅化阶段:在GPU执行,对上一阶段产生的数据,进行着色,最终输出到屏幕上

由于顶点数量要远小于片元数量的,所以一个片元的颜色、深度等,是对顶点进行线性插值得到的

裁剪:把不在摄像机视野内的顶点裁剪掉

三角形设置:根据顶点数据,生成三角形数据

三角形遍历:根据像素和三角形的覆盖情况,获取片元

片元着色器:进行着色

逐片元操作:模板测试,深度测试、透明度测试、透明度混合、深度写入等,决定该片元的最终呈现效果

注意:上面的测试顺序,是在着色器之后进行的,这就会有一个问题,当GPU花费了很大力气,得出了片元的颜色,但是最后没通过测试,舍弃了,这样就浪费了大量的时间

所以现代GPU都尽量把测试提前,在片元着色器之前,就决定出哪些片元不需要渲染

把深度测试提前的技术叫做  Early-Z

测试提前了,又会和片元里面的一些操作冲突,比如 透明度测试,以为在片元里面,需要手动进行clip操作,而在片元之前,如果决定了该片元不会被渲染,就无法进行clip操作,所以 如果有透明度测试,就会关闭提前测试,导致性能下降,因为需要渲染的片元变多了

二 shader基本语法

ShaderLab - Unity 手册

有多个subshader 是因为为了适应不同的GPU

一个subshader 可以有多个pass通道,用来执行渲染

subshader里的标签和pass里的标签含义不一样

pass里面的定义的是该pass使用的光照模型

subshader 和 pass 里面对渲染状态的定义是一致的,比如 ztest alphatest,放在subshader里,表示应用所有的pass,放在pass里表示只应用该pass

当前unity 最新版使用HLSLPROGRAM  ENDPROGRAM,旧版的使用CG,但是CG也可以用,为了兼容

subshader 的标签

其中CanUseSpriteAtlas:表示是否可以使用Legacy Sprite Packer 打包图集里的图,如果为false,则如果该shader中的图是传统图集里的,则会报错 ,默认为true

RenderType 是可以自定义的,用来做着色器替换,unity 内置的rendertype 常见的有

常见的渲染状态命令

​​​​​​​

 三:着色器替换

rendertype 的作用主要是用来进行着色器替换,使用unity内置的方法Camera.RenderWithShaderCamera.SetReplacementShade(shader,rendertype)

规则就是:如果替换目标的rendertype 为空,则把替换的shader应用到所有对象的渲染上

                   如果替换目标的rendertype 不为空,则遍历所有对象的shader

                   如果对象的shader中不包含rendertype的tag,则不进行渲染该对象

                   如果对象的shader不包含替换rendertype的subshader,则不进行渲染

                   如果找到一个subshader的rendertype和你要替换的rendertype一致,就进行替换

一般用来进行边缘检测

使用着色器替换,会自动渲染相机的深度纹理和视角空间下的法线纹理,这是在内置渲染管线内,urp 里面没有法线和深度纹理

3.1 摄像机的深度和法线纹理(内置渲染管线)

摄像机可以生成深度、深度+法线、运动矢量 纹理,主要应用于屏幕后处理效果

深度纹理返回的是0-1之内的像素值,精度在16或32位,取决于不同的平台和配置,非线性

如果想要获取到摄像机之间的距离,可以使用其它宏定义

3.1.1 获得深度纹理、法线纹理的方法

1.通过在脚本中设置 Camera.depthTextureMode 变量开启

2.使用上面的着色器替换功能,自动生成

3.如果使用延迟渲染,深度会自动生成在G-Buffer中

3.1.2 

  Camera.depthTextureMode  有三种可能的深度纹理模式:

  • __DepthTextureMode.Depth__:深度纹理。
  • __DepthTextureMode.DepthNormals__:深度和视图空间法线。
  • __DepthTextureMode.MotionVectors__:当前帧的像素的每帧屏幕运动uv。

3.1.3 DepthTextureMode.Depth 纹理

这将构建一个屏幕大小的深度纹理。

渲染深度纹理时使用的pass与用于渲染阴影的pass相同(RenderPath=ShadowCaster)。如果shader中没有RenderPath=ShadowCaster的pass,fallback中也没有,则使用该着色器的对象将不会显示在深度纹理中。

  • 可以加一个fallback shader,里面有阴影投射通道
  • 如果您在使用表面着色器,那么添加 addshadow 指令也能让它们生成阴影通道。

注意,仅“不透明”对象(这些对象的材质和着色器设置为使用小于等于 2500 的渲染队列)会渲染到深度纹理中。

常见的渲染队列:

分别是1000、2000、2450、3000、4000

3.1.4DepthTextureMode.DepthNormals 纹理

这将构建屏幕大小的 32 位(8 位/通道)纹理,其中视图空间法线编码到 R&G 通道中,而深度编码到 B&A 通道中。法线使用立体投影进行编码,深度是16bit,压缩到到两个 8 位通道中

UnityCG.cginc 具有一个 helper 函数 DecodeDepthNormal,可从编码的像素值中解码深度和法线。返回的深度在 0 到 1 范围内。

3.1.5DepthTextureMode.MotionVectors 纹理

这将构建屏幕大小的 RG16(16 位浮点/通道)纹理,其中屏幕空间像素运动编码到 R&G 通道中。像素运动编码到屏幕 UV 空间中。用来做运动模糊

从该纹理运动采样时,将返回 –1 到 1 范围内的编码像素。这将是从最后一帧到当前帧的 UV 偏移。----------内置渲染管线

通过 (Camera.depthTextureMode) 可能意味着在禁用需要深度纹理的效果后,摄像机可能仍会继续渲染深度纹理。若摄像机上存在多个效果,其中每个效果都需要深度纹理,则无法在禁用单个效果的情况下自动禁用深度纹理渲染。需要注意性能

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

TO_ZRG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值