Unity中Shader的形态
Unity通过Shaderlab组织Shader,用于呈现渲染物体的内容实在SubShader中实现的。使用SubShader,能让开发者针对不同性能的显卡编写不同的Shader。理论上,SubShader的数量没有限制,实际操作中减少文件大小,针对不免最流行的显卡和老旧的显卡写两到三个即可。
SubShader重要标签(Tags{}块)
SubShader{
Tags{"Queue"="Geometry""RenderType"="Opaque""IgnoreProjector"="True"}
}
Queue:渲染队列,表示希望Unity渲染引擎在什么时候渲染自己。有5个可选值:Background、Geometry、AlphaTest、Transparent、Overlay,分别对应数字1000、2000、2450、3000、4000。可以把这些值当成整型变量,For Example:
Tags{"Queue"="Geometry+1000"}
混合使用自定义Shader和Unity内置Shader,要遵守字母对应关系。
RenderType:在替代渲染做Post Effects时很重要,Unity内置的Image Effects要根据他来决定如何替代渲染。内置值有:Opaque、Transparent、TransparentCutout、Background、Overlay。
IgnoreProjector:true表示当前物体忽略Projector的影响。
自定义标签:
Tags{"MyTag"="Lucifer"}
SubShader Pass块
SubShader包装了一个渲染方案,该方案是由一个个Pass块来执行。可以包括多个Pass块,每一个Pass块都包含了渲染一个几何体的具体代码。
Pass块的标签
内置的标签都是针对渲染路径,告诉引擎这个Pass在什么渲染路径下被渲染。
Name:一般用来引用此Pass,可以定义一个Pass块,然后在其他Shader的Pass块中多次引用,就像在函数中调用别的类的静态函数一样。For Example:
Shader "Tue/NewBie/TestShader"{
SubShader{
Pass{
Name "MZ"
Material{
Diffuse(1,0.7,0.4,1)
Ambient(1,0.7,0.4,1)
}
Lighting On
SetTexture[_]{ combine primary}
}
}
}
Shader "Tue/Newbie/TestShader_1"{
SubShader{
UsePass "Tue/Newbie/TestShader/MZ"
}
}
使用FallBack可以保证Shader的广泛适用性,当用户所有的SubShader都失败,为了呈现设定的机制,使用FallBack。FallBack是Unity自己预制的Shader实现,一般可以在所有的显卡上运行。开发时一般不使用,实际发布时为了追求平台的最大适用性而加上。
Unity中Shader的三种形态:固定管线、可编程Shader、Surface Shader。
Shader的数据接口:属性和uniform变量
在Properties块中定义属性:
Properties{
_MyTexture ("Texture (RGB)",2D)="white" {} //图片形式的属性
_MyColor("Color of Object",Color)=(1,1,1,1)//颜色属性
_MyCube("Environment map",Cube)="white" {}//3D贴图,需要6张图片
_MyVector("Vector",vector)=(1,1,1,1)//4个元素的向量
_MyFloat("Float Value",float)=1.0//浮点小数
_MyRange("Another type of float",range(-10,10))=1.0//限定范围的浮点数
}
不仅可以在Inspector面板设置属性,还可以通过C#脚本对属性进行控制
using UnityEngine;
public class Men : MonoBehaviour
{
public Material mat;
public Texture myTexture;
public Color myColor;
public Cubemap myCubemap;
public Vector4 myVector4;
public float value_1;
public float value_2;
private void Start()
{
//对shader中定义属性设置
mat.SetTexture("_MyTexture", myTexture);
mat.SetColor("_MyColor", myColor);
mat.SetTexture("_MyCube", myCubemap);
mat.SetVector("_MyVector", myVector4);
mat.SetFloat("_MyFloat", value_1);
mat.SetFloat("_MyRange", value_2);
//对shader中定义的属性读取
myTexture = mat.GetTexture("_MyTexture");
myCubemap = (Cubemap)mat.GetTexture("_MyCube");
}
}
矩阵目前不能在属性块定义,必须先在Shader中声明,然后通过脚本进行读取和写入:
uniformfloat4x4 myMatrix;//shader中声明
//c#脚本中进行读写
mat.SetMatrix("myMatrix", matrix);
matrix = mat.GetMatrix("myMatrix");