一、数学常数
unity3D内置着色器定义了一系列的数学常数,如下:
从第3行开始,第13行结束:
#ifndef UNITY_CG_INCLUDED
#define UNITY_CG_INCLUDED
#define UNITY_PI 3.14159265359f //圆周率
#define UNITY_TWO_PI 6.28318530718f //2倍圆周率
#define UNITY_FOUR_PI 12.56637061436f //4倍圆周率
#define UNITY_INV_PI 0.31830988618f //圆周率的倒数
#define UNITY_INV_TWO_PI 0.15915494309f //2倍圆周率的倒数
#define UNITY_INV_FOUR_PI 0.07957747155f //4倍圆周率的倒数
#define UNITY_HALF_PI 1.57079632679f //半圆周率
#define UNITY_INV_HALF_PI 0.636619772367f //半圆周率的倒数
二、与颜色空间相关的常数和工具函数
2.1 IsGammaSpace函数的定义如下:
//用来判断当前是否启用了伽马颜色空间函数
inline bool IsGammaSpace()
{
#ifdef UNITY_COLORSPACE_GAMMA
return true;
#else
return false;
#endif
}
上述代码段中的IsGammaSpace函数根据宏UNITY_COLORSPACE_GAMMA是否被启用了,判断当前是否启用了伽马颜色空间。
2.2 GammaToLinearSpaceExact函数
从88行开始,96行结束:
inline float GammaToLinearSpaceExact (float value)
{
if (value <= 0.04045F)
return value / 12.92F;
else if (value < 1.0F)
return pow((value + 0.055F)/1.055F, 2.4F);
else
return pow(value, 2.2F);
}
上述代码段中的GammaToLinearSpaceExact函数把一个颜色值精确地从伽马颜色空间(sRGB颜色空间)变化到线性空间(CIE-XYZ颜色空间)。
2.3 GameToLinearSpace函数
从98行开始,105行结束:
inline half3 GammaToLinearSpace (half3 sRGB)
{
//GammaToLinearSpaceExact函数的近似模拟版本
return sRGB * (sRGB * (sRGB * 0.305306011h + 0.682171111h) + 0.012522878h);
// Precise version, useful for debugging.
//return half3(GammaToLinearSpaceExact(sRGB.r), GammaToLinearSpaceExact(sRGB.g), GammaToLinearSpaceExact(sRGB.b));
}
上述代码段中的GameToLinearSpace函数是用一个近似模拟的函数把颜色值近似地从伽马空间变换到线性空间。
2.4 LinearToGammaSpaceExact函数
从107行开始,117行结束:
inline float LinearToGammaSpaceExact (float value)
{
if (value <= 0.0F)
return 0.0F;
else if (value <= 0.0031308F)
return 12.92F * value;
else if (value < 1.0F)
return 1.055F * pow(value, 0.4166667F) - 0.055F;
else
return pow(value, 0.45454545F);
}
上述函数把一个颜色值精确地从线性空间变换到伽马颜色空间。
2.5 LinearToGammaSpace函数
从119行开始,第127行结束:
inline half3 LinearToGammaSpace (half3 linRGB)
{
linRGB = max(linRGB, half3(0.h, 0.h, 0.h));
// An almost-perfect approximation from http://chilliant.blogspot.com.au/2012/08/srgb-approximations-for-hlsl.html?m=1
return max(1.055h * pow(linRGB, 0.416666667h) - 0.055h, 0.h);
// Exact version, useful for debugging.
//return half3(LinearToGammaSpaceExact(linRGB.r), LinearToGammaSpaceExact(linRGB.g), LinearToGammaSpaceExact(linRGB.b));
}
这个函数用一个近似模拟的函数把颜色值近似地从线性空间变换到伽马颜色空间。
三、描述顶点布局格式的结构体
因为在不同场合中渲染引擎需要顶点携带的信息是不同的,如果只用一个把所有顶点信息都添加在内的结构体去描述顶点,在很多场合会造成数据的冗余。因此unity预定了若干用于描述顶点结构布局的结构体版本,方便在不同场合下使用。
3.1 顶点结构体 appdata_base
从51行开始,56行结束:
struct appdata_base {
float4 vertex : POSITION; //世界坐标下的顶点坐标
float3 normal : NORMAL; //顶点法线
float4 texcoord : TEXCOORD0; //顶点使用的第一层纹理坐标
UNITY_VERTEX_INPUT_INSTANCE_ID //顶点多例化的ID
};
UNITY_VERTEX_INPUT_INSTANCE_ID是定义顶点多例化ID用的一个宏,后面会讲到。
3.2 顶点结构体 appdata_tan
从第58行开始,64行结束:
struct appdata_tan {
float4 vertex : POSITION; //世界坐标下的顶点坐标
float4 tangent : TANGENT;;//顶点切线
float3 normal : NORMAL;//顶点法线
float4 texcoord : TEXCOORD0; //顶点使用的第一层纹理坐标
UNITY_VERTEX_INPUT_INSTANCE_ID //顶点多例化的ID
};
相对于appdata_base结构体,多了一个顶点的切线信息,在使用法线贴图技术时需要利用顶点的切线。
3.2 顶点结构体 appdata_full
从第66行开始,76行结束:
struct appdata_full {
float4 vertex : POSITION;//世界坐标下的顶点坐标
float4 tangent : TANGENT;//顶点切线
float3 normal : NORMAL;//顶点法线
float4 texcoord : TEXCOORD0;//顶点使用的第一层纹理坐标
float4 texcoord1 : TEXCOORD1;//顶点使用的第二层纹理坐标
float4 texcoord2 : TEXCOORD2;//顶点使用的第三层纹理坐标
float4 texcoord3 : TEXCOORD3;//顶点使用的第四层纹理坐标
fixed4 color : COLOR;//顶点颜色
UNITY_VERTEX_INPUT_INSTANCE_ID//顶点多例化的ID
};
上述代码段中appdata_full定义了最全的顶点信息结构体,该结构体有四层纹理坐标和顶点颜色。在做地形渲染时,通常会用到非常多的纹理以产生复杂多变的地面效果。
四、用于进行空间变换的工具函数
实际开发中经常会遇到把某一个位置坐标或者方向向量从一个空间坐标系下变换到另一个空间坐标系的要求。
4.1 UnityWorldToClipPos函数
// Tranforms position from world to homogenous space
inline float4 UnityWorldToClipPos( in float3 pos )
{
return mul(UNITY_MATRIX_VP, float4(pos, 1.0));
}
宏UNITY_MATRIX_VP是当前观察矩阵与投影矩阵的乘积,该函数作用就是把世界坐标空间中某一点pos变换到齐次裁剪空间中去。
4.2 UnityViewToClipPos函数
// Tranforms position from view to homogenous space
inline float4 UnityViewToClipPos( in float3 pos )
{
return mul(UNITY_MATRIX_P, float4(pos, 1.0));
}
宏是当前的投影矩阵,该函数的作用就是把观察坐标空间中某一点pos变换到齐次裁剪空间中去。
4.3 参数类型为float3的UnityObjectToViewPos函数
// Tranforms position from object to camera space
inline float3 UnityOb