《Unity Shader入门精要》Unity Shader基础(二)

一、ShaderLab

Shader Lab是Unity提供的编写 Unity Shader 的一种说明性语言。

从设计上来说,Shader Lab类似与CgFX和Direct3D Effects(.FX)语言,他们都定义了要显示一个材质所需的所有东西,而不仅仅是着色器代码。

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

  二、Unity Shader的结构

(1)Properties

Properties{
     Name ("DisplayName",PropertiesType)=DefaultValue
     Name ("DisplayName",PropertiesType)=DefaultValue
     //更多属性
}
Properties语义块支持的属性类型
属性类型默认值的定义语法例子
Intnumber_Int("Int",Int)=2
Floatnumber

_Float("Float",Float)=1.5

Range(min,max)number_Range("Range",Range(0.0,5.0))=3.0
Color(num,num,num,num)_Color("Color",Color)=(1,1,1,1)
Vector(num,num,num,num)_Vector("Vector",Vector)=(2,3,4,5)
2D"defaulttexture"{}_2D("2D",2D)=""{}
Cube"defaulttexture"{}_Cube("Cube",Cube)="white"{}
3D"defaulttexture"{}_3D("3D",3D)="back"{}

 

 

 

 

 

 

 

 

 

 

属性类型的例子:

Shader"Custom/ShaderLabProperties"{
   Properties{
       //Number and Sliders
      _Int("Int",Int)=2
      _Float("Float",Float)=1.0
      _Range("Range",Rnage(1.0,2.0))=1.5
      //Colors and Vectors
      _Color("Color",Color)=(1,1,1,1)
      _Vector("Vector",Vector)=(1,2,3,4)
      //Texctures
      _2D("2D",2D)=""{}
      _Cube("Cube",Cube)="white"{}
      _3D("3D",3D)="black"{}
   }
   FallBack "Diffuse"
}

(2)SubShader

SubShader{
  //可选的
  [Tags]

  //可选的
  [RenderSetup]

  Pass{
   
  }
  //Other Passes
}

每一个Pass定义了一次完整的渲染流程,但如果Pass的数目过多,往往会造成渲染性能的下降。

SubShader 和 Pass 中的标签设置不一样,但状态设置的语法是相同的。

SubShader 进行的设置会应用到所有的Pass。

  • 状态设置

常见的渲染状态设置选项
状态名称设置指令解释
CullCull Back|Front|Off设置剔除模式:剔除背面/正面/关闭剔除
ZTestZTest Less Greater|LEqual|GEqual|Equal|NotEqual|Always设置深度测试时使用的函数
ZWriteZWrite On|Off 开启/关闭深度写入
BlendBlend Off|SrcFactor DstFactor关闭/开启设置混合模式

 

 

 

 

 

 

  • SubShader的标签

SubShader 的标签(Tags)是一个键值对(Key/Value Pair),它的键和值都是字符串类型。这些键值对是SubShader和渲染引擎之间的沟通桥梁。

Tags{ "TagName 1" = "Value1" "TagName 2" = "Value2" }
SubShader的标签类型
标签类型说明例子
Queue

控制渲染顺序,指定该物体属于哪一个渲染队列。

这种方式可以保证所有的透明物体可以在不透明物体后渲染。

也可自定义渲染顺序。

Tags{ "Queue" = "Transparent"}
RenderType

对着色器进行分类。

例如这是一个不透明着色器 或 是一个透明着色器等。

可被用于着色器替换(ShaderReplacement)功能

Tags{ "RenderType" = "Opaque"}
DisableBatching

一些SubShader在使用批处理时会出现问题。

例如:使用模型空间下的坐标进行顶点动画。

这时可以通过该标签直接指明是否对该SubShader使用批处理。

Tags{ "DisableBatching" = "True"}
ForceNoShadowCasting控制使用该SubShader的物体是否会投射阴影Tags{ "ForceNoShadowCasting" = "True"}
IgnoreProjector

如果该标签为“True”,

那么使用该SubShader的物体不会受Projector的影响。

通常用于透明物体

Tags{"IgnoreProjector" = "True"}
CanUseSpriteAtlas当该SubShader是用于精灵(sprites)时,将该标签设为“False”Tags{ "CanUseSpriteAtlas" = "False"}
PreviewType

