У меня есть равнина, созданная с использованием этого метода: Вот изображение, показывающее мой образ мышления
Я разделяю эти полосы треугольников, чтобы каждый из них мог иметь уникальный цвет, и явсе еще могу использовать индексирование вершин.
Моя проблема с обычным буфером. Я создаю нормали, как это (это в алгоритме, который вычисляет вершины):
//Calculating Vertices
for (unsigned int z = 0; z < m_size; z++)
{
for (unsigned int x = 0; x <= m_size; x++)
{
Vertices.push_back(glm::vec3(m_startingPos.x + x * m_sqrWidth, m_startingPos.y, m_startingPos.z + z * m_sqrWidth));
Vertices.push_back(glm::vec3(m_startingPos.x + x * m_sqrWidth, m_startingPos.y, m_startingPos.z + (z + 1) * m_sqrWidth));
glm::vec3 TL = glm::vec3(m_startingPos.x + x * m_sqrWidth, m_startingPos.y, m_startingPos.z + z * m_sqrWidth);
glm::vec3 TR = glm::vec3(m_startingPos.x + (x + 1) * m_sqrWidth, m_startingPos.y, m_startingPos.z + z * m_sqrWidth);
glm::vec3 BL = glm::vec3(m_startingPos.x + x * m_sqrWidth, m_startingPos.y, m_startingPos.z + (z + 1) * m_sqrWidth);
glm::vec3 BR = glm::vec3(m_startingPos.x + (x + 1) * m_sqrWidth, m_startingPos.y, m_startingPos.z + (z + 1) * m_sqrWidth);
//Normals:
Normals.push_back(glm::normalize(glm::cross(TL - BR, BL - BR)));
Normals.push_back(glm::normalize(glm::cross(TR - BR, TL - BR)));
//Color:
colors.push_back(0.0f); colors.push_back(0.0f); colors.push_back(0.5f);
colors.push_back(0.0f); colors.push_back(0.5f); colors.push_back(0.0f);
}
}
Так что каждая нормаль равна 0 1 0, я знаю это.
Здесь я создаю буфер и attribPointerдля нормалей (все в классе, так что unsigned int normalsBuffer объявлен в файле .h и инициализирован как NULL):
glGenBuffers(1, &normalsBuffer);
glBindBuffer(GL_ARRAY_BUFFER, normalsBuffer);
glBufferData(GL_ARRAY_BUFFER, Normals.size() * sizeof(float) * 3, &Normals[0].x, GL_STATIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
В glVertexAttribPointer inedex установлен в 2, потому что вершины принимают 0, а цвета принимают 1.
Итак, вот мой шейдер:
#shader vertex
#version 330 core
layout(location = 0) in vec3 position;
layout(location = 1) in vec3 color_in;
layout(location = 2) in vec3 normals_in;
uniform mat4 u_MVP;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
out vec3 FragPos;
out vec3 Normal;
out vec3 color_f;
void main()
{
color_f = color_in;
FragPos = vec3(model * vec4(position, 1.0));
Normal = normals_in;
Normal = mat3(transpose(inverse(model))) * normals_in;
gl_Position = projection * view * vec4(FragPos, 1.0);
};
#shader fragment
#version 330 core
out vec4 color;
in flat vec3 Normal;
in vec3 FragPos;
in flat vec3 color_f;
uniform vec4 u_Color;
uniform vec3 lightPos;
uniform vec3 viewPos;
uniform vec3 lightColor;
void main()
{
vec3 objectColor = color_f;
// ambient
float ambientStrength = 0.1;
vec3 ambient = ambientStrength * lightColor;
// diffuse
vec3 norm = normalize(Normal);
vec3 lightDir = normalize(lightPos - FragPos);
float diff = max(dot(norm, lightDir), 0.0);
vec3 diffuse = diff * lightColor;
// specular
float specularStrength = 0.5;
vec3 viewDir = normalize(viewPos - FragPos);
vec3 reflectDir = reflect(-lightDir, norm);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);
vec3 specular = specularStrength * spec * lightColor;
vec3 result = (ambient + diffuse + specular) * objectColor;
color = vec4(result, 1.0);
}
Вот пример того, как работает объект с таким же шейдером и как ведет себя моя равнина. В ней полностью отсутствует рассеянное освещение
Если я перейду к фрагментному шейдеру и установлю vec3 norm = vec3 (0.0, 1.0, 0.0), все будет работать нормально, но я не хочу этого делать.
Поэтому я посылаю данные о цвете так жепуть и это нормально, но отправка данных нормалей, похоже, не работает.
Вот как это выглядит, когда я получил фрагмент шейдера и установил norm в 0 1 0