Unity3d_Shader

本文详细介绍了Unity3D中的Shader工作原理,包括CPU与GPU的通信、渲染流水线、SubShader的结构、渲染状态设定和Tags标签的使用。SubShader允许根据目标平台选择合适的着色器,通过Tags可以控制渲染顺序和类型。渲染状态如Cull、ZTest、ZWrite和Blend等则影响着渲染效果。理解并掌握这些概念对于优化Unity3D的图形性能至关重要。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CPU与GPU之间的通信:

渲染流水线的起点是CPU,即应用阶段:(1)把数据加载到显存(2)设置渲染状态(3)调用DRAW CALL (draw call命令是由cpu发起的,接受方是GPU,GPU会根据渲染状态和所有顶点数据来进行渲染,最终把图元渲染到屏幕上)

shader的渲染流水线,应用阶段(主要由cpu负责实现。是开发者拥有控制权,这个一阶段的主要准备要渲染状态具体包括使用的材质(漫反射颜色、高光反射颜色),使用的纹理、使用的哪种顶点着色器等等)-几何阶段(这阶段主要由GPU负责实现。主要任务是把顶点坐标变换到屏幕空间中,再交给光栈化阶段处理)-光栈化阶段(这阶段也是由GPU负责实现。把上一阶段产生的数据来产生屏幕上的像素)。

【untiy shader–准确认识SubShader语义块结构、渲染状态设定、Tags标签】

一【SubShader】
  每个UnityShader文件可以包含多个SubShader语义块,但至少要有一个。当Unity需要加载这个UnityShader时,
Unity会扫描所有的SubShader语义块,然后选择一个能够在目标平台上运行的SubShader。如果都不支持的话,Unity
就会使用FallBack语义指定的UnityShader。
  Unity提供这种语义的原因在于,不同的显卡具有不同的能力。例如,一些旧的显卡仅能支持一定数目的操作指令,
而一些高级的显卡可以支持更多的指令数,那么我希望在旧的显卡上使用计算复杂度较低的着色器,而在高级的显卡上
执行计算复杂度高的着色器,以便提供更出色的画面效果。

SubShader
{
  //可选的
  [Tags]
  //可选的
  [RenderSetup]

  Pass
  {

  }
  //或更多Pass

}
  SubShader中定义了一系列的Pass以及可选的标签[Tags]、状态[RenderSetup]。每个Pass定义一次完整的渲染流程
但是如果Pass数目过多会造成渲染性能的下降。因此,我们尽量使用数量最小的Pass。
补充说明:[Tags][RenderSetup]也可以在Pass中声明。不同的是,SubShader中的一些标签设置是特定的。也就是说,
这些标签和Pass中设置的标签是不一样的。而对于状态设置来说,其使用的语法是相同。不过在SubShader进行的设置
将会用于所用的Pass。

二【渲染状态】
  ShaderLab提供了一系列渲染状态的设定,这些指令可以设置显卡的各种状态,例如是否开启混合/深度测试等。
状态名称    设置指令                            解释
Cull     Cull Back|Front|Off                      设置剔除模式,剔除背面|正面|关闭剔除 默认CullBack
ZTest    ZTest Less Greater|LEqual|GEqual|Equal|NotEqual|Always    设置深度时使用的函数        默认ZTest LEqual 小于或等于目标深度才能被渲染
ZWrite    ZWrite On|Off                        开启和关闭深度写入         默认ZWrite On
Blend    Blend SrcFactor DstFactor                   开启并设置混合模式

​   当在SubShader块中设置了上述状态,将会被应用于所有的Pass。如果不想这样(例如在双面渲染中,我们可以希望第一
个Pass剔除正面来对背面进行渲染,在第二个Pass中选择剔除背面来对正面进行渲染),可以在Pass内部来单独设置状态。

三【Tags标签】
  UnityShader的Tags是一个键值对(Key/Value Pair),他的键和值都是字符串类型。这些键值是对SubShader和渲染引擎
之前沟通的桥梁。他们用于告诉渲染引擎:怎么样和什么时候调用这个SubShader。
标签语法如下:Tags{“TagName1” = “Value1” “TagName2” = “Value2”}

SubShader标签类型:注意这些标签只能在SubShader中声明,不能再Pass中
  标签类型                  说明                   列    子
Queue          控制渲染顺序,指定该物体属于哪一个渲染队列      Tags{“Queue” = “Transparent”}
RenderType        对着色器分类。例如:这是一个不透明着色器       Tags{“RenderType” = “Opaque”}
DisableBatching      一些SubShader在使用Unity批处理时会出现问题。
             可以用该标签直接表明是否使用批处理          Tags{“DisableBatching” = “True”}
ForecNoShadowCasting    控制该SubShader的物体是否会投射阴影        Tags{“ForceNoShadowCasting” = “True”}
IgnoreProjector        设置该SubShader的物体是否受Projector影响      Tags{“IgnoreProjector” = “True”}
              True常用与半透明物体。
CanUseSpriteAtlas       当该SubShader用于“sprite”时,将该标签设为False    Tags{“CanUseSpriteAtlas” = “False”}
PriviewType          材质面板的预览类型,一般默认材质预览效果是球形   Tags{“PreviewType” = “Plane”}
              还可以该为"Plane" “SkyBox”。

四【Pass语义块】
Pass
{
  [Name]
  [Tags]
  [RenderSetup]
  //other code
}
1、[Name]Pass名称
  Pass的名称,可以使用ShaderLab的UsePass命令来使用其他Shader的Pass代码
例如:UsePass"MyShader/MYPASSNAME",这样提高代码复用性,
注意:UnityShader内部会自动把PassName转换成大写格式。
2、[RenderSetup]Pass渲染状态设置
  SubShader的渲染状态也适用于Pass,而且Pass还可以适用固定管线着色器的命令
3、[Tags]Pass的标签
  Pass的标签不同于SubShader标签,这些标签用于告诉渲染引擎我们希望如何来渲染物体
  标签类型        说明                 例子
LightModel     定义该Pass在渲染管线中的角色      Tags{“LightModel”=“ForwardBase”}
RequireOption    用于指定满足某些条件是才渲染该    Pass Tags{“RequireOption” = “SoftVegetation”}

ColorMask  可以让我们制定渲染结果的输出通道,而不是通常情况下的RGBA这4个通道全部写入。可选参数是 RGBA 的任意组合以及 0, 这将意味着不会写入到任何通道。

个人总结:
shader对于一些形状复杂的物体(或物体之间有缠绕遮挡)渲染时,使用两个pass,第一个开启深度写入,第二个关闭深度写入。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值