前置:UnityShader2:Shader与材质
在前置中已经了解了什么是表面着色器,下面这是 Standard Surface Shader,也是创建 Shader 时的默认代码之一
Shader "Custom/NewSurfaceShader"
{
Properties
{
_Color("Color", Color) = (1,1,1,1)
_MainTex("Albedo (RGB)", 2D) = "white" {}
_Glossiness("Smoothness", Range(0,1)) = 0.5
_Metallic("Metallic", Range(0,1)) = 0.0
}
SubShader
{
Tags { "RenderType" = "Opaque" }
LOD 200
CGPROGRAM
#pragma surface surf Standard fullforwardshadows
#pragma target 3.0
sampler2D _MainTex;
struct Input
{
float2 uv_MainTex;
};
half _Glossiness;
half _Metallic;
fixed4 _Color;
UNITY_INSTANCING_BUFFER_START(Props)
UNITY_INSTANCING_BUFFER_END(Props)
void surf (Input IN, inout SurfaceOutputStandard o)
{
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb;
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
直接一行一行注释(对于紫色的内容,可以暂时不用去详细了解):
void surf (Input IN, inout SurfaceOutputStandard o) {}:第一个参数 Input IN 就是前面定义的 Input 结构体,第二个参数用了 inout 声明,这表示这个参数既是输入的也是输出的,这个 surf 函数虽然没有返回值,但是它的第二个参数是有输出功能
从上述程序中可以看出:表面着色器被定义在 SubShader 语义块中的 CGPROGRAM 和 ENDCG 之间,并且没有 Pass 语义块,这是因为表面着色器不需要开发者关心使用了多少个 Pass、每个 Pass 如何渲染等问题,Unity 会在背后为我们做好这些事情,我们要做的只是告诉它使用哪些纹理去填充颜色,如何填充法线,使用哪种光照模型等
上面的代码对应的预览效果(无纹理):
固定渲染管线已经过时了,没有必要去学习/关心,但也可以在这一章顺便提一下
一个非常简单的固定函数着色器例子如下:
Shader "Tutorial/Basic" {
Properties {
_Color("Main Color", Color) = (1,0.5,0.5,1)
}
SubShader {
Pass {
Material {
Diffuse [_Color]
}
Lighting On
}
}
}
关于固定函数着色器可以了解的是:
UnityShader形式有三种,前面主要提到了表面着色器和固定函数着色器,然而事实上,最常用的还是顶点/片元着色器,可以自己实现一些五花八门的渲染效果,只不过关于顶点片元着色器,需要了解的东西不少,这篇就暂时不讲了
传统的 Shader 和 UnityShader 的区别有:
关于 CG/HLSL 和 GLSL:
对于上面的表面着色器,是通过在 ShaderLab 内部嵌套 CG/HLSL 语言来编写这些着色器代码的,由于 CG 和 DX9 风格的 HLSL 从写法上来说几乎是同一种语言,因此在 Unity 里 CG 和 HLSL 等价
当然也可以用 GLSL 来写,不过这样对于PC、Xbox 360这些的仅支持DirectX的平台来说,就不能正常的运行了
本文[系列]参考于:UnityShader入门摘要
其它参考资料:https://docs.unity3d.com/Manual/SL-Reference.html
https://docs.unity3d.com/Manual/ShaderTut1.html