Отправка вектора нормали через vbo в шейдер?

Я пытаюсь отправить нормальный вектор каждой грани моего объекта, но он не делает того, чего я ожидаю. В шейдере я добавил эту строку vec4(normal, 1.) * texture(texture_, coordTexture);, которая должна отображать текстуру без какого-либо освещения (нормальное значение должно быть vec (1., 1., 1.)). Но получаю такой результат:

I am getting the following result

Что означает, что координаты нормального не отправляются.

Генерация вершин:

void Chunck::generate() {
    int width = 1024;
    int height = 1024;

    for (int i = -width / 2.; i <= width / 2.; ++i)
        for (int j = -height / 2.; j <= height / 2.; ++j)
            map_m[i][j] = 50. * std::cos(i * 0.01) + 50. * std::sin(j * 0.01)
                    + std::exp(0.01 * i);

    for (int i = -width / 2.; i < width / 2.; ++i)
        for (int j = -width / 2.; j < height / 2.; ++j) {
            vertices_m.push_back(i);
            vertices_m.push_back(map_m.at(i).at(j));
            vertices_m.push_back(j);

            vertices_m.push_back((i + 1));
            vertices_m.push_back(map_m.at(i + 1).at(j));
            vertices_m.push_back(j);

            vertices_m.push_back((i + 1));
            vertices_m.push_back(map_m.at(i + 1).at(j + 1));
            vertices_m.push_back((j + 1));

            auto normal = getNormal(i, j);

            normals_m.push_back(1.);//normal[0]);
            normals_m.push_back(1.);//normal[1]);
            normals_m.push_back(1.);//normal[2]);

            normals_m.push_back(1.);//normal[0]);
            normals_m.push_back(1.);//normal[1]);
            normals_m.push_back(1.);//normal[2]);

            normals_m.push_back(1.);//normal[0]);
            normals_m.push_back(1.);//normal[1]);
            normals_m.push_back(1.);//normal[2]);

            // Face 2
            vertices_m.push_back(i);
            vertices_m.push_back(map_m.at(i).at(j));
            vertices_m.push_back(j);

            vertices_m.push_back((i + 1));
            vertices_m.push_back(map_m.at(i + 1).at(j + 1));
            vertices_m.push_back((j + 1));

            vertices_m.push_back(i);
            vertices_m.push_back(map_m.at(i).at(j + 1));
            vertices_m.push_back((j + 1));

            normal = getNormal2(i, j);

            normals_m.push_back(1.);//normal[0]);
            normals_m.push_back(1.);//normal[1]);
            normals_m.push_back(1.);//normal[2]);

            normals_m.push_back(1.);//normal[0]);
            normals_m.push_back(1.);//normal[1]);
            normals_m.push_back(1.);//normal[2]);

            normals_m.push_back(1.);//normal[0]);
            normals_m.push_back(1.);//normal[1]);
            normals_m.push_back(1.);//normal[2]);

            std::vector<float> vec =
                    { 0, 0, 1., 0, 1., 1., 0, 0, 0, 1., 1., 1. };
            texture_m.insert(texture_m.end(), vec.begin(), vec.end());

        }
}

Рисунок:

void Chunck::draw() const {

    glBindBuffer(GL_ARRAY_BUFFER, vboID_m);


    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
    glEnableVertexAttribArray(0);

    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(vertices_m.size() * sizeof(float)));
    glEnableVertexAttribArray(1);

    glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0,
            BUFFER_OFFSET(
                    vertices_m.size() * texture_m.size() * sizeof(float)));
    glEnableVertexAttribArray(2);


    glBindTexture(GL_TEXTURE_2D, grassTexture_m.getID());
    glDrawArrays(GL_TRIANGLES, 0, vertices_m.size() / 3);
    glBindTexture(GL_TEXTURE_2D, 0);

    glDisableVertexAttribArray(2);
    glDisableVertexAttribArray(1);
    glDisableVertexAttribArray(0);


    glBindBuffer(GL_ARRAY_BUFFER, 0);
}

Загрузка нормалей вершин в VBO:

void Chunck::load() {
    grassTexture_m.load();

    if (glIsBuffer(vboID_m) == GL_TRUE)
        glDeleteBuffers(1, &vboID_m);

    glGenBuffers(1, &vboID_m);
    glBindBuffer(GL_ARRAY_BUFFER, vboID_m);
    {
        glBufferData(GL_ARRAY_BUFFER, (vertices_m.size() + texture_m.size()) * sizeof(float), 0,
        GL_STATIC_DRAW);
        glBufferSubData(GL_ARRAY_BUFFER, 0, vertices_m.size() * sizeof(float), vertices_m.data());
        glBufferSubData(GL_ARRAY_BUFFER, vertices_m.size() * sizeof(float),
                texture_m.size() * sizeof(float), texture_m.data());
        glBufferSubData(GL_ARRAY_BUFFER, vertices_m.size() * texture_m.size() * sizeof(float),
                        normals_m.size() * sizeof(float), normals_m.data());
    }
    glBindBuffer(GL_ARRAY_BUFFER, 0);

}

