2013-10-30 5 views
0

Assimp를 사용하여 3D 모델을 가져오고 노멀 맵에 대한 접선과 비트를 제공합니다. 그러나 꼭지점 셰이더에서 접선과 비트 맵 벡터를 곱하는 데 사용되는 행렬이 무엇인지 알 수 없습니다. WorldViewProjection 매트릭스 또는 다른 특수 목적의 "일반 매트릭스"입니까?OpenGL 버텍스 쉐이더 용 NormalMatrix?

UPDATE : 내 버텍스 쉐이더

const std::string gVertexShader = "#version 330                      \n \ 
                               \n \ 
             layout(std140) uniform;             \n \ 
                               \n \ 
             uniform UnifTransform             \n \ 
             {                  \n \ 
              mat4 mWVPMatrix;             \n \ 
              mat4 mWorldMatrix;             \n \ 
              float mTextureTilingFactor;           \n \ 
             } Transform;               \n \ 
                               \n \ 
             layout(location = 0) in vec3 vert_position;            \n \ 
             layout(location = 1) in vec3 vert_normal;             \n \ 
             layout(location = 2) in vec2 vert_texcoord;             \n \ 
             layout(location = 3) in vec3 vert_tangent;             \n \ 
             layout(location = 4) in vec3 vert_bitangent;             \n \ 
                               \n \ 
             out vec3 frag_position;             \n \ 
             out vec3 frag_normal;             \n \ 
             out vec2 frag_texcoord;             \n \ 
             out vec3 frag_tangent;             \n \ 
             out vec3 frag_bitangent;             \n \ 
                               \n \ 
             void main()                         \n \ 
             {                             \n \ 
              gl_Position = Transform.mWVPMatrix * vec4(vert_position, 1.0); \n \ 
                               \n \ 
              vec4 position = Transform.mWorldMatrix * vec4(vert_position, 1.0); \n \ 
              vec4 normal = Transform.mWorldMatrix * vec4(vert_normal, 0.0); \n \ 
              vec4 tangent = Transform.mWorldMatrix * vec4(vert_tangent, 0.0); // correct matrix? \n \ 
              vec4 bitangent = Transform.mWorldMatrix * vec4(vert_bitangent, 0.0); \n \ 
                               \n \ 
              frag_position = position.xyz;          \n \ 
              frag_normal = normal.xyz;           \n \ 
              frag_tangent = tangent.xyz;           \n \ 
              frag_bitangent = bitangent.xyz;           \n \ 
              frag_texcoord = Transform.mTextureTilingFactor * vert_texcoord;  \n \ 

답변

4

일반적으로 TBN (접선, 비잔틴, 일반) 행렬 (3x3)은 탄젠트 공간에서 객체 공간으로 이동하는 데 사용됩니다. 당신은 법선을 번식하여 변형시킬 수 있습니다. 법선은 사실상 방향성을 가지므로, 일반적으로 다루는 대부분의 변환 행렬과는 달리 이것을 수행하려면 vec3 및 3x3 행렬 만 필요합니다. 내 마음 속에서, 그것이이 특별한 행렬을 "특별하게"만드는 것입니다. 이 행렬을 사용하는 방법에 따라 라이트 벡터를 접선 공간으로 변환하거나 노멀 맵을 오브젝트 공간으로 변환 할 수 있습니다.

일반적으로 Tangent, Bitangent 및 Normal 벡터를 개별적으로 배가하지 않습니다. 그들은 당신의 벡터 공간 기초를 정의하고, 혼자 있어야합니다. 이 벡터 공간으로 또는 밖으로 변환하는 데 사용되는 행렬은이 세 벡터에서 파생됩니다. 탄젠트 공간에 오브젝트 공간에서 이동이 역을 사용할 수 있습니다

물론
mat3 (Tangent, Bitangent, Normal); 

:


이 (의사 코드)를 수행하여 공간 객체에 탄젠트 공간으로 변형하는 행렬을 만들 것 . Assimp는 (대략적으로) 직교 정규 기저 벡터를 생성 할 것이므로 역변환이 존재하도록 보장되며이 경우 전치 연산자로 나타낼 수 있습니다.

접선과 bitangent

되어 있지 질감의 전단이 존재할 수 있고 둘 중 하나의 법선에 수직으로 필요하지만 직교하도록 보장. 일부 모델 가져 오기 소프트웨어는 TBN 벡터를 출력 할 때 후 처리 단계로 직교 화를 수행하며 대부분의 자습서에서는이 관계가 항상이라고 가정하는 것으로 보입니다.

+0

그러나이 매트릭스가 프래그먼트 셰이더에서 사용되지 않았습니까? 버텍스 쉐이더에있는 것을 참조하고 있습니다. 업데이트 된 질문입니다. – KaiserJohaan

+0

@KaiserJohaan : 반드시 그런 것은 아닙니다. 조각 쉐이더에서이를 사용하여 샘플 된 접선 공간 법선을 오브젝트 공간으로 변환 할 수 있습니다. 이는 지연 쉐이딩에서 매우 일반적입니다. 또한 조명 방향 벡터를 버텍스 쉐이더의 접선 공간으로 변환하는 데 사용할 수도 있습니다. 이것은 프래그먼트 쉐이더의 복잡성을 줄여줌으로써 포워드 쉐이딩 엔진에서 유용합니다. 그러나 모든 경우에 꼭지점 법선, 접선 또는 비트 대를 변환 할 필요가 없습니다. TBN 행렬을 변경하여 공간을 볼 수있는 접선 공간을 만들 수도 있지만 (객체 공간은 대개 유용하지 않습니다) . –

+0

@KaiserJohaan : *** 조각 쉐이더 ***에서 탄젠트, 비트 겐트 및 법선 벡터를 사용하는 방법을 정확하게 설명 할 수 있습니까? 업데이트 된 질문에서 샘플링 된 접선 공간 법선을 다른 벡터 공간 (이 경우에는 월드 공간)으로 변환한다는 인상을 받고 있습니다. –

3

접선 및 bitangents (또한 법선)는 노멀과 동일한 규칙을 따릅니다. 사실 접선, 비 정규 분포 및 법선은 3 × 3 행렬로 표현할 수있는 표면 로컬 공간의 밑을 형성합니다. 이 공간은 모델 뷰 행렬의 역 전치 (normal matrix라고도 함)에 의해 변환됩니다.

관련 문제