Problèmes de shaders Opengl – artefacts de reflection de lumière étranges

J'ai lutté avec ça pendant des jours. Je pense que j'ai finalement réduit à un problème avec les tangentes par vertex, mais je ne suis pas sûr de la meilleure façon de le réparer.

Le context est l'application iPhone, opengl es2 en utilisant mon propre moteur. Mon shader est une variété de carte de relief (carte normale) utilisant la tangente vertex fournie pour créer une masortingce TBN. Le vertex shader transforme les vectors lumineux et les vectors oculaires en espace tangent, les transmet au fragment shader et calcule les lumières. Mais une certaine geometry dans mes deux premiers templates de test montre des artefacts étranges dans l'éclairage. C'est le plus facile à voir dans la composante spéculaire.

En essayant de déboguer cela, j'ai remplacé la carte normale par un png plat normal. Tous les pixels sont 128,128,255. J'ai aussi codé en dur la couleur.

Mon premier model est une forme de button. Il montre l'artefact comme un coup spéculaire festonné sur l'anneau extérieur. Il est important de noter que la méthode de cartographie UV ici était «plate» pour que les côtés qui sont perpendiculaires à la cartographie ssortingent fondamentalement la texture. Je pense que cela rendrait les tangentes difficiles à calculer pour cette geometry puisque deux des points auraient la même coordonnée de texture.

J'ai essayé les rendus de debugging en définissant gl_FragColor à différentes variables. En le fixant aux normales par vertex, nous voyons que le scalloping est parti, indiquant que les normales sont correctes. Mais en le réglant sur les tangentes par vertex, vous pouvez voir le pétoncle.

entrez la description de l'image ici

La forme suivante est une sphère simple. Avec elle le tout en haut et en bas du model est où l'artefact montre. Dans le fil de fer, vous verrez que c'est là que plusieurs sortingangles se rencontrent à un sumt. Je ne peux pas comprendre ce que cela signifie pour les tangentes car chaque sortingangle a une cartographie UV complètement différente.

Je suppose que je vais avoir beaucoup de flack si je ne montre pas le code shader …

Vertex Shader:

v_fragmentTexCoord0 = a_vertexTexCoord0; gl_Position = u_modelViewProjectionMasortingx * vec4(a_vertexPosition,1.0); vec3 normal = normalize(u_normalMasortingx * a_vertexNormal); vec3 tangent = normalize(u_normalMasortingx * a_vertexTangent); vec3 bitangent = cross(normal, tangent); mat3 TBNMasortingx = mat3(tangent, bitangent, normal); v_eyeVec = -a_vertexPosition.xyz; v_eyeVec *= TBNMasortingx; v_lightVec = u_lightPosition - a_vertexPosition.xyz; v_lightVec *= TBNMasortingx; 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; 

En essayant de comprendre le shader et en regardant tous les exemples et tutoriels en ligne, j'ai pu find … J'étais confus par la raison pour laquelle les shaders de bump map ne perturberaient pas la carte normale fournie par le model 3D. Je suppose que sans une sorte de sharepoint reference comment vous savez comment modifier la normale du model? Par quelle orientation? Je suppose que c'est à ça que sert la masortingce TBN. Mais dans mon test au-dessus du vector normal dans la carte normale est 0,0,1 – tout droit. Il semble donc que cela ne devrait pas du tout être modifié. Quelque chose fois 1 est toujours 1. Mais il doit y avoir quelque chose de foutu assez dans les maths ou dans la masortingce TBN que ça n'arrive pas avec la même normale que celle du model 3d. Alors cette idée a frappé quelque chose avec moi .. que dans mon vertex shader je multiplie d'abord le vertex normal par le normalMasortingx pour le faire entrer dans l'espace modélisé. Mais encore une fois, ces rendus de debugging sont du vertex normal avant d'être transformé.

Existe-t-il une autre méthode pour perturber la normale du model sans utiliser de masortingce TBN? Rendu avec un shader phong sans la carte normale ne montre pas l'artefact.

MISE À JOUR: Je suis presque certain que le problème est les tangentes précalculées créées par l'application d'import. Après avoir essayé différents templates avec différentes maps UV, je trouve des problèmes d'apparence similaire, parfois c'est une obscurité plutôt qu'un point culminant. Donc, sauf si je peux appliquer une carte normale sans masortingce TBM ou convertir en espace tangent, je vais devoir find un autre importateur.

UPDATE # 2: Je viens de find cette autre question qui semble être un indice du vrai problème. Graphiques 3D, vectors unitaires et masortingces orthogonales

Il est important de noter que ces lumières étranges ne se produisent pas sur les sumts mais seulement entre eux. Même sur la sphère, nous voyons une bague qui se trouve entre le sumt supérieur et ceux juste en dessous. Je commence à croire que c'est un problème d'interpolation. Prenez juste un de ces sortingangles là-haut:

entrez la description de l'image ici

Ignorer le mauvais bitangent pour une seconde cause Je recalcule ça. Mais les tangentes ont une polarité opposée. Donc, tout en étant interpolé entre ces deux états, vous allez get des vectors qui pointent partout.

La nouvelle question est comment puis-je le résoudre? Fixer les tangentes? Fixer le shader pour y faire face?

Parfois, la réponse la plus simple est la bonne. Les tangentes étaient mauvaises. Ils n'étaient pas orthogonaux à la normale.

J'ai recalculé manuellement toutes les tangentes et les bitangents en utilisant les methods décrites ici:

http://www.terathon.com/code/tangent.html

Et ce problème est parti.