OpenGL Lighting Scene 조명 씬 구현 [Learn OpenGL 쉬운 번역]

728x90
반응형
※ 본 포스팅은 learnopengl.com을 번역 및 가감한 포스팅이며, learnopengl에서는 번역 작업 참여를 적극 장려하고 있습니다!
아래 링크에서 원문을 확인할 수 있습니다.

 

A lighting scene

이후에는 실제 조명을 시뮬레이션 해서 효과도 만들어보고 하는 등 색상을 이용해봅시다. 일단 광원을 장면에 표시하려면 물체 하나는 있어야 확인 가능하겠죠?

 

빛을 비출 물체는 이전에 사용했던 cube를 사용하고, 광원의 위치를 표시할 객체도 필요합니다.(이미 가지고 있는 cube object를 사용합니다)

 

정점 버퍼 객체를 채구오 정점 속성 포인터를 설정하는 것은 익숙하실테니 지나가고, vertex shader에서 컨테이너를 

#version 330 core
layout (location = 0) in vec3 aPos;

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

void main()
{
    gl_Position = projection * view * model * vec4(aPos, 1.0);
}

vertex data를 업데이트하고 vertex attribute pointer를 새로운 vertex shader에 맞춥니다.

 

광원 큐브를 렌더링 할거니까, 광원을 위한 새로운 VAO를 생성합시다. 지금이야 같은 VAO를 써서 광원을 렌더링하고 transform을 수행할 수 있지만, 이후 컨테이너 객체의 데이터와 속성 포인터를 변경하려면 따로 분리하는게 좋겠죠. 

unsigned int lightVAO;
glGenVertexArrays(1, &lightVAO);
glBindVertexArray(lightVAO);
// 컨테이너의 VBO 데이터는 이미 포함되어 있으므로 VBO만 바인딩하면 됩니다.
glBindBuffer(GL_ARRAY_BUFFER, VBO);
// 정점 속성을 설정합니다.
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);

컨테이너 광원 큐브 모두 생성했으니 두 개에 대한 fragment shader를 정의합니다.

#version 330 core
out vec4 FragColor;
  
uniform vec3 objectColor;
uniform vec3 lightColor;

void main()
{
    FragColor = vec4(lightColor * objectColor, 1.0);
}

fragment shader는 객체와 광원의 색을 uniform 변수에서 가져오고, shader 안에서 이 둘을 곱해서 물체에 빛이 반사된 색을 만듭니다. 이제 uniform으로 객체와 빛의 색을 전달해줍시다.

// 유니폼을 설정하기 전에 해당 셰이더 프로그램을 먼저 사용하세요.
lightingShader.use();
lightingShader.setVec3("objectColor", 1.0f, 0.5f, 0.31f);
lightingShader.setVec3("lightColor",  1.0f, 1.0f, 1.0f);

우리는 나중에 조명 shader를 업데이트 하게 될 텐데 이때 광원큐브도 영향을 받을 수 있습니다. 그래서 광원 객체 색이 조명 계산의 변화를 받지 않고 분리되면 좋겠네요. 그래서 광원 큐브가 빛이 나온 곳임을 알 수 있도록 밝게 색상을 유지시킵시다.

 

그럴려면 광원 큐브를 그릴 또 다른 shader를 만들어야합니다. 그러면 조명 셰이더를 바꾸어도 괜찮을 겁니다. vertex shader는 동일하게 사용하고, 광원 큐브의 fragment shader는 큐브 색이 밝게 보이도록 흰색으로 만들어줍니다.

#version 330 core
out vec4 FragColor;

void main()
{
    FragColor = vec4(1.0); // 모든 벡터 값을 1.0으로 설정
}

조명 셰이더를 사용해서 컨테이너 객체나 나중에 추가될 다른 객체들을 렌더링하고, 광원 큐브는 방금 만든 광원 셰이더를 사용해서 렌더링합니다. 

 

광원 큐브는 물체로 오는 빛이 어디서 출발했는지 우리가 눈으로 확인하려고 넣은 겁니다. 그냥 씬의 특정 위치에 광원만 정의하면 광원이 눈에 보이지 않아요. 광원의 위치가 보이면 빛이 어디서 오고 있는지 확인할 수 있겠죠. 그래서 별도의 광원 큐브를 추가하도록 합니다. 광원은 계속 같은 위치에 유지되니까 마찬가지로 광원 큐브도 같은 위치에 만듭시다. 

 

광원의 위치를 월드 공간 좌표의 전역변수 vec3로 선언합니다.

glm::vec3 lightPos(1.2f, 1.0f, 2.0f);

광원 큐브를 광원의 위치로 이동시키고 크기를 줄입니다.

model = glm::mat4(1.0f);
model = glm::translate(model, lightPos);
model = glm::scale(model, glm::vec3(0.2f));

광원 큐브 렌더링을 합니다.

lightCubeShader.use();
// 모델, 뷰, 프로젝션 행렬 유니폼 설정
[...]
// 광원 큐브 객체 그리기
glBindVertexArray(lightCubeVAO);
glDrawArrays(GL_TRIANGLES, 0, 36);

이제 조명을 테스트하기 위한 애플리케이션이 만들어졌습니다. 결과는 다음과 같아요.

물체가 빛을 받은 조명효과로는 아직 안보이나요? 이제 다음에 다룰겁니다. 

 

728x90
반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유