Это мой первый ответ на стек, поэтому я хотел бы сделать это шаг за шагом. Очевидно, что вы используете учебное пособие LearnOpenGL (возможно, оно ошибочное, но код выглядит знакомым). Я только что преодолел элементарные проблемы с освещением из некоторой справки из этого урока, я тоже новичок, но надеюсь оказать некоторую помощь.
Vertex Shader :
Итак, для вашего Vertex Shader вы берете 3 указателя attrib: положение, нормаль и координата текстуры - это стандартно, и я ожидаю, что вы ' Вы правильно буферизируете / передаете данные.
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
layout (location = 2) in vec2 textureCoordinate;
Это не проблема, и я не вижу, как это может быть (не видя остальной части вашего кода).
out vec3 Normal;
out vec3 FragmentPos;
out vec2 mobileTextureCoordinate;
Вы также передаете нормали вершин, положение фрагмента и координату текстуры фрагментному шейдеру (кстати, почему вы называете это «Мобильной текстурной координатой»? Я недостаточно разбираюсь в догадках); здесь все выглядит хорошо: никаких проблем.
Тогда у вас есть униформа: объявления модели, вида и матрицы проекции - конечно, нет проблем.
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
Теперь в Основная функция вашего вершинного шейдера. Возможно, проблема здесь не в этом, потому что, очевидно, ваша пирамида отображается правильно - только при неправильном освещении.
void main(){
gl_Position = projection * view * model * vec4(position, 1.0f);
выглядит хорошо.
FragmentPos = vec3(model * vec4(position, 1.0f));
выглядит хорошо, вы игнорируете матрицу проекции и, очевидно, матрица вида.
mobileTextureCoordinate = vec2(textureCoordinate.x, 1.0f - textureCoordinate.y);
Вы переворачиваете координату текстуры по горизонтали (пока не знаю, почему, но неважно)
Normal = mat3(transpose(inverse(model))) * normal;
}
);
Не до конца понимаете, что здесь происходит, но не собираюсь пытаться выяснить это - вы, вероятно, аннулируете некоторые преобразования, так что нормали все еще действительны независимо от преобразований модели или чего-то еще (я действительно не знаю, правильно ли это, и надеюсь, что кто-то может отредактировать мой ответ. )
Фрагментный шейдер:
in vec2 mobileTextureCoordinate;
in vec3 Normal;
in vec3 FragmentPos;
out vec4 pyramidColor; // For outgoing pyramid color
Пока проблем нет
uniform vec3 fillLightColor;
uniform vec3 fillLightPos;
uniform vec3 keyLightColor;
uniform vec3 keyLightPos;
uniform vec3 viewPosition;
uniform sampler2D uTexture;
Предполагается, что эти формы заданы правильно, и вы вызываете glUseProgram () / "shader" .useProgram () / связывание эквивалента шейдера перед установкой униформ с помощью вызовов glUniformX
void main() {
// Calculate Ambient lighting
float ambientStrength = 0.3f;
vec3 ambient = ambientStrength * fillLightColor;
// Calculate Diffuse lighting for fill lamp
vec3 norm = normalize(Normal); // Normalize vectors to 1 unit
vec3 lightDirection = normalize(fillLightPos - FragmentPos); // Calculate distance (light direction) between fill light source and fragments/pixels
float impact = max(dot(norm, lightDirection), 0.0); // Calculate diffuse impact by generating dot product of normal and light
vec3 diffuse = impact * fillLightColor; // Generate diffuse light color
// Calculate Specular lighting for fill lamp
float specularIntensity = 0.8f; // Set specular light strength
float highlightSize = 16.0f; // Set specular highlight size
vec3 viewDir = normalize(viewPosition - FragmentPos); // Calculate view direction
vec3 reflectDir = reflect (-lightDirection, norm); // Calculate reflection vector
//Calculate specular component
float specularComponent = pow(max(dot(viewDir, reflectDir), 0.0), highlightSize);
vec3 specular = specularIntensity * specularComponent * fillLightColor;
// Calculate Ambient lighting for key lamp
float keyAmbientStrength = 1.0f;
vec3 keyAmbient = keyAmbientStrength * keyLightColor;
// Calculate Diffuse lighting for key lamp
vec3 keyLightDirection = normalize(keyLightPos - FragmentPos); // Calculate distance between key light source and fragments
float keyImpact = max(dot(norm, keyLightDirection), 0.0);
vec3 keyDiffuse = keyImpact * keyLightColor;
// Calculate Specular lighting for key lamp
float keySpecularIntensity = 0.8f; // Set specular light strength
float keyHighlightSize = 32.0f; // Set specular highlight size
vec3 keyReflectDir = reflect (-keyLightDirection, norm); // Calculate reflection vector
//Calculate specular component
float keySpecularComponent = pow(max(dot(viewDir, keyReflectDir), 0.0), keyHighlightSize);
vec3 keySpecular = keySpecularIntensity * keySpecularComponent * keyLightColor;
// Calculate phong result
vec3 objectColor = texture(uTexture, mobileTextureCoordinate).xyz;
vec3 fillResult = (ambient + diffuse + specular);
vec3 keyResult = (keyAmbient + keyDiffuse + keySpecular);
vec3 lightingResult = fillResult + keyResult;
vec3 phong = (lightingResult) * objectColor;
pyramidColor = vec4(phong, 1.0f); // Send lighting results to GPU
}
);
Вы сошли с ума? Вы уверены, что pyramidColor действительно устанавливает цвет фрагмента?
Все это выглядит готово ie Резак с этого момента, но я не проверял себя!