PBR物理渲染、IBL基于图像

0 说在开始

PBR总结文章有很多,如 Ubp.a总结文章, moriya苏蛙可总结文章,以及 LearnOpenGLPBR章节部分等等。都是优秀的文章,不在过多重复和赘述,这里给出需要学习的内容以及我所实现的场景。

整个场景的代码: https://github.com/douysu/person-summary如果对您有帮助,还请给一个star,如果大家发现错误以及不合理之处,还希望多多指出。

1 运行效果

[运行效果视频链接]

2 所需知识和概念

总结学习过程中涉及到的知识和概念。

  • 微平面模型

  • 辐射度量学(Radiometry)

    • 辐射通量(Radiant flux)
    • 辐射强度(Radiant Intensity)
    • 辐照度(Irradiance)
    • 辐射率 (Radiance)
    • 立体角
  • 渲染方程(Render Equation)

    • BRDF(Bidirectional Reflective Distribution Function)
    • Cook-Torrance 微表面模型
      • 正态分布函数(Normal Distribution Function)
      • 菲涅尔方程(Fresnel Rquation)
      • 几何函数(Geometry Function)
    • 常见PBR材质
  • 基于图像的照明(Image Based Lighting, IBL)

    • 通过Environment Map生成漫反射Irradiance贴图
    • 通过Environment Map生成带有粗糙度Roughness的镜面Irradiance贴图
    • 采样及积分(蒙特卡洛方法)

总结的只是重点内容,还有HDR、Gamma变换等内容在LearnOpenGL中查看。

3 踩坑及优化

LearnOpenGL的IBL代码比较冗余,个人在此基础上进行优化,优化部分如下。

3.1 PBR纹理加载优化

代码涉及加载较多纹理,复制粘贴很难受,完成优化:

    const int sphereNum = 8; 
    std::string inputPath = "resources/textures/pbr"; 
    std::string twoInputPath[] = { "/gold/", "/slipperystonework/", "/ornate-celtic-gold/", "/bamboo-wood-semigloss/", "/wornpaintedcement/", "/paint-peeling/", "/Titanium-Scuffed/", "/wrinkled-paper/" }; 
    std::string allTextureName[] = { "albedo.png", "normal.png", "metallic.png", "roughness.png", "ao.png" }; 
    unsigned int sphereMap[sphereNum][5]; 
     
    for (int i = 0; i < sphereNum; i++) 
    { 
        std::string tempInputPath = inputPath + twoInputPath[i]; 
        for (int j = 0; j < 5; j++) 
        { 
            std::string lastInputPath = tempInputPath + allTextureName[j]; 
            sphereMap[i][j] = loadTexture(FileSystem::getPath(lastInputPath).c_str()); 
        } 
    } 

3.2 assimp模型数据加载顺序

assimp模型加载顺序与Shader中数据输入顺序不同,需要修改,否则无法完成加载模型。

        // set the vertex attribute pointers 
        // vertex Positions 
        glEnableVertexAttribArray(0);	 
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0); 
        // vertex normals 
        glEnableVertexAttribArray(1);	 
        glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, TexCoords)); 
        // vertex texture coords 
        glEnableVertexAttribArray(2);	 
        glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Normal)); 
#version 330 core 
layout (location = 0) in vec3 aPos; 
layout (location = 1) in vec2 aTexCoords; 
layout (location = 2) in vec3 aNormal; 

out vec2 TexCoords; 
out vec3 WorldPos; 
out vec3 Normal; 

uniform mat4 projection; 
uniform mat4 view; 
uniform mat4 model; 

void main() 
{ 
TexCoords = aTexCoords; 
WorldPos = vec3(model * vec4(aPos, 1.0)); 
Normal = mat3(model) * aNormal; 

gl_Position =  projection * view * vec4(WorldPos, 1.0); 
} 

3.3 完整项目配置

从零配置了一个PBR VS项目,其中涉及到lib,dll,等文件导入,配置好的项目在这里找到: https://github.com/douysu/person-summary

4 参考

[1] LearnOpenGL

[2] 闫令琪-现代计算机图形学入门-Ray Tracing

[3] 以及其他博主文章

你可能感兴趣的:(3D图形学,PBR,图形学,3d,渲染器,IBL)