Параллакс картографический глюк в OpenGL - PullRequest
4 голосов
/ 20 января 2011

alt text alt text

И это результат, когда я инвертирую касательный вектор сразу после передачи его в вершинный шейдер:

alt text alt text

«Тень» находится не в том месте.

(И это работает только тогда, когда я поворачиваю его по оси Y, так что последнее изображение, кажется, представляет хороший куб с параллаксом)

Я уверен, что это не TANGENT VECTOR ИЛИ ТЕКСТУРА КООРДИНАТЫ ПРОБЛЕМА

Из

Я использовал точно такие же функции вычисления тангенса и точно такие же позиции куба, данные нормали и координаты текстуры , как в рабочей демонстрации. В конце концов, я экспортировал массивы с данными position / texcoord / normal / tangent в файл .txt и увидел, что именно ожидал (и я ожидал, что это те же данные pos / tex / norm, что и в рабочей демонстрации, включая вычисленные касательные, которые Мне удалось экспортировать с рабочего демо).

Следующий аргумент - я скопировал свой код шейдера в рабочую демонстрацию, и он все еще работает . Другой, я пробовал несколько способов визуализации этого куба. Я пробовал VBO с glVertexAttribPointer, я пробовал VBO с сохранением тангенса в качестве другой координаты текстуры (как в демо), я пробовал DisplayList с glVertexAttrib4f. Результат ... Точно такой же.

Карта высоты загружается правильно, я попытался установить ее как диффузную карту, и она выглядела нормально. glGetError () не выдаёт мне ошибок, а логи компиляции шейдеров говорят так.

Возможно, это что-то с камерой или состояниями инициализации.

Возможно, размещение кода инициализации поможет.

void CDepthBase::OpenGLSet() {

    glEnable( GL_TEXTURE_2D );
    glShadeModel( GL_SMOOTH );
    glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
    glClearDepth( 1.0f );
 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glDepthFunc( GL_LEQUAL );
    glEnable(GL_DEPTH_TEST);



    glBlendFunc( GL_ONE, GL_ONE );
    GLfloat ratio;

    glViewport(0, 0, ResolutionWidth, ResolutionHeight);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45.0f, ResolutionWidth / (float)ResolutionHeight, 0.1f, 900.0f);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    if (GLEW_OK != glewInit()) {
        MBX("Failed to init GLEW.", "Error");
    }
    if (glewIsSupported("GL_ARB_vertex_buffer_object")) {
        VBO_supported = true;


    } else VBO_supported = false;

 glHint( GL_FOG_HINT, GL_DONT_CARE );      
    glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
 glShadeModel(GL_SMOOTH);

    glAlphaFunc(GL_ALWAYS, 0);
}

Кстати, я использую GL Extension Wrangler с расширениями.

Код и журнал шейдера (этот экспортированный файл содержит код, который был напрямую передан glShaderSource):

Vertex shader was successfully compiled to run on hardware.


Fragment shader was successfully compiled to run on hardware.

Fragment shader(s) linked, vertex shader(s) linked. 


------------------------------------------------------------------------------------------


 varying vec3 lightDir;                                          
 varying vec3 viewDir;
 attribute vec4 tangent;
 void main() 
 { 
 gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
 gl_TexCoord[0] = gl_MultiTexCoord0;
 vec3 vertexPos = vec3(gl_ModelViewMatrix * gl_Vertex);
 vec3 tn = tangent.xyz;             
 vec3 n = normalize(gl_NormalMatrix * gl_Normal);
 vec3 t = normalize(gl_NormalMatrix * tangent.xyz);
 vec3 b = cross(t, n) * -tangent.w;
 mat3 tbnMatrix = mat3(t.x, b.x, n.x,
                       t.y, b.y, n.y,
                       t.z, b.z, n.z);
 lightDir = (gl_LightSource[0].position.xyz - vertexPos) / 100.0;
 lightDir = tbnMatrix * lightDir;
 viewDir = -vertexPos;
 viewDir = tbnMatrix * viewDir;
 } 

