Posts OpenGL 공부 - 21 - Material Class
Post
Cancel

OpenGL 공부 - 21 - Material Class

목표


  • Material 클래스 작성


공부 내용


  • 오브젝트에 적용할 색상과 텍스쳐들을 Material 클래스로 래핑하여 쉐이더에 전달한다.

Fragment 쉐이더 수정

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#version 440

#define saturate(x) clamp(x, 0., 1.)

struct Material
{
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;

    sampler2D diffuseMap;
};

in vec3 vs_position;
in vec3 vs_color;
in vec2 vs_texcoord;
in vec3 vs_normal;

out vec4 fs_color;

// ====================== Uniforms =========================
uniform Material material;
uniform sampler2D wallTex;
uniform vec3 lightPos0; // Main Light World Position
uniform vec3 cameraPos; // Camera World Position

void main()
{
    vec3 worldPos = vs_position;

    // ====================== World Vectors =========================
    vec3 worldNormal = normalize(vs_normal);
    vec3 worldLight  = normalize(lightPos0 - worldPos);
    vec3 worldView   = normalize(cameraPos - worldPos);
    vec3 worldHalf = normalize(worldLight + worldView);

    // ====================== Lighting ==============================
    // Ambient Light
    vec3 ambient = vec3(1.);

    // Diffuse Light
    float NdL = dot(worldNormal, worldLight);
    float diffuse = saturate(NdL);

    // Specular Light - Blinn Phong
    float NdH = dot(worldNormal, worldHalf);
    float specBpPower = 500.;
    float specBP = pow(saturate(NdH), specBpPower);

    // Rim Light
    //float NdV = dot(worldNormal, worldView);
    //float rimPower = 1.;
    //float rim = pow(1. - saturate(NdV), rimPower) * 2.;
    
    // ====================== Textures ==============================
    vec3 diffMapCol = texture(material.diffuseMap, vs_texcoord).xyz;
    vec3 diffMapMask = step(vec3(0.01), diffMapCol);
    vec3 wallMapCol = texture(wallTex, vs_texcoord).xyz;
    
    // ====================== Colors ================================
    vec3 ambientCol = material.ambient;
    vec3 diffCol = mix(wallMapCol, diffMapCol * material.diffuse, diffMapMask);
    vec3 specCol = material.specular;
    vec3 lightCol = vec3(1., 1., 1.);
    
    // ====================== Final Colors ==========================
    ambientCol = ambient * ambientCol;
    diffCol = diffuse * diffCol;
    specCol = specBP * specCol;


    vec3 col = (diffCol + specCol) * lightCol + ambientCol;

    fs_color = vec4(col, 1.);
}

Material 클래스 작성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#pragma once

class Material
{
private:
    glm::vec3 ambient;
    glm::vec3 diffuse;
    glm::vec3 specular;
    GLint diffuseMapID;

public:
    Material(const glm::vec3& ambient, const glm::vec3& diffuse, const glm::vec3& specular,
        Texture& diffuseMap)
    {
        this->ambient = ambient;
        this->diffuse = diffuse;
        this->specular = specular;
        this->diffuseMapID = diffuseMap.GetID();
    }
    ~Material() {}

    // 쉐이더에 전달
    void SendToShader(Shader& shader)
    {
        shader.SetVec3f("material.ambient", this->ambient);
        shader.SetVec3f("material.diffuse", this->diffuse);
        shader.SetVec3f("material.specular", this->specular);
        shader.SetTexture("material.diffuseMap", this->diffuseMapID);
    }
};

main.cpp 수정

1
2
3
4
5
6
7
8
9
10
11
Texture texture0("Images/MoonCat.png");
Texture texture1("Images/Wall.png");

// 마테리얼 선언
Material material(
    glm::vec3(0.1f), glm::vec3(1.0f, 1.0f, 1.0f), glm::vec3(1.0f, 0.0f, 1.0f),
    texture0
);

// 쉐이더에 마테리얼 전달
material.SendToShader(shader);


실행 결과


2021_0218_Opengl


Source Code



References


This post is licensed under CC BY 4.0 by the author.