IBL-镜面反射(LUT篇)

LUT(查找表)用于预计算BRDF(双向反射分布函数)的积分,主要涉及几何阴影项和考虑粗糙度的Fresnel项。通过在半球上采样并积分,计算出不同入射角和粗糙度下的反射效果。在实时渲染中,LUT简化了不同材质的反射处理,一个LUT贴图可以应用于各种场景,提高效率。
摘要由CSDN通过智能技术生成

1. LUT需要求解什么

首先我们将镜面反射部分的积分分割为两个部分。
L o ( p , ω o ) = ∫ Ω L i ( p , ω i ) d ω i ∗ ∫ Ω f r ( p , ω i , ω o ) n ⋅ ω i d ω i L_{o}\left(p, \omega_{o}\right)=\int_{\Omega} L_{i}\left(p, \omega_{i}\right) d \omega_{i} * \int_{\Omega} f_{r}\left(p, \omega_{i}, \omega_{o}\right) n \cdot \omega_{i} d \omega_{i} Lo(p,ωo)=ΩLi(p,ωi)dωiΩfr(p,ωi,ωo)nωidωi
第一部分的积分即为预滤波,将所有照到该像素点的光照求积分。
∫ Ω L i ( p , ω i ) d ω i \int_{\Omega} L_{i}\left(p, \omega_{i}\right) d \omega_{i} ΩLi(p,ωi)dωi
第二部分需要我们知道,这个半球的光线照过来之后,有多少反射到了 ω i \omega_{i} ωi 所在的方向。

L U T LUT LUT 求解的便是,在夹角 c o s θ = N ⋅ ω i cos\theta = N\cdot \omega_{i} cosθ=Nωi,粗糙度为 r o u g h n e s s roughness roughness 下, B R D F BRDF BRDF 的积分是多少。
即,输入为
( N ⋅ V , r o u g h n e s s ) (N\cdot V , roughness) (NV,roughness)
输出为
∫ Ω f r ( p , ω i , ω o ) n ⋅ ω i d ω i \int_{\Omega} f_{r}\left(p, \omega_{i}, \omega_{o}\right) n \cdot \omega_{i} d \omega_{i} Ωfr(p,ωi,ωo)nωidωi

= ∫ Ω D F G 4 ( ω o ⋅ n ) ( ω i ⋅ n ) n ⋅ ω i d ω i = \int_{\Omega} \frac{D F G}{4\left(\omega_{o} \cdot n\right)\left(\omega_{i} \cdot n\right)} n \cdot \omega_{i} d \omega_{i} =Ω4(ωon)(ωin)DFGnωidωi

= ∫ Ω D G 4 ( ω o ⋅ n ) ( ω i ⋅ n ) ( F 0 + ( 1 − F 0 ) ( 1 − ω o ⋅ h ) 5 ) n ⋅ ω i d ω i =\int_{\Omega} \frac{D G}{4\left(\omega_{o} \cdot n\right)\left(\omega_{i} \cdot n\right)} \left(F_{0}+\left(1-F_{0}\right)\left(1-\omega_{o} \cdot h\right)^{5}\right) n \cdot \omega_{i} d \omega_{i} =Ω4(ωon)(ωin)DG(F0+(1F0)(1ωoh)5)nωidωi

= F 0 ∫ Ω D G 4 ( ω o ⋅ n ) ( ω i ⋅ n ) ( 1 − ( 1 − ω o ⋅ h ) 5 ) n ⋅ ω i d ω i + ∫ Ω D G 4 ( ω o ⋅ n ) ( ω i ⋅ n ) ( 1 − ω o ⋅ h ) 5 n ⋅ ω i d ω i = F_{0} \int_{\Omega} \frac{D G}{4\left(\omega_{o} \cdot n\right)\left(\omega_{i} \cdot n\right)} \left(1-\left(1-\omega_{o} \cdot h\right)^{5}\right) n \cdot \omega_{i} d \omega_{i} \\ \quad\\ + \int_{\Omega} \frac{D G}{4\left(\omega_{o} \cdot n\right)\left(\omega_{i} \cdot n\right)} \left(1-\omega_{o} \cdot h\right)^{5} n \cdot \omega_{i} d \omega_{i} =F0Ω4(ωon)(ωin)DG(1(1ωoh)5)nωidωi+Ω4(ωon)(ωin)DG(1ωoh)5nωidωi

