我读了一些关于BRDF集成的文章,不管有没有重要的抽样,我都不理解公式中的一件事。
我证实了它的数值积分库克-托兰斯BRDF和简单兰伯余弦BRDF,但我不明白为什么2π乘法消失时,我们使用重要性抽样时,从数学角度?
下面是用余弦函数积分的例子。在重要意义上,采样余弦函数也被用作自己的PDF。另外,我对这两种情况的集成代码正确吗?
float f(Vec3f sampleDir) { return sampleDir.z; }
float pdf(Vec3f sampleDir) { return sampleDir.z; } // cosine function is also its PDF
void uniformIntegrationCos()
{
double sum = 0.0;
const int N = 1000;
for (int i = 0; i < N; ++i)
{
Vec3f sampleDir = randomHemisphere(i, N); // fibonacci hemisphere spiral
float value = f(sampleDir);
float weight = sampleDir.z; // NdotL == pdf(sample)
sum += value * weight / PI / N; // divide by PI to normalize cosine-weighted PDF
}
const float HEMISPHERE_SOLID_ANGLE = 2.f * PI; // integration area
sum *= HEMISPHERE_SOLID_ANGLE;
std::cout << "Sum = " << sum << std::endl;
}
void importanceIntegrationCos()
{
double sum = 0.0;
const int N = 1000;
for (int i = 0; i < N; ++i)
{
// generate sample direction using inversed CDF of cosine BRDF
Vec2f r = randomHammersley(i, N);
float phi = 2.f * PI * r.x;
float sinTheta = sqrt(r.y);
float cosTheta = sqrtf(1.f - sinTheta * sinTheta);
Vec3f sampleDir;
sampleDir.x = cos(phi) * sinTheta;
sampleDir.y = sin(phi) * sinTheta;
sampleDir.z = cosTheta;
float value = f(sampleDir);
sum += value / N; // BRDF is divided by it's PDF, so no NdotL weight and no PDF normalization by dividing by PI
}
//const float HEMISPHERE_SOLID_ANGLE = 2.f * PI; // integration area
//sum *= HEMISPHERE_SOLID_ANGLE; // Not needed, why ???
std::cout << "Sum = " << sum << std::endl;
}
void main()
{
uniformIntegrationCos();
importanceIntegrationCos();
}
发布于 2021-11-02 10:36:36
想一想:当在半球上均匀地整合时,你就好像是重要的--用一个恒定的1/2π的pdf进行抽样。
那么,2π在结尾处的乘法可以看作是pdf的除法,从和中扣除,因为它是常数。
常量pdf是1/2π (相对于其他一些数字),因为它需要标准化才能在半球上整合到1,这是因为半球的面积是2π。
从我所看到的情况来看,您的代码看起来是合理的,但我将定义函数pdf
,以包含余弦pdf的1/π归一化因子:
float cosinePDF(Vec3f sampleDir) { return sampleDir.z / PI; }
https://computergraphics.stackexchange.com/questions/12309
复制