計算機圖形學(OPENGL):光照貼圖

本文同時發布在我的個人博客上:https://dragon_boy.gitee.io

光照貼圖

??在實際應用中,一個模型包含不同的組件,每個組件都有不同的材質表現。如果用上一節的內容來實現這一特點是不夠的,接下來介紹漫反射貼圖和高光貼圖。

漫反射貼圖

??我們以紋理為基礎來實現漫反射貼圖。我們用下面的帶金屬邊緣的箱子圖片來進行學習:



??為了使用漫反射貼圖,我們同樣定義一個材質結構體,但不同的是,我們將diffuse屬性設置為sampler2D類型,我們不在需要環境光屬性(由于簡化了環境光的定義,這里使用環境光屬性對結果沒有什么影響,當然,我們可以同樣定義環境光貼圖來影響結果):

struct Material
{
  smapler2D diffuse;
  vec3 specular;
  float shininess;
};
...
in vec2 TexCoords;

??這樣我們就可以計算漫反射的結果:

vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));

??這里我們將材質的環境光設置為材質漫反射的值:

vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));

??這里提供新增紋理坐標的頂點數組:

float vertices[] = {
    // 位置                 // 法線               //紋理
    -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f, 0.0f,
     0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f, 0.0f,
     0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f, 1.0f,
     0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f, 1.0f,
    -0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f, 1.0f,
    -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f, 0.0f,

    -0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   0.0f, 0.0f,
     0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   1.0f, 0.0f,
     0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   1.0f, 1.0f,
     0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   1.0f, 1.0f,
    -0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   0.0f, 1.0f,
    -0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   0.0f, 0.0f,

    -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,  1.0f, 0.0f,
    -0.5f,  0.5f, -0.5f, -1.0f,  0.0f,  0.0f,  1.0f, 1.0f,
    -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,  0.0f, 1.0f,
    -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,  0.0f, 1.0f,
    -0.5f, -0.5f,  0.5f, -1.0f,  0.0f,  0.0f,  0.0f, 0.0f,
    -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,  1.0f, 0.0f,

     0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  1.0f, 0.0f,
     0.5f,  0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  1.0f, 1.0f,
     0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  0.0f, 1.0f,
     0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  0.0f, 1.0f,
     0.5f, -0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  0.0f, 0.0f,
     0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  1.0f, 0.0f,

    -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,  0.0f, 1.0f,
     0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,  1.0f, 1.0f,
     0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,  1.0f, 0.0f,
     0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,  1.0f, 0.0f,
    -0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,  0.0f, 0.0f,
    -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,  0.0f, 1.0f,

    -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  0.0f, 1.0f,
     0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  1.0f, 1.0f,
     0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,  1.0f, 0.0f,
     0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,  1.0f, 0.0f,
    -0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,  0.0f, 0.0f,
    -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  0.0f, 1.0f
};

??更新一下 頂點著色器:

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aTexCoords;
...
out vec2 TexCoords;

void main()
{
    ...
    TexCoords = aTexCoords;
}  

??同時記住更新VAO的設置,并為漫反射貼圖設置ID,并激活和綁定紋理:

lightingShader.setInt("material.diffuse", 0);
...
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, diffuseMap);

??運行結果如下:


高光貼圖

??從上面的結果我們可以發現一些問題,金屬邊的高光與木紋的高光沒什么區別,這是不符合實際的。同樣的,為解決這個問題,我們為高光的顯示設置高光貼圖(通過灰度值來控制高光的強弱)。我們使用下面的圖片來作為高光貼圖:



??原則上木紋處也有高光,但這里我們暫時忽略掉。
??接下來的操作就與漫反射貼圖一樣了。修改結構體:

struct Material {
    sampler2D diffuse;
    sampler2D specular;
    float     shininess;
};  

??修改片元著色器的main函數:

vec3 ambient  = light.ambient  * vec3(texture(material.diffuse, TexCoords));
vec3 diffuse  = light.diffuse  * diff * vec3(texture(material.diffuse, TexCoords));  
vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));
FragColor = vec4(ambient + diffuse + specular, 1.0);   

??設置貼圖ID,并激活和綁定貼圖:

lightingShader.setInt("material.specular", 1);
...
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, specularMap);  

??運行結果如下:


??可以看到結果比較真實了。這里貼出原文代碼:Code

??使用漫反射貼圖和高光貼圖我們可以為模型增添許多細節,當然,還有許多諸如法線貼圖,凹凸貼圖,反射貼圖的技術來為模型增添更多的細節,這些將在之后講解。
??最后,請多多關注原文:https://learnopengl.com/Lighting/Lighting-maps

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。