reference:
主要参考part1
主要参考part2
知乎透射
b站教学视频
BTDF
- 就是进入物体的光,从物体另一面出射
- 影响其的有物质的散射系数,折射率(散射系数和折射率应当指的是同一物理参数),反射率(有多少光入射)
和半透明:
- 注意这和半透明并不一样,这是基于物理的模型,半透明是理想状态
- 半透明是BTDF的特殊情况,也就是散射系数极低至0,并且材质不发生折射
BTDF/透射/背光
- 便于理解,可以认为sss材质是一种更加高级的半透明材质,带着这样的前提去理解公式的目的;
- BTDF是构成SSS材质主要的效果之一,其仅刻画材质在背光面的效果;
- 看起来就像光穿过半透明物体,并且照亮了物体内部
其构成包含这些元素:
SSS = 背光 + 扰动 + 扩散 + ···
背光
Unity中光线强度标准值是1,所以 光线方向L 都省略了光线强度,在下面的公式中要注意这一点
- 正面光:就是普通的漫反射光,漫反射强度 = 光强 × \times × cos(光线 法线夹角)
即: D = L ⋅ N D= L·N D=L⋅N
- 背光:模拟透过物体进入人眼的光线,想象一下拿着一块玉石在透过太阳看,越正对太阳越亮,眼睛偏的话就没那么透对吧?公式的点积就是在计算这个效果;
背光强度 = 光线反方向 · 透光点(即当前渲染点)到人眼的向量
B
=
−
L
⋅
V
B = -L \cdot V
B=−L⋅V (L和N均为标准化向量)
在获得这个背光强度后,再与物体表面的漫反射系数相乘就可以获得背光颜色
扰动
- 如果仔细观察生活,就能观察到物体的轮廓凹凸会对透光产生影响,这便是扰动要做的事情
进一步完善上述公式:注意到这个公式并没有考虑到任何法线信息,(只考虑了光线方向和摄像机方向)在扰动这一步,我们添加表面(背面)法线对于光线出射方向的影响:
背光强度 = - (光线+扰动强度x法线) · 透光点到人眼的向量
B
=
−
(
L
+
δ
N
)
⋅
V
=
−
H
⋅
V
B= -(L+ \delta N)\cdot V = -H\cdot V
B=−(L+δN)⋅V=−H⋅V (
δ
\delta
δ为扰动强度)
- 其中
δ
\delta
δ为扰动强度,这是控制整体的扰动强度
取值为 [0,1],即H的取值范围为为 [L,L+N]
即: δ \delta δ为0时没有扰动,为1时扰动强度最大(大于1也不是不行啊)
扰动后的向量记为 H,为了节省算力,H一般不单位化
- (refer中说这是因为且进不进行单位化对最终结果影响不大,可以理解,因为扰动的偏差确实看不出来,但是我觉得,想要真实的效果就是需要注重这些细节,不能省这个标准化,当然为了速率可以省)
扩散
最后一步进行扩散,先亮公式
B = s a t u r a t e [ − ( L + δ N ) ⋅ V ] p × s B=saturate[ -(L+ \delta N)\cdot V]^p\times s B=saturate[−(L+δN)⋅V]p×s
- saturate函数:对括号内的数值进行截断,保留0-1的部分
- p:power高光集中度,越大越集中,随着p增大,图像由大面积色块转化为高光描边
- s:scale最终的整体亮度,s>1;由于指数运算会降低大部分亮度,乘以s用来平衡 (其大于1会导致最大亮度突破1,可以运用bloom,HDR等)
实际上就是进行一点微调,由线性变化转为非线性,就像gloss
厚度贴图
以上这一系列步骤完成后,能得到一个不错的光照分布结果,但这只是光照的分布,透射效果肯定需跟厚度相关
- 要实现厚度很简单,从厚度贴图中读取厚度信息(这是一个0-1的数,用来表示透光率,越大越透),在光照结果上乘以透光率即可达到最终效果
厚度图并不准确,其是一种近似,很显然,物体上的某一点的厚度是会随着观察角度变化而变化的,厚度图却是一个固定值;
尝试构想过真实厚度的计算,在着色器中是不可能实现的,因为厚度的计算需要两个片元的位置信息(入射和出射点);但是着色器是逐像素执行,其无法获得其他片元的信息
- 厚度的制作:
-
翻转模型的面
-
将环境光遮挡渲染到纹理
-
反转纹理的颜色
该过程背后的原理是,通过在背面渲染环境遮挡,可以大致“平均形状内部发生的所有光传输”。
(厚度也可以直接存储在顶点中)
shader
之后补上