-----------------------------------------------------------------------------------------
 varying vec3 lightDir;                                          
 varying vec3 viewDir;
 uniform sampler2D diffuseMap;
 uniform sampler2D normalMap;
 uniform sampler2D heightMap;
 uniform float scale;
 uniform float bias;
 void main() 
 { 
 vec3 v = normalize(viewDir);
 vec2 TexCoord = gl_TexCoord[0].st;
{
 float height = texture2D(heightMap, gl_TexCoord[0].st).r;
 height = height * scale + bias;
 TexCoord = gl_TexCoord[0].st + (height * v.xy); 
}
 vec3 l = lightDir;
 float atten = max(0.0, 1.0 - dot(l, l));
 l = normalize(l);
 vec3 n = normalize(texture2D(normalMap, TexCoord).rgb * 2.0 - 1.0);
 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 = gl_FrontLightProduct[0].ambient * atten;
 vec4 diffuse = gl_FrontLightProduct[0].diffuse * nDotL * atten;
 vec4 specular = gl_FrontLightProduct[0].specular * power * atten;
 vec4 color = gl_FrontLightModelProduct.sceneColor + ambient + diffuse + specular;color *= texture2D(diffuseMap,TexCoord);
 gl_FragColor = color ;
 } 

Униформы работают правильно, потому что результаты одинаковы, если я переключаю их с постоянными значениями. Компиляция шейдера:

void __Shader::import(){
    if(imported) __Shader::~__Shader();

        v = glCreateShader(GL_VERTEX_SHADER);
        f = glCreateShader(GL_FRAGMENT_SHADER); 


        glShaderSource(v, 1, (const GLchar **)&vsrc.cstr,NULL);
        glShaderSource(f, 1, (const GLchar **)&fsrc.cstr,NULL);

        glCompileShader(v);
        glCompileShader(f);

        p = glCreateProgram();

        glAttachShader(p,v);
        glAttachShader(p,f);

        if(_flags & NORMAL_MAPPING) 
            glBindAttribLocation(p, ATTRIB_TANGENT, "tangent");

        glLinkProgram(p);

        if(_flags & DIFFUSE_MAPPING) 
            diffuseUni.loc = glGetUniformLocation(p, "diffuseMap");
        if(_flags & NORMAL_MAPPING) 
            normalUni.loc = glGetUniformLocation(p, "normalMap");
        if(_flags & PARALLAX_MAPPING) 
            heightUni.loc = glGetUniformLocation(p, "heightMap");
        if(_flags & SPECULAR_MAPPING) 
            specularUni.loc = glGetUniformLocation(p, "specularMap");

        imported = true;
}

Установка атрибута в VBO:

    if(tangents.size() > 0){
        buffered |= 3;
        glGenBuffers(1, &VBO_tangent);
        glBindBuffer(GL_ARRAY_BUFFER, VBO_tangent);
        glBufferData(GL_ARRAY_BUFFER, tangents.size()*sizeof(tangent), tangents.get_ptr(), GL_STATIC_DRAW);
    }

// and in draw:

if(buffered & 3) {

        glBindBuffer(GL_ARRAY_BUFFER, VBO_tangent);    
        glVertexAttribPointer(__Shader::ATTRIB_TANGENT, 4, GL_FLOAT, GL_FALSE, 0, 0);   
        glEnableVertexAttribArray(__Shader::ATTRIB_TANGENT);  
    }

и небольшая заметка

for(int i = 0; i < responders.size(); ++i)
if(strstr(responders[i].idea, "tangent problem"))
responders[i].please_dont_talk();

Просто расскажите мне ваши другие идеи о том, что может быть причиной этих плохих результатов.

1 Ответ

5 голосов
/ 21 января 2011

Вот так ... уже решил это.Проблема была с загрузкой текстурных файлов, хотя я не видел никаких проблем с диффузным отображением или даже с диффузным + нормальным отображением.Я использовал IMG_Load из SDL, возможно, я использовал его неправильно, но у меня это не сработало.Вероятно, это была нормальная карта испорчена.

плохой код импорта текстуры:

if(imported || filenamez.length() < 1) return;
    SDL_Surface* surface = 0;


        surface = IMG_Load(filenamez.c_str());

    if (surface) { 
        glGenTextures(1, &texture);
        glBindTexture(GL_TEXTURE_2D, texture);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    bool endianess = filenamez.substr(filenamez.length()-4) == ".jpg";
        glTexImage2D(GL_TEXTURE_2D, 0, 3, surface->w, surface->h, 0, 
            (endianess ? GL_RGB : GL_BGR), GL_UNSIGNED_BYTE, surface->pixels);

    }

ОСТОРОЖНО!

Я сейчас использую загрузку текстур на основе HBITMAP, взятую из демонстрации dhpowareо котором я говорил.И это прекрасно работает.

мир.

После 2-3 дней тяжелой отладки позвольте мне почувствовать небольшую эйфорию.

ОЯ бы забыл, окончательный результат: alt text

...