Problemas de sombreado de Opengl: artefactos extraños de reflexión de luz.

He estado luchando con esto durante días. Creo que finalmente lo networkingujo a un problema con las tangentes per vértice, pero no estoy seguro de la mejor manera de solucionarlo.

El context es la aplicación de iPhone, opengl es2 usando mi propio motor. Mi sombreador es una variedad de map de baches (map normal) que utiliza la tangente por vértice suministrada para crear una matriz de TBN. El sombreador de vértices transforma los vectores de luz y los vectores de ojo en espacio tangente, los pasa al fragment sombreador y calcula las luces. Pero alguna geometry en mis primeros dos models de testing muestra artefactos extraños en la iluminación. Es más fácil de ver en el componente especular.

Al tratar de depurar esto, he reemplazado el map normal con un png plano normal … todos los píxeles son 128.128.255. También codificé el color duro.

Mi primer model es una forma de button. Muestra el artefacto como un golpe especular festoneado en el anillo exterior. Es importante tener en count que el método de mapeo UV aquí fue 'plano' para hacer que los lados que son perpendiculares a la cartografía básicamente rayan la textura a través de allí. Creo que esto haría que las tangentes sean difíciles de calcular para esa geometry ya que dos de los puntos tendrían exactamente la misma coorderada de textura.

Intenté depurar renderiza la configuration de gl_FragColor para diferentes variables. Cuando lo configura en las normales de vértice vemos que la festoneada se ha ido, lo que indica que las normales son correctas. Pero cuando lo establece en las tangentes per vértice, puede ver la vieira.

introduzca la descripción de la imagen aquí

La siguiente forma es una esfera simple. Con él, la parte superior e inferior del model es donde se muestra el artefacto. En el wireframe verá que aquí es donde se encuentran varios triangularjs en un vértice. No puedo concentrarme en lo que significa para las tangentes, ya que cada triángulo tiene maps UV completamente diferentes allí.

Supongo que obtendré un montón de flack si no muestro el código de sombreado …

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; 

Al tratar de descubrir el sombreador y mirar todas las muestras y tutoriales en línea, pude encontrar … Estaba confundido por el hecho de que los sombreadores de maps de golpes no solo perturbaran el map normal proporcionado por el model 3D. Supongo que sin algún tipo de punto de reference, ¿cómo sabes CÓMO modificar el model normal? ¿Por que orientación? Supongo que para eso es la matriz de TBN. Pero en mi testing por encima del vector normal en el map normal es 0,0,1 – directamente hacia arriba. Por lo tanto, parece que no debería modificarse en absoluto. Cualquier cosa por 1 sigue siendo 1. Pero debe haber algo bastante jodido en las matemáticas o en la matriz de TBN que no venga con la misma normalidad que en el model 3D. Entonces esa idea golpeó algo conmigo … que en mi sombreador de vértices primero también estoy multiplicando el vértice normal por la matriz normal para meterlo en el espacio model. Pero, una vez más, esos renders de debugging son del vértice normal antes de transformarse.

¿Hay otro método para perturbar la normalidad del model sin usar una matriz TBN? La representación con un phong shader sin el map normal no muestra el artefacto.

ACTUALIZACIÓN: Estoy casi seguro de que el problema es las tangentes precalculadas creadas por la aplicación importadora. Después de probar diferentes models con diferentes maps UV, estoy encontrando problemas parecidos, a veces es una oscuridad en lugar de un punto culminante. Entonces, a less que pueda aplicar un map normal sin una matriz TBM o convertir a un espacio tangente, necesitaré encontrar otro importador.

ACTUALIZACIÓN # 2: Acabo de encontrar esta otra pregunta que parece que podría ser una pista del problema real. Gráficos en 3D, vectores unitarios y matrices ortogonales.

Es importante tener en count que estas luces extrañas no suceden en los vértices sino solo entre ellos. Incluso en la esfera estamos viendo un anillo que está entre el vértice superior y los que están justo debajo de él. Estoy empezando a creer que este es un problema de interpolación. Toma solo uno de esos triangularjs:

introduzca la descripción de la imagen aquí

Ignora el mal bitangente por una segunda causa. Estoy volviendo a calcularlo. Pero las tangentes tienen polaridad opuesta. Entonces, mientras estás interpolado entre esos dos estados, vas a get vectores que apunten por todas partes.

La nueva pregunta es ¿cómo lo resuelvo? ¿Arreglando las tangentes? ¿Arreglando el sombreador para lidiar con eso?

A veces la respuesta más simple es la correcta. Las tangentes eran malas. No eran ortogonales a lo normal.

Recalculé manualmente todas las tangentes y bitangentes utilizando los methods descritos aquí:

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

Y ese problema desapareció.