Unity Shader 入门(一) SurfaceShade
xzhuan原创稿件,转载请注明出处!
//-------------------------------【Unity右键路径】-----------------------------------------
Shader "Custom/MySurfaceShader"
{
//-------------------------------【Shader属性】-----------------------------------------
Properties
{
// Color :颜色 Inspector面板里会有一个选取颜色的picker
// Range :某范围内的浮点数 Inspector面板里会出现一个Slider
// 2D : 2D纹理
// Rect : 创建非2次方边长的纹理
// Cube : 创建Cube Map,也是一种纹理
// Float :浮点数,和Range的区别就是Range是一个范围内的数,Float是单个数
// Vector:向量 定义一个四元素的容器
_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
{
//----------------------------【标签】---------------------------
//Queque 渲染顺序 BackGround/Geometry
//RenderType 渲染类型 Opaque不透明/Transparent透明
Tags { "RenderType"="Opaque" }
//Level of Detail
LOD 200
//CG程序 开始
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
//说明是surface shader,可以换成Vertex或Fragment,surf是表面处理函数,在代码段的下面就有一个surf函数。Standard fullforwardshadows是光照模型函数。
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
//设置编译目标Shader model的版本
#pragma target 3.0
//在surf函数的上面,将properties里的变量用相同的名称定义一遍。还有一个Input结构体,这是输入结构
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)
{
// Albedo comes from a texture tinted by color
//先定义了一个4元的定点数c,tex2D是纹理采样函数,第一个参数是纹理,第二个参数是uv坐标,函数的返回值乘以颜色
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
//o这个变量就是着色器会输出的变量,也就是存储着我们眼睛会看到的效果的变量
//后面的语句的意思就是将各个值赋给o里的不同值。rgb就是RGB颜色,Albedo是反射值,Metalic是金属值,Smoothness是光滑值,Alpha是透明通道
o.Albedo = c.rgb;
// Metallic and smoothness come from slider variables
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = c.a;
}
//CG程序 结束
ENDCG
}
//备胎: 表示前面的着色程序显卡不支持的时候就用默认的“Diffuse”
FallBack "Diffuse"
}
CG数据结构 类型
CG支持7种数据类型:
float 32位浮点数
half 16位浮点数
int 32位整型数
fixed 12位定点数
bool 布尔数据
sampler 纹理对象的句柄,公有sampler, sampler1D, sampler2D, sampler3D, samplerCUBE, 和 samplerRECT 六种
string 字符,其实没有必要在CG中用到字符
向量类型 float2就是2元的float类型的向量,fixed4就是4元的fixed类型的向量
向量最长不超过4元
此外,CG还支持矩阵数据类型,比如:
float2×4 matrix; // 表示2×4阶矩阵,包含8个float类型数据
surface shader的输入输出结构:
输入结构就是存储输入的信息,输出结构就是存储要输出的信息,也就是我们的眼睛会看见的效果。
struct Input
{
float2 uv_MainTex;
}
纹理坐标必须命名为“uv”+"纹理名称",uv_MainTex就是名为_MainTex的纹理的uv坐标。
surface shader的默认的几种输出结构如下,输出结构也是可以自定义的。
struct SurfaceOutput
{
fixed3 Albedo; // 漫反射颜色
fixed3 Normal; // 切线空间法线,如果赋值的话
fixed3 Emission; // 自发光颜色
half Specular; // 高光强度,范围是0-1
fixed Gloss; // specular intensity
fixed Alpha; // 透明度
};
struct SurfaceOutputStandard
{
fixed3 Albedo; // 基础 (漫反射或镜面反射) 颜色
fixed3 Normal; // 切线空间法线,如果赋值的话
half3 Emission; // 自发光颜色
half Metallic; // 0=非金属, 1=金属
half Smoothness; // 0=粗糙, 1=光滑
half Occlusion; // 遮挡(默认1)
fixed Alpha; // 透明度
};
struct SurfaceOutputStandardSpecular
{
fixed3 Albedo; // 漫反射颜色
fixed3 Specular; // 镜面反射颜色
fixed3 Normal; // 切线空间法线,如果赋值的话
half3 Emission; // 自发光颜色
half Smoothness; // 0=粗糙, 1=光滑
half Occlusion; // 遮挡(默认1)
fixed Alpha; // 透明度
};
那么定义变量的时候怎么知道该用哪种类型呢?
- 精度够用就好
- 颜色和单位向量,使用fixed
- 其他情况,尽量使用half(即范围在[-6万, +6万]内、精确到小数点后3.3位);否则才使用float。