Unity Shader的结构

材质和Unity Shader

在unity中,需要配合使用材质Material和Unity Shader才能达到需要的效果

流程

创建一个材质→创建一个Unity Shader,并把它赋给上一步中创建的材质→把材质赋给要渲染的对象→在材质面板中调整Unity Shader的属性,以得到满意的效果

Unity中的材质

Unity中的材质需要配合一个GameObject的Mesh或者Particle Systen组件来工作,它决定了我们的游戏对象看起来是什么样子的

Unity中的Shader

为了和前面通用的Shader语义进行区分,这里把Unity中的Shader文件统称为Unity Shader
Unity Shader和之前提及的渲染管线的Shader有很大的不同

Unity4种Shader模板
  • Standard Surface Shader:产生一个包含标准关照模型的表面着色器模板
  • Unity Shader:产生一个不包含光照的基本的顶点/片元着色器
  • Image Effect Shader:实现各种屏幕后处理效果
  • Compute Shader:产生一个特殊的Shader文件,旨在利用GPU的并行性进行一些常规渲染流水线无关的计算
Unity会显示Shader的相关信息
  • 是否是一个表面着色器
  • 是否是一个固定函数着色器(Fixed Function Shader)
  • 标签设置(是否会投射阴影,使用的渲染队列,LOD值)

Unity Shader的基础:SharderLab

在Unity Shader的帮助下,开发者只需要使用ShaderLab来编写Unity Shader文件就可以完成所有工作

Shader"ShaderName"
{
    
    
	Properties{
    
    //属性}
	SubShader{
    
    //显卡A使用的子着色器}
	SubShader{
    
    //显卡B使用的子着色器}
	Fallback"VertexLit"
}

SubSharder

给SubSharder起名字
  • 每个Unity Sharder文件的第一行都需要通过Sharder语义来指定该Unity Sharder的名字
  • 这个名字由一个字符串定义,如“MySharder”
  • 当为材质选择使用的Unity Sharder时,这些名称就会出现在材质面板的下拉列表里
  • 通过在字符串中添加“/”,可以控制Unity Sharder在材质面板中的出现的位置。
材质和Unity Sharder的桥梁:Properties

Properties语义块中包含了一系列数学(property),这些属性将会出现在材质面板中的位置

Properties
{
    
    
	Name ("display name",Propertype) = DefaultValue
	Name ("dispaly name",Propertype) = DefaultValue
	//更多属性
}

开发者们能过声明这些属性是为了在材质面板中能够跟方便的调整各种材质属性

 - Int-number-_Int("int",int) = 2
 - Float-number-_Float("Float",Float) = 1.5
 - Range(min,max)-number-_Range("Range",Range(0,0,5,0)) = 3.0
 - Color-(number,number,number,number)-_Color("Color",Color) = (1,1,1,1)
 - Vector-(number,number,number,number)-_Vector("Vector",Vector) = (2,3,6,1)
 - 2D-"defaulttexture"{}-_2D("2D,2D") = ""0
 - Cube-"defaulttexture"{}-_Cude("Cude",Cude) = ""white"{}
 - 3D-"defaulttexture"{}-_3D("3D",3D) = "black"{}

重量级成员:SubShader

每一个Unity Shader文件可以包含多个SubShader语义块,但最少要有一个
当Unity 需要加载这个Unity Shader时,Unity 会扫描所有的SubShder语义块,然后选择第一个能够在目标平台上运行的SubShader
如果都不支持的话,Unity就会shiyongFallback语义指定的Unity Shader
Unity提供这种语义的原因在于,不同的显卡具有不同的能力

SubShader
{
    
    
//可选的[Tags]
//可选的[RenderSetup]
pass{
    
    }
//Other Passes
}
  • SubShader中定义了一系列Pass以及可选的状态([RenderSetup])和标签{[Tags]}设置
  • 每个Pass定义了一次完整的渲染流程,但如果Pass的数目过多,往往会造成渲染性能下降
常见的渲染状态设置选项:
  • Cull-Cull Back | Front | Off-设置剔除模式:剔除/正面/关闭剔除
  • ZTest-ZTest Less Greater | LEqual | GEqual-设置深度测试时使用的函数
  • ZWrite- ZWrite On | Off-开启/关闭深度写入
  • Blend-Blend SrcFactor DstFactor-开启并设置混合模式

SubShade的标签(Tags)是一个键值对(Key/Value Pair),它的键值都是字符串类型

SubShade的标签类型
  • Queue——控制渲染顺序,指定该物体属于哪个渲染队列,通过这种方法可以保证所有的透明物体可以在所有不透明的物体后面被渲染,我们也可以自定义使用个的渲染队列来控制物体的渲染顺序——Tage{“Queue” = “Transparent”}
  • RenderType——对着色器进行分类,例如如果这是一个不透明的着色器,或者是一个透明的着色器,或是一个透明的着色器等。这可以被用于着色器替换(Shader Replacement)功能——Tags{“RenderType”=“Opaque”}
  • DisableBatching——一些SuShader在使用Unity的批处理功能是会出现问题,例如使用了模型空间下的坐标进行顶点动画。这时可以通过该标签来直接指明是否对该SubShader使用批处理——Tags{“DisableBatching”=“True”}
  • ForeNoShadowCasting——控制使用该SubShade的物体是否会映射阴影——Tags{“ForeceNoShadowCasting”=“True”}
  • IgnoreProjector——如果该标签为"True",那么使用该SubShader的物体将不会受Projector的影响。通常用于半透明物体——Tags{“IgnoreProjector”=“True”}
  • CanUseSpriteAtlas——当该SubShader是用于精灵(sprites)时,将该标签设为"False"——Tags{“CanUseSpriteAtlas”=“False”}
  • PreviewType——指明材质面板将如何预览该材质。默认情况下,材质将显示为一个球形,我们可以通过把该标签的值设为"Plane""SkyBox"来改变预览类型——Tags{“PreviewType”=“Plane”}
Pass的标签类型
  • LightMode——定义该Pass在unity的渲染流水线中的角色——Tags{“LightMode”=“ForwardBase”}
  • RequireOptions——用于指定当满足某些条件时才过滤该Pass,它的值是一个由空格分隔的字符串,目前,Unity支持的选项有:SoftVegetation。在后面的版本中,可能会增加更多的选项
特殊的Pass
  • UsePass:如我们之前提到的一样,可以使用该命令来复用其它Unity Shader中Pass
  • GraPass: 该Pass负责抓取屏幕并将结果存储一张纹理中,以用于后续的Pass处理
留最后一条后路:Fallback
  • 紧跟在各个SubShader语义块后面的,可以是一个Fallback指令,它用于告诉Unity,"如果上面所有的SubShader 在这块显卡上都不能运行,那么就使用这个最低级的Shader "
Faallback"name"
//或者
Fallback Of

我们可以通过一个字符串来告诉Unity这个"最低级的Unity Shader "是谁
也可以任性地关闭Fallback功能

  • Fallback还会影响阴影的投射
ShaderLab其它的语义
  • 就可以使用CustomEditor语义来扩展编辑界面
  • 还可以使用Category语义来对Unity Shader中的命令进行分组

猜你喜欢

转载自blog.csdn.net/weixin_50617270/article/details/123394184