GLSL Normal Mapping (Области с 0,0 Ламберта Горит)
Когда я использую модель в норме, результат будет хорошим (есть темные и светлые области, как я и ожидал от простого диффузного шейдера Ламберта)
но когда я использую карту нормалей, темные области освещаются!
я хочу использовать карту нормалей и по-прежнему получать правильное рассеянное освещение, как в этих примерах
вот код с и без нормального отображения
и вот код, который использует карту нормалей
Вершинный шейдер
varying vec3 normal,lightDir;
attribute vec3 vertex,normalVec,tangent;
attribute vec2 UV;
void main(){
gl_TexCoord[0] = gl_TextureMatrix[0] * vec4(UV,0.0,0.0);
normal = normalize (gl_NormalMatrix * normalVec);
vec3 t = normalize (gl_NormalMatrix * tangent);
vec3 b = cross (normal, t);
vec3 vertexPosition = normalize(vec3(gl_ModelViewMatrix * vec4(vertex,1.0)));
vec3 v;
v.x = dot (lightDir, t);
v.y = dot (lightDir, b);
v.z = dot (lightDir, normal);
lightDir = normalize (v);
lightDir = normalize(vec3(1.0,0.5,1.0) - vertexPosition);
gl_Position = gl_ModelViewProjectionMatrix*vec4(vertex,1.0);
}
Фрагмент шейдера
vec4 computeDiffuseLight (const in vec3 direction, const in vec4 lightcolor, const in vec3 normal, const in vec4 mydiffuse){
float nDotL = dot(normal, direction);
vec4 lambert = mydiffuse * lightcolor * max (nDotL, 0.0);
return lambert;
}
varying vec3 normal,lightDir;
uniform sampler2D textures[8];
void main(){
vec3 normalVector = normalize( 2 * texture2D(textures[0],gl_TexCoord[0].st).rgb - 1 );
vec4 diffuse = computeDiffuseLight (lightDir, vec4(1,1,1,1) , normalVector, vec4(0.7,0.7,0.7,0));
gl_FragColor = diffuse ;
}
Примечание: фактическое отображение нормалей работает правильно, как видно на зеркальных бликах
Я использовал Assimp для загрузки модели (md5mesh) и вычислял касательные, используя Assimp, а затем отправил его шейдерам в качестве атрибута
вот ссылка на код и скриншоты проблемы
https://dl.dropboxusercontent.com/u/32670019/code%20and%20screenshots.zip
это проблема в коде или у меня неправильное представление?
Обновлен код и скриншоты
https://dl.dropboxusercontent.com/u/32670019/updated%20code%20and%20screenshots.zip
теперь карта нормалей работает с диффузной, но только диффузная некорректна
1 ответ
Ответ см. Ниже.
Быстрое (возможно, неправильное) наблюдение: линия
vec3 normalVector = normalize( 2 * texture2D(textures[0],gl_TexCoord[0].st).rgb - 1 );
в вашем фрагментном шейдере правильно масштабируется ваш нормальный, чтобы учесть отрицательные значения. Если ваша карта нормалей неверна, отрицательные значения могут появиться там, где вы их не хотите (я полагаю, ваша ось Y). Отрицательные значения в нормале могут привести к изменению освещения.
Мой вопрос к вам: ваша карта нормальна?
ОТВЕТ: После небольшого обсуждения мы нашли проблему, я отредактировал этот пост, чтобы сохранить ветку в чистоте, решение проблем Дарко находится в комментариях здесь. Дело дошло до неинициализированного варьирования, называемого lightDir.
Оригинальный комментарий:
lightDir = нормализовать (v); lightDir = normalize(vec3(1.0,0.5,1.0) - vertexPosition); Это странно, вы мгновенно перезаписываете, это неправильно? Вы, кажется, не сохраняете правильно переведенный lightDir... Или я сумасшедший... Кроме того, этот lightDir варьируется, но вы его вообще не устанавливаете. Таким образом, вы рассчитываете av вектор из ничего?