一、Unity Shader最重要的任务是指定着色器所需的代码
一般来说、着色器的代码写在SubShader语句块中或者在Pass语句块中
不管用什么着色器、真正意义上的shader代码都需要包含在shaderlab中
Shader "MyShader"
{
Properties{}
SubShader
{
//真正意义的shader代码
//XX着色器
}
SubShader{}
}
二、表面着色器
表面着色器是Unity自己创造的着色器,它的本质是转换成对应的顶点/片元着色器。它存在的目的是unity让我们能够更简单地使用,但渲染的代价比较大
一个简单的表面着色器结构:
Shader "Custom/001SurfaceShader"
{
Properties
{
//需要的属性
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
sampler2D _MainTex;
struct Input
{
float2 uv_MainTex;
};
half _Glossiness;
half _Metallic;
fixed4 _Color;
// Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
// See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
// #pragma instancing_options assumeuniformscaling
UNITY_INSTANCING_BUFFER_START(Props)
// put more per-instance properties here
UNITY_INSTANCING_BUFFER_END(Props)
void surf (Input IN, inout SurfaceOutputStandard o)
{
o.Albedo = 1;
}
ENDCG
}
FallBack "Diffuse"
从这可以看出,表面着色器是没有Pass语句的,原因是unity已经帮我们弄好了。
三、顶点/片元着色器
顶点/片元着色器的代码与表面着色器不同,是写在Pass语句块中的,虽然要编写更多的代码,但好处是灵活性更高了
四、固定函数着色器
常用于较旧的设备,用于实现简单的效果
五、UnityShader 与 Shader的区别
Unity Shader实际上指的就是一个ShaderLab文件。以.shader作为后缀的一种文件。在Unity shader里面,我们可以做的事情远多于一个传统意义上的Shader。
- ①在传统的shader中,我们仅可以编写特定类型的Shader,例如顶点着色器,片元着色器等。在Unity Shader中,我们可以在同一个文件里面同时包含需要的顶点着色器和片元着色器代码。
- ②在传统shader中,我们无法设置一些渲染设置,例如是否开启混合,深度测试等,这些是开发者在另外的代码中自行设置的。而Unity shader中,我们通过一行特定的指令就可以完成这些设置。
- ③在传统shader中,我们需要编写冗长的代码设置着色器的输入和输出,要小心的处理这些输入输出的位置对应关系等。而在Unity shader中,我们只需要在特定语句块中声明一些属性,就可以依靠材质来方便的改变这些属性。而对于模型自带的数据(如顶点,纹理坐标,法线等),Unity Shader也提供了直接访问的方法,不需要开发者自行编码来传给着色器。