(二)unity自带的着色器源码剖析之——————UnityCG.cginc文件(上篇:数学常数、颜色空间常数和函数、顶点布局格式结构体、进行空间变换的函数、HDR级光照贴图编解码相关函数等)

一、数学常数

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
  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值