离散化,采样根据法线分布函数D选择路线,其中法线n在单条路径中,法线为h
= F 0 ∑ c o u n t G ( ω o ⋅ n ) ( ω i ⋅ n ) ( 1 − ( 1 − ω o ⋅ h ) 5 ) h ⋅ ω i c o u n t + ∑ c o u n t G ( ω o ⋅ n ) ( ω i ⋅ n ) ( 1 − ω o ⋅ h ) 5 h ⋅ ω i c o u n t = F_{0} \frac{ \sum_{count} \frac{G}{\left(\omega_{o} \cdot n\right)\left(\omega_{i} \cdot n\right)} \left(1-\left(1-\omega_{o} \cdot h\right)^{5}\right) h \cdot \omega_{i} } { count } \\ \quad\\ + \frac{ \sum_{count} \frac{G}{\left(\omega_{o} \cdot n\right)\left(\omega_{i} \cdot n\right)} \left(1-\omega_{o} \cdot h\right)^{5} h \cdot \omega_{i} } { count } =F0countcount(ωon)(ωin)G(1(1ωoh)5)hωi+countcount(ωon)(ωin)G(1ωoh)5hωi
可以看出公式中主要需要考虑到数据有:

  1. G ( ω o ⋅ n ) ( ω i ⋅ n ) h ⋅ ω i \frac{G}{\left(\omega_{o} \cdot n\right)\left(\omega_{i} \cdot n\right)} h \cdot \omega_{i} (ωon)(ωin)Ghωi
  2. ( 1 − ω o ⋅ h ) 5 \left(1-\omega_{o} \cdot h\right)^{5} (1ωoh)5
  3. 如何进行采样 如何进行采样 如何进行采样
  4. 如何积分 如何积分 如何积分

问题1

代码如下

float GeometrySchlickGGX(float NdotV, float roughness)
{
    // note that we use a different k for IBL
    float a = roughness;
    float k = (a * a) / 2.0;

    float nom   = NdotV;
    float denom = NdotV * (1.0 - k) + k;

    return nom / denom;
}
// ----------------------------------------------------------------------------
float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness)
{
    float NdotV = max(dot(N, V), 0.0);
    float NdotL = max(dot(N, L), 0.0);
    float ggx2 = GeometrySchlickGGX(NdotV, roughness);
    float ggx1 = GeometrySchlickGGX(NdotL, roughness);

    return ggx1 * ggx2;
}

int main(){
	for(i : count){
		float G = GeometrySmith(N, V, L, roughness);
        float G_Vis = (G * VdotH) / (NdotH * NdotV);
	}
}

问题2

float Fc = pow(1.0 - VdotH, 5.0);

问题3:如何进行采样

我们已知光线输出方向为 V = ω o V = \omega_o V=ωo,采光防线为 L = ω i L = \omega_i L=ωi
采光方向的计算采用在预过滤篇使用的采样方式,在以N为周边的法线区域采样的得到H,在通过反射计算得到L

vec2 Xi = Hammersley(i, SAMPLE_COUNT);
vec3 H = ImportanceSampleGGX(Xi, N, roughness);
vec3 L = normalize(2.0 * dot(V, H) * H - V);

问题4 : 如何积分

按照公式,得到每个所有采样方向积分的综合

		A += (1.0 - Fc) * G_Vis;
        B += Fc * G_Vis;

之后对积分求平均,返回。

    A /= float(SAMPLE_COUNT);
    B /= float(SAMPLE_COUNT);
    return vec2(A, B);

问题5:为什么分两段存储

第二部分卷积主要求解:当入射角度为 V ⋅ N V \cdot N VN ,粗糙度为 r o u g h n e s s roughness roughness 时, B R D F BRDF BRDF的平均值。

然而,不同材质应该拥有不同的反射性质,即不同的反射系数以及BRDF,但在实时渲染中,这里做了简化。
实时渲染中不同的材质的参数只包括:粗糙度,基础反射系数
因为不同材质的拥有不同的 F 0 F_0 F0基础反射系数与材质基础颜色金属度有关。
而反射率 F F F 与粗糙度 r o u g h n e s s roughness roughness 有关。

因此 L U T LUT LUT 表的构建不需要任何参数的输入,即与环境贴图,材质纹理,观察角度都无关,一个贴图适用于任何场景。因此在实际使用中,只需要保存该表,每次程序运行时加载就好,不需要计算得到。

生成结果

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Elsa的迷弟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值