Вершинный шейдер:

#version 330 core

in vec3 in_Vertex;
in vec2 in_TexCoord0;
in vec3 in_normal;

uniform mat4 projection;
uniform mat4 model;
uniform mat4 view;


out vec2 coordTexture;
out vec3 normal;
out vec3 FragPos;


void main()
{
    gl_Position = projection * view * model * vec4(in_Vertex, 1.0);
    FragPos = vec3(model * vec4(in_Vertex, 1.0));
    coordTexture = in_TexCoord0;
    normal = in_normal;
}

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

#version 330 core

in vec2 coordTexture;
in vec3 normal;
in vec3 FragPos;

uniform sampler2D texture_;

out vec4 out_Color;

void main()
{
    float ambientStrength = 0.1;
    vec3 lightColor = vec3(1., 1., 1.);
    vec3 ambient = ambientStrength * lightColor;

    vec3 lightDir = normalize(vec3(0., 10000., 0.) - FragPos);
    float diff = max(dot(normal, lightDir), 0.0);
    vec3 diffuse = diff * lightColor;

    //out_Color = vec4((ambient + diffuse), 1.) * texture(texture_, coordTexture);
    out_Color = vec4(normal, 1.) * texture(texture_, coordTexture);
}

Отсутствие layout(location=...) в вашем вершинном шейдере вызывает подозрение. Вы вручную привязываете атрибуты вручную в коде загрузки шейдера?

Frank 13.09.2018 19:07

Спасибо за оперативность ответа, да, привязываю так: glBindAttribLocation (programID_m, 0, "in_Vertex"); glBindAttribLocation (programID_m, 1, "in_TexCoord0"); glBindAttribLocation (programID_m, 2, "in_normal");

Alex 13.09.2018 19:10

Посмотрите на этот вопрос о том, как использовать "шаг" в чередующемся буфере. Поражает glVertexAttribPointer и glBufferSubData.

Ripi2 13.09.2018 19:11
glBufferData(GL_ARRAY_BUFFER, (vertices_m.size() + texture_m.size()) * sizeof(float), 0, GL_STATIC_DRAW); не слишком ли мал? ты наверное хочешь vertices_m.size() + texture_m.size() + normals_m.size()
Frank 13.09.2018 19:11

Да, но, изменив его, это не поможет

Alex 13.09.2018 19:13

Также обратите внимание, что вы используете нормали в пространстве NDC, а не в пространстве мира. И что все номиналы одинаковы, несмотря на вершины, образующие грани.

Ripi2 13.09.2018 19:16

Я обнаружил одну ошибку: glVertexAttribPointer (2, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET (vertices_m.size () * texture_m.size () * sizeof (float))); должен быть glVertexAttribPointer (2, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET ((vertices_m.size () + texture_m.size ()) * sizeof (float))); Но теперь у меня черный экран: \

Alex 13.09.2018 19:33

Нет ...GL_FALSE, 0, BUFFER_OFFSET... Этот 0 - это шагать. У вас здесь неправильное значение.

Ripi2 13.09.2018 19:42

Я почти не пытался написать это, но обычный должен иметь длину 1. Ваши нормали (1, 1, 1) имеют длину sqrt (3). Сомневаюсь, что это актуально (может было бы больше, если бы у вас был белый экран ...)

Scheff's Cat 13.09.2018 19:46

@ Ripi2 даже с: glVertexAttribPointer (2, 3, GL_FLOAT, GL_FALSE, 3 * sizeof (float), BUFFER_OFFSET ((vertices_m.size () + texture_m.size ()) * sizeof (float))); У меня все еще черный экран

Alex 13.09.2018 19:50

@Scheff Если я изменю фрагментный шейдер с vec4 (normal, 1.) * texture (texture_, correTexture); в vec4 (1., 1., 1., 1.) * texture (texture_, correctiveTexture); Я правильно понимаю мой мир

Alex 13.09.2018 19:50

@ Ripi2 Это забавный специальный оператор *, умножающий на компоненты. Итак, vec4(1., 1., 1., 1.) * - это операция идентификации, ничего не меняющая. (Может быть, я слишком зациклился на математическом значении слова «нормальный».) ;-) Извините.

Scheff's Cat 13.09.2018 19:54

Я нашел вторую ошибку, glBufferSubData (GL_ARRAY_BUFFER, (vertices_m.size () * texture_m.size ()) * sizeof (float), normals_m.size () * sizeof (float), normals_m.data ()); должно быть: glBufferSubData (GL_ARRAY_BUFFER, (vertices_m.size () + texture_m.size ()) * sizeof (float), normals_m.size () * sizeof (float), normals_m.data ()); теперь это работает, спасибо за вашу помощь!

Alex 13.09.2018 19:57

@ Ripi2 Извините, предыдущий комментарий не получен. Я имел в виду Алекса и не признал своей ошибки, так как он тоже ее понял и ответил.

Scheff's Cat 13.09.2018 19:59
0
14
155
0

Другие вопросы по теме