/ / Problemas de mapeamento normal do OpenGL - Normais possivelmente enfrentando direção errada? - c ++, opengl, glsl, normais

Problemas de mapeamento normal OpenGL - Normals possivelmente enfrentando direção errada? - c ++, opengl, glsl, normals

Atualmente, estou trabalhando no meu primeiro mecanismo de jogo baseado em OpenGL. Preciso de mapeamento normal como um recurso, mas ele não está funcionando corretamente.

Aqui está uma animação do que está acontecendo

Os artefatos são afetados pelo ângulo entrea luz e os normais na superfície. O movimento da câmera não afeta de forma alguma. Também estou (pelo menos por enquanto) seguindo a rota do método menos eficiente em que o normal extraído do mapa normal é convertido em espaço de visualização em vez de converter tudo em espaço tangente.

Aqui estão as partes relevantes do meu código:

Gerando tangentes e bitangentes

        for(int k=0;k<(int)mb->getIndexCount();k+=3)
{
unsigned int i1 = mb->getIndex(k);
unsigned int i2 = mb->getIndex(k+1);
unsigned int i3 = mb->getIndex(k+2);

JGE_v3f v0 = mb->getVertexPosition(i1);
JGE_v3f v1 = mb->getVertexPosition(i2);
JGE_v3f v2 = mb->getVertexPosition(i3);

JGE_v2f uv0 = mb->getVertexUV(i1);
JGE_v2f uv1 = mb->getVertexUV(i2);
JGE_v2f uv2 = mb->getVertexUV(i3);

JGE_v3f deltaPos1 = v1-v0;
JGE_v3f deltaPos2 = v2-v0;
JGE_v2f deltaUV1 = uv1-uv0;
JGE_v2f deltaUV2 = uv2-uv0;

float ur = deltaUV1.x * deltaUV2.y - deltaUV1.y * deltaUV2.x;

if(ur != 0)
{
float r = 1.0 / ur;

JGE_v3f tangent;
JGE_v3f bitangent;

tangent = ((deltaPos1 * deltaUV2.y) - (deltaPos2 * deltaUV1.y)) * r;
tangent.normalize();

bitangent = ((deltaPos1 * -deltaUV2.x) + (deltaPos2 * deltaUV1.x)) * r;
bitangent.normalize();

tans[i1] += tangent;
tans[i2] += tangent;
tans[i3] += tangent;
btans[i1] += bitangent;
btans[i2] += bitangent;
btans[i3] += bitangent;
}
}

Aqui está uma foto das tangentes

Cálculo da matriz TBN no Vertex Shader (mNormal corrige o normal para escalas não uniformes)

vec3 T = normalize((mVW * vec4(tangent, 0.0)).xyz);
tnormal = normalize((mNormal * n).xyz);
vec3 B = normalize((mVW * vec4(bitangent, 0.0)).xyz);

tmTBN = transpose(mat3(
T.x, B.x, tnormal.x,
T.y, B.y, tnormal.y,
T.z, B.z, tnormal.z));

Finalmente, aqui é onde eu uso o normal amostrado do mapa normal e tento convertê-lo para visualizar o espaço no Fragment Shader

fnormal = normalize(nmapcolor.xyz * 2.0 - 1.0);
fnormal = normalize(tmTBN * fnormal);

"nmapcolor" é a cor da amostra do mapa normal. "normal" é então usado como normal nos cálculos de iluminação.

Eu tenho tentado resolver isso por tanto tempo e não tenho absolutamente nenhuma idéia de como fazer isso funcionar. Qualquer ajuda seria muito apreciada.

EDIT - Modifiquei levemente o código para trabalhar no espaço mundial e produzi os resultados. A plataforma grande não possui mapeamento normal (e funciona corretamente) enquanto a plataforma menor possui. Normais do Espaço Mundial

Eu adicionei em que direção os normais estão enfrentando. Ambos devem ser geralmente da mesma cor, mas "são claramente diferentes. Parece que a matriz mTBN não está transformando o espaço tangente normal no espaço do mundo (e normalmente visualiza) adequadamente.

Respostas:

0 para resposta № 1

Bem ... eu resolvi o problema. Acontece que minha implementação de mapeamento normal foi perfeita. O problema estava na minha aula de texturas. Esta é, obviamente, a primeira vez que escrevi um mecanismo de renderização OpenGL, e não percebi que a função unlock () na minha classe de textura salvou TODAS minhas texturas como GL_SRGB_ALPHA, incluindo mapas normais. Somente texturas difusas do mapa devem ser GL_SRGB_ALPHA. Forçar temporariamente o carregamento de todas as texturas, conforme GL_RGBA corrigiu o problema. Não posso acreditar que tive esse problema por 11 meses, apenas para descobrir que era algo tão pequeno.