指明材质面板将如何预览该材质。

默认为球形,可设为“Plane” “SkyBox”

Tags{ "PreviewType" = "Plane"}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • Pass语义块

Pass{
   [Name]
   [Tags]
   [RenderSetup]
//Other code
}

可以在Pass中定义该Pass的名称,如:

Name "MyPassName"

通过这个名称,可以使用Shader Lab的Use Pass命令来直接使用其他Unity Shader中的Pass。

UsePass "MyShader/MYPASSNAME"
   
   //Unity内部会把所有Pass的名称转换成大写字母
   //使用UsePass命令时,Pass名字必须大写

Pass中还可以使用固定管线的着色器命令。

Pass的标签也是用于告诉渲染引擎怎么来渲染该物体。

Pass的标签类型
标签类型说明例子
LightMode定义该Pass在Unity的渲染流水线中的角色Tags{ "LightMode" = "ForwardBase"}
RequireOptions

用于指定当满足某些条件时渲染该Pass,它的值是一个由空格分隔的字符串。

目前支持的选项有:SoftVegectation

Tags{ "RequireOptions" = "SoftVegetation"}

 

 

 

 

 

UnityShader还支持一些特殊的Pass,以便进行代码复用 或 实现更复杂的效果。

Use Pass:复用其他Unity Shader中的Pass

Grab Pass:该Pass负责抓取屏幕并将结果存储在一张纹理中,以用于后续的Pass处理。

(3)FallBack

Fallback "name"
//或者
Fallback Off

Fallback还会影响阴影的投射。

Fallback使用的内置Shader中包含了一个通用的阴影投射的Pass。

正确设置Fallback也非常重要。

三、UnityShader的形式

着色器代码写在SubShader语义块中是表面着色器的做法,写在Pass语义块中,是顶点/片元着色器固定函数着色器的做法。

Shader "MyShader" {
   Properties{
     //所需的各种属性
   }
   SubShader{
     //真正意义上的Shader代码会出现在这里
     //表面着色(Surface Shader)或者
     //顶点/片元着色器(Vertex/Fragment Shader)或者
     //固定函数着色器(Fixed Function Shader)
   }
   SubShader{
     //和上一个SubShader类似
   }
}

(1)表面着色器(Surface Shader)

表面着色器是Unity自己创造的一种着色器代码类型。

代码量很少,但渲染代价很大。

在背后仍旧把它转换成对应的顶点/片元着色器。

它存在的价值在于,为我们处理了很多光照细节。

Shader "Custom/Simple Surface Shader"{
  SubShader{
     Tags{ "RenderType" = "Opaque"}
     CGPROGRAM
     #pragma surface surf Lambert
     struct Input{
         float4 color:COLOP;
     };
     void surf (Input IN, inout SurfaceOutput o ){
         o.Albedo = 1;
     }
     ENDCG
  }
  Fallback "Diffuse"
}

CGPROGRAM 和 ENDCG 之间的代码是使用 CG/HLSL 编写的

(2)顶点/片元着色器(Vertex/Fragment Shader)

灵活性高,可控制渲染细节。

Shader "Custom/Simple VertecFragment Shader"{
   SubShader{
       Pass{
         CGPROGRAM
         
         #pragma vertex vert
         #peagma fragment farag

         float4 vert(float4 v : POSITION) : SV_POSITION{
            return mul (UNITY_MATRIX_MVP, v );
         }
      
         float4 frag() : SV_Target {
            return fixed4(1.0,0..0,0.0,1.0);
         }

         ENDCG
       }
   }
}

(3)固定函数着色器(Fixed Function Shader)

不支持可编程管线着色器,就需要使用固定函数着色器来完成渲染。

Shader "Tutorial/Basic" {
   Properties {
      _Color ("Main Color",Color) = (1,0.5,0.5,1)
   }
   SubShader {
      Pass {
        Material {
           Diffuse [_Color]
        }
        Lighting On
      }
   }
}

(4)选择哪种UnityShader形式

  • 和各种光源打交道,选表面着色器。

  • 光源数目比较少,有很多自定义渲染效果的,选顶点/片元着色器。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值