Неправильное освещение в картах нормалей - PullRequest
2 голосов
/ 19 февраля 2012

У меня есть карта нормалей в игровом движке OpenGL, и я понял, что мой шейдер карт нормалей (и шейдер карт параллакса в этом отношении) имеет проблемы с освещением. Независимо от того, где находится свет, он всегда исходит справа. Я использую касательный пространственный шейдер, и я не уверен, что то, что я передаю, правильно.

Это карта нормалей, которую я использую: The Normal Map I am using

А вот рендер:

Rendered Image

Похоже, что свет исходит от координаты 3,0,3, но его фактическое местоположение составляет -3,0,3

Любые идеи.

Шейдеры:

[верт]

attribute vec3 intan;

varying vec3 lightDir;
varying vec3 viewDir;

void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_TexCoord[0] = gl_MultiTexCoord0;

vec3 vertexPos = vec3(gl_ModelViewMatrix * gl_Vertex);

vec3 n = normalize(gl_NormalMatrix * gl_Normal);
vec3 t = normalize(gl_NormalMatrix * intan);
vec3 b = cross(n, t) ;

mat3 tbnMatrix = mat3(t.x, b.x, n.x,
                      t.y, b.y, n.y,
                      t.z, b.z, n.z);

lightDir = (gl_LightSource[1].position.xyz - vertexPos) / 1000.;
lightDir = tbnMatrix * lightDir;

viewDir = -vertexPos;
    //viewDir = 
viewDir = tbnMatrix * viewDir;
}

[осколочная]

uniform sampler2D tex;
uniform sampler2D nor;

varying vec3 lightDir;
varying vec3 viewDir;

const vec4 d = vec4(0.19225,0.19225,0.19225,1.0);
const vec4 a = vec4(0.50754,0.50754,0.50754,1.0);
const vec4 s = vec4(0.508273,0.508273,0.508273,1.0);

void main()
{
vec3 l = lightDir;
float atten = max(0.0, 1.0 - dot(l, l));

l = normalize(l);

vec3 n = normalize(texture2D(nor, gl_TexCoord[0].st).xyz * 2.0 - 1.0);
vec3 v = normalize(viewDir);
vec3 h = normalize(l + v);

float nDotL = max(0.0, dot(n, l));
float nDotH = max(0.0, dot(n, h));
float power = (nDotL == 0.0) ? 0.0 : pow(nDotH, gl_FrontMaterial.shininess);

vec4 ambient = a * atten;
vec4 diffuse = d * nDotL * atten;
vec4 specular = s * power * atten;
vec4 color = ambient + diffuse + specular;

gl_FragColor = color * texture2D(tex, gl_TexCoord[0].st);
}

1 Ответ

0 голосов
/ 19 февраля 2012
vec3 n = normalize(gl_NormalMatrix * gl_Normal);
vec3 t = normalize(gl_NormalMatrix * intan);
vec3 b = cross(n, t) ;

Полагаю, intan обозначает направление, в котором карта нормалей указывает "вправо". Тогда этот перекрестный продукт неправильный. Если n указывает на поверхность и интан вправо, то b (неформально) указывает вниз.

Обратите внимание, что нет никакой разницы, если вы преобразуете нормаль и касательную, а затем создаете перекрестный продукт результата или сначала делаете перекрестный продукт и преобразовываете результат.

lightDir = (gl_LightSource [1] .position.xyz - vertexPos) / 1000.;

Почему бы вам просто не нормализовать это? Это деление на 1000 не имеет смысла.

...