/ / Problemi di mappatura normale OpenGL - Normali che si possono eventualmente orientare in direzione sbagliata? - c ++, opengl, glsl, normali

Problemi di mappatura normale di OpenGL - Normali che si possono eventualmente orientare in direzione sbagliata? - c ++, opengl, glsl, normali

Attualmente sto lavorando al mio primo motore di gioco basato su OpenGL. Ho bisogno di una mappatura normale come funzione, ma non funziona correttamente.

Ecco un'animazione di ciò che sta accadendo

Gli artefatti sono influenzati dall'angolo trala luce e le normali sulla superficie. Il movimento della fotocamera non influisce in alcun modo. Anch'io (almeno per ora) sto seguendo il percorso del metodo meno efficiente in cui il normale estratto dalla normale mappa viene convertito in spazio di visualizzazione piuttosto che convertire tutto in spazio tangente.

Ecco i pezzi rilevanti del mio codice:

Generazione di tangenti e bitangenti

        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;
}
}

Ecco una foto delle Tangenti

Calcolo della matrice TBN nel Vertex Shader (mNormal corregge il normale per scale non uniformi)

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 qui è dove utilizzo la normale campionata dalla normale mappa e cerco di convertirla per visualizzare lo spazio in Fragment Shader

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

"nmapcolor" è il colore campionato dalla mappa normale. "Fnormal" viene quindi utilizzato come normale nei calcoli di illuminazione.

Ho cercato di risolvere questo problema per così tanto tempo e non ho assolutamente idea di come farlo funzionare. Qualsiasi aiuto sarebbe molto apprezzato.

EDIT - Ho leggermente modificato il codice per lavorare nello spazio mondiale e ho emesso i risultati. La grande piattaforma non ha una mappatura normale (e funziona correttamente) mentre la piattaforma più piccola lo fa. World Space Normals

Ho aggiunto in che direzione si trovano le normali. Dovrebbero essere entrambi di solito dello stesso colore, ma sono chiaramente diversi: sembra che la matrice mTBN non stia trasformando lo spazio tangente normale in uno spazio del mondo (e normalmente lo vede) correttamente.

risposte:

0 per risposta № 1

Bene ... Ho risolto il problema. Risulta che la mia normale implementazione della mappatura era perfetta. Il problema era in realtà nella mia classe di texture. Questa è, ovviamente, la mia prima volta in cui scrivo un motore di rendering OpenGL e non mi sono reso conto che la funzione unlock () della mia classe texture ha salvato TUTTE le mie trame come GL_SRGB_ALPHA incluse le mappe normali. Solo le trame di mappe diffuse devono essere GL_SRGB_ALPHA. Forzare temporaneamente tutte le trame per caricare come GL_RGBA risolto il problema. Non posso credere che ho avuto questo problema per 11 mesi, solo per scoprire che era qualcosa di così piccolo.