我们是如何看到这个世界的

  • 光源: 在光学里,我们使用辐照度 (irradiance) 来量化光
  • 物体的吸收和散射: 光线由光源发射出来后,就会与一些物体相交
  • 着色: 根据材质属性(如漫反射属性等)、光源信息(如光源方向、辐照度等),使用一个等式去计算沿某个观察方向的出射度的过程。我们也把这个等式称为光照模型 (Lighting Model)
  • BRDF光照模型

标准光照模型

  • 环境光: 近似模拟间接光照
  • 自发光: 光线也可以直接由光源发射进入摄像机,而不需要经过任何物体的反射
  • 高光反射: 它可用于计算那些沿着完全镜面反射方向被反射的光线,这可以让物体看起来是有光泽的,例如金属材质。
  • 自发光
  • 漫反射: 漫反射光照是用于对那些被物体表面随机散射到各个方向的辐射度进行建模的. 符合兰伯特定律 (Lambert’s law)

兰伯特定律: 反射光线的强度与表面法线和光源方向之间夹角的余弦值成正比

逐像素还是逐顶点

  • 在片元着色器中计算,也被称为逐像素光照 (per-pixel lighting) ;
  • 在顶点着色器中计算,也被称为逐顶点光照 (per-vertex lighting) 。
  • 这种在面片之间对顶点法线进行插值的技术被称为Phong 着色 (Phong shading) ,与之相对的是逐顶点光照,也被称为高洛德着色 (Gouraud shading)

Unity中的环境光和自发光

在标准光照模型中,环境光和自发光的计算是最简单的。

在Shader中,我们只需要通过Unity的内置变量UNITY_LIGHTMODEL_AMBIENT就可以得到环境光的颜色和强度信息

实现漫反射光照模型

公式:

diff = (c * m) max(0, n, i)

计算漫反射需要知道4个参数:

  • 入射光线的颜色和强度 c
  • 材质的漫反射系数 m
  • 表面法线 n
  • 光源方向 i

为了防止点积结果为负值,我们需要使用max操作,而Cg提供了这样的函数。在本例中,使用Cg的另一个函数可以达到同样的目的,即saturate函数。

  • 函数 :saturate(x )
  • 参数 :x :为用于操作的标量或矢量,可以是float、float2、float3等类型。
  • 描述 :把x 截取在[0, 1]范围内,如果x 是一个矢量,那么会对它的每一个分量进行这样的操作。

实现高光反射光照模型

计算高光反射需要知道4个参数:

  • 入射光线的颜色和强度 c
  • 材质的高光反射系数 m
  • 视角方向 v
  • 反射方向 r: 可以由表面法线n 和光源方向l 计算而得 r = 2(n*i)n - l

公式:

spucular = (c . m) max(0, v, r)

Cg提供了计算反射方向的函数reflect

  • 函数 :reflect(i, n)
  • 参数 :i,入射方向;n,法线方向。可以是float、float2、float3等类型。
  • 描述 :当给定入射方向i和法线方向n时,reflect函数可以返回反射方向。图6.9给出了参数和返回值之间的关系。

使用Unity内置的函数

UnityCG.cginc中一些常用的帮助函数

函 数 名描 述
float3 WorldSpaceViewDir (float4 v)输入一个模型空间中的顶点位置,返回世界空间中从该点到摄像机的观察方向。内部实现使用了UnityWorldSpaceViewDir函数
float3 UnityWorldSpaceViewDir (float4 v)输入一个世界空间中的顶点位置,返回世界空间中从该点到摄像机的观察方向
float3 ObjSpaceViewDir (float4 v)输入一个模型空间中的顶点位置,返回模型空间中从该点到摄像机的观察方向
float3 WorldSpaceLightDir (float4 v)仅可用于前向渲染中 。输入一个模型空间中的顶点位置,返回世界空间中从该点到光源的光照方向。内部实现使用了UnityWorldSpaceLightDir函数。没有被归一化
float3 UnityWorldSpaceLightDir (float4 v)仅可用于前向渲染中 。输入一个世界空间中的顶点位置,返回世界空间中从该点到光源的光照方向。没有被归一化
float3 ObjSpaceLightDir (float4 v)仅可用于前向渲染中 。输入一个模型空间中的顶点位置,返回模型空间中从该点到光源的光照方向。没有被归一化
float3 UnityObjectToWorldNormal (float3 norm)把法线方向从模型空间转换到世界空间中
float3 UnityObjectToWorldDir (float3 dir)把方向矢量从模型空间变换到世界空间中

扩展

漫反射: https://blog.csdn.net/puppet_master?type=blog 高光反射: https://blog.csdn.net/puppet_master/article/details/53428885?spm=1001.2014.3001.5502

思维导图

--完--