- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在关注“Moving Frostbite to PBR course notes” ' 在我的 OpenGL 渲染引擎中实现 IBL,但我在预积分方程的镜面反射分量时遇到了一些问题。
正如您将从我的下一张图片中看到的那样,问题在预过滤重要性采样的立方体贴图结果的 mipmap 中可见。
这是我使用的环境贴图(它是以 HDR 格式动态创建的基于物理的天空纹理):
如您所见,在正 X 面的 mip 右侧,采样方向似乎与 mip 左侧的采样方向相似。
此外,在正 X 面的第二个 mip 上可以看到那些“点状”形状,我认为这可能是由于样本量少所致?
这是我用来预集成镜面 IBL 的代码:
float radicalInverse_VdC(uint bits)
{
bits = (bits << 16u) | (bits >> 16u);
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
return float(bits) * 2.3283064365386963e-10; // / 0x100000000
}
//
// Attributed to:
// http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
// Holger Dammertz.
//
vec2 Hammersley(uint i, uint N)
{
return vec2(float(i)/float(N), radicalInverse_VdC(i));
}
// Based on GGX example in:
// http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf
vec3 importanceSampleGGX(vec2 u, float roughness, vec3 N, vec3 upVector, vec3 tangentX, vec3 tangentY)
{
float a = roughness * roughness;
float phiH = u.x * PI * 2.0f;
float cosThetaH = sqrt((1.0f - u.y) / (1.0f + (a * a - 1.0f) * u.y));
float sinThetaH = sqrt(1.0f - min(1.0f, cosThetaH * cosThetaH));
vec3 H = vec3(sinThetaH * cos(phiH), sinThetaH * sin(phiH), cosThetaH);
H = normalize(tangentX * H.x + tangentY * H.y + N * H.z);
return H;
}
// D(h) for GGX.
// http://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html
float D_GGX(float roughness, float NdotH)
{
float a = roughness * roughness;
float a2 = a * a;
float NdotH2 = NdotH * NdotH;
float f = 1.0f + (NdotH2 * (a2 - 1.0f));
return a2 / (f * f);
}
float D_GGX_Divide_Pi(float roughness, float NdotH)
{
return D_GGX(roughness, NdotH) / PI;
}
vec3 ImportanceSample (vec3 N)
{
vec3 V = N;
float size2 = ConvolutionSrcSize * ConvolutionSrcSize;
vec3 upVector = abs(N.z) < 0.999 ? vec3(0.0f, 0.0f, 1.0f) : vec3(1.0f, 0.0f, 0.0f);
vec3 tangentX = normalize(cross(upVector, N));
vec3 tangentY = cross(N, tangentX);
vec3 accBrdf = vec3(0.0f);
float accBrdfWeight = 0.0f;
float roughness = ConvolutionRoughness;
uint samplesCount = uint(ConvolutionSampleCount);
for(uint i = uint(0); i < samplesCount; i++)
{
vec2 eta = Hammersley(i, samplesCount);
vec3 H = importanceSampleGGX(eta, roughness, N, upVector, tangentX, tangentY);
vec3 L = 2.0f * dot(V, H) * H - V;
float NdotL = dot(N, L);
if(NdotL > 0.0f)
{
float NdotH = saturate(dot(N, H));
float LdotH = saturate(dot(L, H));
float pdf = D_GGX_Divide_Pi(roughness, NdotH) * NdotH / (4.0f * LdotH);
float omegaS = 1.0f / (samplesCount * pdf);
float omegaP = 4.0f * PI / (6.0f * size2);
float mipLevel = roughness == 0.0f ? 0.0f : clamp(0.5f * log2(omegaS / omegaP), 0.0f, ConvolutionMipCount);
vec4 Li = textureLod(ConvolutionSrc, L, mipLevel);
accBrdf += Li.rgb * NdotL;
accBrdfWeight += NdotL;
}
}
if(accBrdfWeight > 0.0f)
return accBrdf * (1.0f / accBrdfWeight);
else
return accBrdf;
}
void main()
{
// VertexIn.textureCoord is the normal of a sphere I use as mesh to draw to the IBL cubemap
FragColor = vec4(ImportanceSample(VertexIn.textureCoord), 1.0f);
}
最佳答案
发现这是由于立方体面边缘附近的立方体贴图接缝问题。启用 GL_TEXTURE_CUBE_MAP_SEAMLESS
解决了这个问题。我没有注意到这一点,因为我使用 NSight 调试着色器,但 NSight 不支持 glTexParameteri
和 GL_TEXTURE_CUBE_MAP_SEAMLESS
所以我总是禁用它来调试着色器,但我发现NSight 接受 glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS)
。
但仍然存在一个问题,mips 非常嘈杂,而且样本量很大。我得到了 1024 个样本:
关于opengl - IBL 探测 BRDF 预积分伪像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38069330/
我有一个小路径跟踪器,我正在尝试弄清楚如何实现一些基本的 BRDF。 这是我使用的管道的简要说明(没有递归): 1) For each pixel: 1.1) For each sample:
我不确定这是否是问这个问题的正确地方,但我想不出更好的地方。有人可以向我解释为什么 BRDF 是两个微分的商,而不是输出辐照度和辐照度的未微分数量的商吗?在最好的情况下有一些涂鸦。我能找到的关于这个主
这是一个理论问题。我目前正在研究渲染方程,我不明白在哪种情况下区域采样或半球采样更好以及为什么。 我想知道的另一件事是,如果我们采用两种方法的平均值,结果是否会更好? 最佳答案 Veach 和 Gui
我正在关注“Moving Frostbite to PBR course notes” ' 在我的 OpenGL 渲染引擎中实现 IBL,但我在预积分方程的镜面反射分量时遇到了一些问题。 正如您将从我
现在我正在研究一个关于 BRDF 的基本 CG 程序。而且我拿到图像后,似乎所有的点都对着光太亮了,我不知道为什么。这是我的代码,我在其中尝试调用 lookup_brdf_val 函数。 Vec3f
我试图弄清楚我的 BRDF 方法是否正确。 // Calculate sun BRDF color vec3 sunBrdf = brdf(tsLightSourceDir, tsEyeDir,
我是一名优秀的程序员,十分优秀!