笔记当前的Unity版本:2019.3
当前最新的Unity版本:2020.2
1.概述
又回到了这个经久不衰的话题,即光照,其实准确点来说,光照是每个游戏渲染技术的核心。而我们近几年的升级,大部分也都是为了光照。从基础的Lambert和Blinn-Phong光照模型到复杂的光追算法,毕竟,所谓“看起来真实”这件事,来源于光照,而非色彩。
在本章节中,我们会先简单回顾一下兰伯特漫反射光照模型,然后利用HLSL来翻译Built-In管线中的代码。
2.兰伯特光照模型
从一般性的角度来说,构建着色器大体分为两个部分,第一是原理,第二是具体的实现方式。实现方式是多种多样的,你可以用OpenGL+GLSL实现,也可以用DirectX+HLSL实现。但是无论怎样,原理都是一样的,这也是为什么算法才是核心。可以深挖的,而语法至多做到熟练就可以了。
2.1 兰伯特定律
兰伯特定律是一种描述CG当中的经验性漫反射定律,它是这样说的。
漫反射光的强度近似地服从于Lambert定律,即漫反射光的光强仅与入射光的方向和反射点处表面法向夹角的余弦成正比。
这段话中可以拆分为几个点来看。
第一,近似的服从,也就是并不完全服从,主要说明它是一个经验模型。而非基于物理的渲染(PBR)
第二,入射光的方向,即我们需要入射光的角度,(当然还需要强度)
第三,反射点出的表面法线,我们需要顶点的法线
第四,与余弦成正比,我们需要计算入射光与顶点法线的余弦值,以计算光在该点的强度。
2.2 兰伯特定律的公式
根据上面四个点,我们来简单梳理一下这个公式。首先,入射光的方向与反射点处的表面法线夹角的余弦成正比。我们就需要计算两个方向的余弦值,且不说这两个方向是什么,我们先看一下怎么计算两个方向的余弦值。
假设我们有A和B两个向量,我们可以得到以下关系。其中θ为A和B的夹角。
这样,我们计算出了A向量和B向量的夹角值。
又由于,在夹角超过90°的地方,余弦值会变成负数,而这显然不符合光强度大于等于0的现实问题,所以我们给它加上一个限度。因而漫反射可以表示为下面这样。
其中L为光照方向,而N为法线方向,I为光照强度。虽然这个公式已经十分简单了,但是我仍然推荐新手或者刚入门的人多理一下。
3.用HLSL来实现兰伯特定律
我们之前使用CG实现过,现在无非是更换了不同的API,对于老手来说,这可能是查个API的事情,但是对于新手来说可能就是自废武功了。所以我们慢慢的来过,不要急躁。
既然更换了API,那么库肯定也更换了,所以我们主要了解几个核心的HLSL库。
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/SpaceTransforms.hlsl"
这个任务主要了解三个库,Core.HLSL,Lighting.HLSL以及SpaceTransforms.hlsl。其中Core.HLSL是其他库的集合,相当于在Core当中引用了别的HLSL,不过并不是所有的都引用了