인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

샤니캉님의 프로필 이미지
샤니캉

작성한 질문수

게임 개발자를 위한 3D 그래픽스, 쉐이더, OpenGL (6) - 쉐이딩 기초, 퐁 리플렉션 모델, 블린-퐁 쉐이딩

vert_phong.vert negate 질문

작성

·

47

0

  • 학습 관련 질문 을 남겨주세요. 상세히 작성하면 더 좋아요!

  • 출장이 잦아서, 답변에 시간이 좀 걸릴 수는 있습니다. 양해 바랍니다. 🏃

 

안녕하세요, 강의를 듣고 직접 구현해보며 연습중인데 한 가지 궁금한게 생겨 질문 드립니다.

 

앞서 진행했던 강의의 vertex shader와 마찬가지로, z-negate 를 해주어야한다고 생각해서 버텍스 쉐이더에서 vPos를 구하고

vPos.z *= -1

을 해주고 있었습니다.

 

하지만 강의 소스코드에는 이 negate해주는 부분이 없는게 왜인지 잘 모르겠습니다.

강의 소스코드에는 C++ 코드 상에서 negate되어지는 부분이 있는걸까요?

 

저는 negate하지 않으면 아래와 같은 결과로 렌더링됩니다.

image.png

 

vertex shader에서 z-negate하면 잘 나옵니다.

image.png

 

#version 410 core

struct Light
{
    vec4 position;
    vec4 ambient;
    vec4 diffuse;
    vec4 specular;
    vec4 att;
};

struct Material
{
    vec4 ambient;
    vec4 diffuse;
    vec4 specular;
    float shineness;
};

in vec4 aPos;
in vec4 aNorm;

uniform mat4 uMat;

uniform Light light;
uniform Material material;

out vec4 vColor;

void main()
{
    vec4 vPos = uMat * aPos;
    vec4 vNorm = transpose(inverse(uMat)) * aNorm;

    vec3 N = normalize(vNorm.xyz);
    vec3 L = normalize(light.position.xyz - vPos.xyz);
    vec3 V = vec3(0.0f, 0.0f, 1.0f);
    vec3 R = reflect(-L,N);

    vec4 ambient = light.ambient * material.ambient;
    float d = length(light.position.xyz - vPos.xyz);
    float denom = light.att.x + light.att.y * d + light.att.z * d * d;
    vec4 diffuse = max(dot(L,N), 0.0) * light.diffuse * material.diffuse / denom;
    vec4 specular = pow(max(dot(R, V), 0.0), material.shineness) * light.specular * material.specular / denom;


    vColor = ambient + diffuse + specular;
    vPos.z *= -1;
    gl_Position = vPos;
}

답변 2

0

안녕하세요.

강의를 진행해 나가면서, 앞부분에서는 z 좌표를 negate 하는 방식으로 좌표계를 전환했습니다.

뒤에, projection 부분을 설명하면서, projection matrix를 설정할 때, z 좌표 부분을 matrix 내에서 한번 뒤집도록 했습니다. 그래서, 그 이후는 z negate 부분이 vertex shader 에서 삭제되었습니다.

정확히는 projection matrix 에서 이미 z-negate 를 하는 경우라면, vertex shader 에서 z-negate를 하지 않습니다. 위의 코드가 바로 여기 해당될 겁니다. projection matrix를 계산하는 부분의 코드를 검토해 보면, 거기서 이미 z-negate를 하고 있을 겁니다.

감사합니다. ~

0

안녕하세요, 인프런 AI 인턴입니다. 샤니캉님, 질문해 주셔서 감사합니다!

현재 질문하신 내용은 OpenGL의 좌표계 전환과 관련이 있어 보입니다. OpenGL에서 객체를 렌더링할 때, 일반적으로 카메라 공간에서는 z축이 증가할수록 화면 안쪽으로 깊어집니다. 하지만, 일반적으로 사용하는 입체 렌더링 시스템에서는 z축이 감소할수록 화면 안쪽으로 들어가는 경우가 많습니다. 이러한 좌표계의 미묘한 차이로 인해 원하는 결과가 나오지 않을 수 있습니다.

샤니캉님께서 vPos.z *= -1;를 통해 z축을 반전시키는 것은 이러한 좌표계 차이를 보정하기 위한 방법일 수 있습니다. 강의의 다른 부분이나 제공된 C++ 코드에서 이러한 변환이 이루어지지 않는 경우, 쉐이더 코드에서 직접 보정해야 할 필요가 있을 수 있습니다.

렌더링 결과가 다르게 나타나는 이유는 다음과 같을 수 있습니다:

  1. 좌표계의 반전 필요성: 일반적인 3D 렌더링 환경에서 OpenGL의 기본 좌표계와 다른 구조(카메라 공간과 좌표계의 방향성 차이)로 인해 z-axis에 대한 반전 필요성을 느낄 수 있습니다.

  2. 광원과 물체의 위치 관계: OpenGL에서의 빛의 포지션이나 계산법이 다르다면 결과가 달라질 수 있습니다. 빛과 물체 사이의 벡터 계산 시에도 반전이 원인일 수 있습니다.

  3. 라이팅 및 쉐이더 계산의 차이: 쉐이더 코드에서의 정상 벡터 또는 빛의 벡터 계산 시에 그런 반전이 필요할 수도 있습니다. 이는 환경설정의 차이로 발생할 수 있습니다.

추가적으로 확인해 보시면 좋을 내용은, 제공된 C++ 코드 상에서 변환이나 프로젝션 매트릭스 내의 설정 값입니다. 특정 매트릭스나 내역이 z축 좌표에 어떠한 영향을 주고 있는지 확인이 필요합니다.

더 자세한 내용은 OpenGL 좌표계 변환과 같은 자료를 통해 확인해 보실 수 있습니다.

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

샤니캉님의 프로필 이미지
샤니캉

작성한 질문수

질문하기