首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >IBL探测器BRDF预集成工件

IBL探测器BRDF预集成工件
EN

Stack Overflow用户
提问于 2016-06-28 15:08:12
回答 1查看 291关注 0票数 3

我遵循'Moving Frostbite to PBR course notes‘在我的OpenGL渲染引擎中实现IBL,但是我在预集成公式的镜面反射部分时遇到了一些问题。

正如您将从我的下一张图片中看到的,问题在预先过滤的重要性采样的立方图结果的mipmap中可见。

这是正X面mip链:

这是负X面mip链:

这是我使用的环境贴图(它是以HDR格式动态创建的基于物理的天空纹理):

这是环境贴图的正X面mip链:

正如您所看到的,在正X面的mips右侧,采样方向似乎与mip左侧的采样方向相似。

此外,在正X面的第二个mip上可以看到那些“点状”形状,我认为可能是由于样本数量较少?

这是我用来预集成镜面IBL的代码:

代码语言:javascript
复制
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);
}
EN

回答 1

Stack Overflow用户

发布于 2016-06-28 15:54:02

发现这是由于立方体面边附近的立方体贴图接缝问题。启用GL_TEXTURE_CUBE_MAP_SEAMLESS解决了问题。我没有注意到这一点,因为我使用NSight来调试着色器,但是NSight不支持glTexParameteriGL_TEXTURE_CUBE_MAP_SEAMLESS,所以我总是禁用它来调试着色器,但我发现NSight接受glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS)

然而,还有一个问题,mips非常非常嘈杂,而且还有大量的样本。通过1024个样本,我得到了以下结果:

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38069330

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档