Ho lottato con questo per giorni. Penso di averlo finalmente ridotto a un problema con le tangenti per vertice, ma non sono sicuro che sia il modo migliore per risolverlo.Problemi di shader Opengl - strani artefatti di riflessione della luce
Il contesto è l'app per iPhone, utilizza il mio motore. Il mio shader è una varietà di mappe bump (mappa normale) usando la tangente per vertice fornita per creare una matrice TBN. Il vertex shader trasforma i vettori della luce e i vettori dell'occhio in uno spazio tangente, li passa allo shader dei frammenti e calcola le luci. Ma alcune geometrie nei miei primi due modelli di test mostrano strani artefatti nell'illuminazione. È più facile vedere nel componente speculare.
Nel tentativo di eseguire il debug di questo ho sostituito la normale mappa con una normale png piatta .. tutti i pixel sono 128,128,255. Ho anche hard codificato il colore.
Il mio primo modello è una forma a pulsante. Mostra l'artefatto come un colpo speculare smerlato sull'anello esterno. È importante notare che il metodo di mappatura UV qui era 'piatto' per rendere i lati che sono perpendicolari alla mappatura fondamentalmente strisciare la trama attraverso là. Penserei che questo renderebbe le tangenti difficili da calcolare per quella geometria poiché due dei punti avrebbero esattamente la stessa coordinata della trama.
Ho provato il debug rende l'impostazione di gl_FragColor a variabili diverse. Quando lo impostiamo sulle normali per per- vertice vediamo che la smerlatura è sparita, indicando che le normali sono corrette. Ma quando lo si imposta alle tangenti per vertice, è possibile vedere la scaloppina.
La forma prossimo è una sfera semplice. Con esso la parte superiore e inferiore del modello è dove mostra l'artefatto. Nel wireframe vedrai che questo è dove diversi triangoli si incontrano in un vertice. Non riesco a capire cosa significhi per le tangenti dato che ogni triangolo ha una mappatura UV completamente diversa.
Suppongo che prendo un sacco di Flack, se non mi presento il codice dello shader ...
Vertex Shader:
v_fragmentTexCoord0 = a_vertexTexCoord0;
gl_Position = u_modelViewProjectionMatrix * vec4(a_vertexPosition,1.0);
vec3 normal = normalize(u_normalMatrix * a_vertexNormal);
vec3 tangent = normalize(u_normalMatrix * a_vertexTangent);
vec3 bitangent = cross(normal, tangent);
mat3 TBNMatrix = mat3(tangent, bitangent, normal);
v_eyeVec = -a_vertexPosition.xyz;
v_eyeVec *= TBNMatrix;
v_lightVec = u_lightPosition - a_vertexPosition.xyz;
v_lightVec *= TBNMatrix;
v_normal = a_vertexTangent;
Fragment Shader:
vec3 norm = texture2D(u_normalSampler, v_fragmentTexCoord0).rgb * 2.0 - 1.0;
vec4 baseColor = vec4(0.6015625,0.0,0.0,1.0); // is normally texture2D(u_textureSampler,v_fragmentTexCoord0);
float dist = length(v_lightVec);
vec3 lightVector = normalize(v_lightVec);
float nxDir = max(0.0, dot(norm, lightVector));
vec4 diffuse = u_lightColorDiffuse * nxDir;
float specularPower = 0.0;
if(nxDir != 0.0)
{
vec3 cameraVector = v_eyeVec;
vec3 halfVector = normalize(v_lightVec + cameraVector);
float nxHalf = max(0.0,dot(norm, halfVector));
specularPower = pow(nxHalf, u_shininess);
}
vec4 specular = u_lightColorSpecular * specularPower;
gl_FragColor = (diffuse * vec4(baseColor.rgb,1.0)) + specular;
nel tentativo di capire lo shader e guardando tutti i campioni e le esercitazioni online che ho trovato ... sono stato confuso dal perché l'urto mappa shaders non sarebbe solo perturbare la mappa normale fornito dal modello 3D. Immagino senza una sorta di punto di riferimento come sai COME modificare il normale del modello? Con quale orientamento? Immagino che sia per quello che serve la matrice TBN. Ma nel mio test sopra il vettore normale nella mappa normale è 0,0,1 - dritto verso l'alto. Quindi sembra che non dovrebbe essere affatto modificarlo. volte Anything 1 è ancora 1. Ma ci deve essere qualcosa avvitato abbastanza in matematica o nella matrice TBN che non è venuta con la stessa normale, come quella nel modello 3D. Poi quell'idea ha colpito qualcosa con me ... che nel mio vertex shader sto anche prima moltiplicando il vertice normale della normale matrice per farlo entrare nello spazio del modello. Ma poi di nuovo, quei rendering di debug sono del vertice normale prima di essere trasformati.
C'è un altro metodo per perturbare il modello del normale senza l'utilizzo di una matrice TBN? Il rendering con phong shader senza la normale mappa non mostra l'artefatto.
AGGIORNAMENTO: Sono quasi sicuro che il problema sia rappresentato dalle tangenti precalcolate create dall'app di importazione.Dopo aver provato diversi modelli con diverse mappe UV, sto riscontrando problemi di aspetto simile, a volte è un'oscurità invece che un'evidenziazione. Quindi, a meno che non possa applicare una mappa normale senza una matrice TBM o convertendo in spazio tangente, avrò bisogno di trovare un altro importatore.
UPDATE # 2: Ho appena trovato quest'altra domanda che potrebbe essere un indizio del vero problema. 3d graphics, unit vectors and orthogonal matrices
È importante notare che queste luci strane non si verificano sui vertici ma solo tra di loro. Anche sulla sfera stiamo vedendo un anello che si trova tra il vertice superiore e quelli proprio sotto di esso. Sto iniziando a credere che questo sia un problema di interpolazione. Prendere solo uno di quei triangoli lassù:
Ignorare il male bitangent per una seconda causa che sto ricalcolando che. Ma le tangenti hanno polarità opposta. Quindi, mentre sei interpolato tra questi due stati, otterrai dei vettori che puntano dappertutto.
La nuova domanda è come risolverlo? Risolvere le tangenti? Fissare lo shader per affrontarlo?
Perché non passare i vettori normali e tangenti (LERP'd) allo shader dei frammenti e gestire le trasformate TBN lì? Se le normali variano a ogni vertice, otterrai risultati più uniformi con i calcoli per frammento. –
Immagino di essere preoccupato che sarebbe troppo lento. Quando ha la mappa delle texture su di esso e la mappa del bump sembra davvero buona e non te ne accorgi. Se fosse risolvere il problema, lo farei. – badweasel
Non è molto per uno shader, specialmente rispetto al profilo di qualcosa come la funzione 'pow'. Come dici tu, probabilmente non è la fonte del problema. –