本文主要是介绍Diffuse irradiance 关键知识点,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
卷积:
上面的 Lo 的计算公式,只是计算了一个方向,就一个。例如,物体的一个顶点,到眼睛的方向,就是 w0。
所以,bake的时候,要对所有出射方向计算积分。每个出射的积分计算时,都做半球的累积,再存起来。
这样,使用的时候,眼晴的方向来采样到的,就是该出射方向上预计好的。
辐射度的近似处理:
离散地对两个球坐标轴进行采样时,每个采样近似代表了半球上的一小块区域。如上图所示。注意,由于球的一般性质,当采样区域朝向中心顶部会聚时,天顶角 θθ 变高,半球的离散采样区域变小。为了平衡较小的区域贡献度,我们使用 sinθsinθ 来权衡区域贡献度,这就是多出来的 sin的作用。
vec3 irradiance = vec3(0.0); vec3 up = vec3(0.0, 1.0, 0.0);
vec3 right = cross(up, normal);
up = cross(normal, right);float sampleDelta = 0.025;
float nrSamples = 0.0;
for(float phi = 0.0; phi < 2.0 * PI; phi += sampleDelta)
{for(float theta = 0.0; theta < 0.5 * PI; theta += sampleDelta){// spherical to cartesian (in tangent space)vec3 tangentSample = vec3(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta));// tangent space to worldvec3 sampleVec = tangentSample.x * right + tangentSample.y * up + tangentSample.z * N; irradiance += texture(environmentMap, sampleVec).rgb * cos(theta) * sin(theta);nrSamples++;}
}
irradiance = PI * irradiance * (1.0 / float(nrSamples));
获取一个球面坐标并将它们转换为 3D 直角坐标向量,将向量从切线空间转换为世界空间,并使用此向量直接采样 HDR 环境贴图。我们将每个采样结果加到 irradiance,最后除以采样的总数,得到平均采样辐照度。请注意,我们将采样的颜色值乘以系数 cos(θ) ,因为较大角度的光较弱,而系数 sin(θ) 则用于权衡较高半球区域的较小采样区域的贡献度。
粗糙度与折射率:
pbr流程,使用菲涅耳公式来计算表面的间接反射率,我们从中得出折射率或(漫反射率)。
vec3 kS = fresnelSchlick(max(dot(N, V), 0.0), F0);
vec3 kD = 1.0 - kS;
vec3 irradiance = texture(irradianceMap, N).rgb;
vec3 diffuse = irradiance * albedo;
vec3 ambient = (kD * diffuse) * ao;
但是计算漫反射辐射的光,来自半球内围绕法线 N 的所有方向,所有没有一个确定的法向量来计算菲涅耳效应。
为了模拟菲涅耳效应,用法线和视线之间的夹角计算菲涅耳系数。然而,之前我们是以受粗糙度影响的微表面半向量作为菲涅耳公式的输入,但我们目前没有考虑任何粗糙度,表面的反射率总是会相对较高。间接光和直射光遵循相同的属性,因此我们期望较粗糙的表面在边缘反射较弱。由于我们没有考虑表面的粗糙度,间接菲涅耳反射在粗糙非金属表面上看起来将会有点过强。
我们可以通过在 Sébastien Lagarde 提出的 Fresnel-Schlick 方程中加入粗糙度项来缓解这个问题:
vec3 fresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness)
{return F0 + (max(vec3(1.0 - roughness), F0) - F0) * pow(1.0 - cosTheta, 5.0);
}
vec3 kS = fresnelSchlickRoughness(max(dot(N, V), 0.0), F0, roughness);
vec3 kD = 1.0 - kS;
vec3 irradiance = texture(irradianceMap, N).rgb;
vec3 diffuse = irradiance * albedo;
vec3 ambient = (kD * diffuse) * ao;
这篇关于Diffuse irradiance 关键知识点的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!