Проблемы с шейдером нормальных карт GLSL - PullRequest
0 голосов
/ 05 декабря 2011

VC ++ 2010, OpenGL, GLSL, SDL

Так что у меня две основные проблемы.Я надеюсь в первую очередь решить эту проблему: шейдер карты норм, который я использую, не работает с нормалями, которые указывают в положительном или отрицательном направлении х.z и y работают нормально (тестирование текстуры и нормалей на кубе).

edit : Кажется, что это не нормали в направлении x, потому что когда я поворачиваюгеометрия, фронтальный четырехугольник все еще будет работать.Так что кажется, что то, что было изначально ориентировано на x, не работает.

Вот несколько простых тестовых геометрий:

glBegin(GL_QUADS);
    glNormal3f(0.0f, 0.0f, 1.0f);
    glTexCoord2f(0.0, 0.0); glVertex3f(-1.0f, 0.0f, 1.0f);
    glTexCoord2f(0.0, 1.0); glVertex3f(-1.0f, 2.0f, 1.0f);
    glTexCoord2f(1.0, 1.0); glVertex3f(1.0f, 2.0f, 1.0f);
    glTexCoord2f(1.0, 0.0); glVertex3f(1.0f, 0.0f, 1.0f);
glEnd();
glBegin(GL_QUADS);
    glNormal3f(-1.0f, 0.0f, 0.0f);
    glTexCoord2f(0.0, 0.0); glVertex3f(-1.0f, 0.0f, 1.0f);
    glTexCoord2f(0.0, 1.0); glVertex3f(-1.0f, 2.0f, 1.0f);
    glTexCoord2f(1.0, 1.0); glVertex3f(-1.0f, 2.0f, -1.0f);
    glTexCoord2f(1.0, 0.0); glVertex3f(-1.0f, 0.0f, -1.0f);
glEnd();

Vertex Shader

#define MAX_LIGHTS 8
#define NUM_LIGHTS 1

varying vec3 lightVec[MAX_LIGHTS];
varying vec3 viewVec;

attribute vec4 glTangent4f;

void main(void)
{
    gl_Position = ftransform();
    gl_TexCoord[0] = gl_MultiTexCoord0;

    vec3 n = normalize(gl_NormalMatrix * gl_Normal);
    vec3 t = normalize(gl_NormalMatrix * glTangent4f.xyz);
    vec3 b = cross(n, t);

    vec3 v;
    vec3 vVertex = vec3(gl_ModelViewMatrix * gl_Vertex);
    int i;
    for (i=0; i<NUM_LIGHTS; ++i)
    {
        vec3 lVec = gl_LightSource[i].position.xyz - vVertex;
        v.x = dot(lVec, t);
        v.y = dot(lVec, b);
        v.z = dot(lVec, n);
        lightVec[i] = v;
    }

    vec3 vVec = -vVertex;
    v.x = dot(vVec, t);
    v.y = dot(vVec, b);
    v.z = dot(vVec, n);
    viewVec = v;
}

Фрагмент шейдера

#define MAX_LIGHTS 8
#define NUM_LIGHTS 1

varying vec3 lightVec[MAX_LIGHTS];
varying vec3 viewVec;

uniform sampler2D colorMap;
uniform sampler2D normalMap;

void main (void)
{
    vec2 uv = gl_TexCoord[0].st * 4.0;
    vec4 base = texture2D(colorMap, uv);
    vec4 final_color = vec4(0.2, 0.2, 0.2, 1.0) * base;
    vec3 vVec = normalize(viewVec);
    vec3 bump = normalize(texture2D(normalMap, uv).xyz * 2.0 - 1.0);
    vec3 R = reflect(-vVec, bump);

    int i;
    for (i=0; i<NUM_LIGHTS; ++i)
    {
        vec3 lVec = normalize(lightVec[i]);
        float diffuse = max(dot(lVec, bump), 0.0);
        vec4 vDiffuse = gl_FrontLightProduct[i].diffuse * diffuse * base;
        final_color += vDiffuse;

        float specular = pow(clamp(dot(R, lVec), 0.0, 1.0), gl_FrontMaterial.shininess);
        vec4 vSpecular = gl_FrontLightProduct[i].specular * specular * diffuse;
        final_color += vSpecular;
    }

    gl_FragColor = final_color;
}

Другая проблема (к которой я не обязательно должен обращаться прямо сейчас) состоит в том, что зеркальный свет направленного света, похоже, следует за камерой

Ответы [ 2 ]

2 голосов
/ 05 декабря 2011
attribute vec4 glTangent4f;

Где вы на самом деле предоставляете это значение?Это атрибут вершины, но ваш код рендеринга, похоже, ничего не предоставляет.

0 голосов
/ 01 октября 2012

«Как мне передать эту касательную поверхности программе?»

Вы рассчитали касательную для вашего объекта? Я помню, что объекты волнового фронта обычно не включают данные касательных вершин, и в этом случае вам необходимо вычислить базис касательных после анализа данных волнового фронта. Судя по внешнему виду вашего кода, вы, похоже, не имеете никаких касательных данных.

Вы также можете сделать касательное приближение в вершинном шейдере, просто используя нормаль.

На самом деле я не знаю, как бы вы передавали свои данные касательных в программу, потому что вы не используете VBO.

EDIT:

Теперь я вижу, что сделал идиотское предположение, что вы загружаете свои данные из трехмерного формата файла, которым вы не являетесь, но вам все равно нужно где-то вычислить касательную.

...