首页 > 解决方案 > 通过VBO将法线向量发送到着色器?

问题描述

我正在尝试发送对象每个面的法线向量,但它没有达到我的预期。在着色器中,我添加了这条线vec4(normal, 1.) * texture(texture_, coordTexture);,女巫应该在没有任何光照的情况下显示纹理(正常应该是 vec(1., 1., 1.))。但我得到以下结果:

我得到以下结果

这表明没有发送法线的坐标。

顶点的生成:

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);
}

标签: c++openglshader

解决方案


推荐阅读