Na początku chciałem wyświetlić ten sam model 3 krotnie, dlatego stworzyłem tablice 3 obiektów macierzy 4x4, która zawierała odpowiednio przemnożone przez siebie macierze projection matrix, view matrix oraz model matrix (powstała przez przesuniecie o wektor oraz obrót wokół osi x o -90 stopni, ponieważ załadowany model był obrócony), następnie tą tablice przesłałem przez uniform do vertex shadera. Potem chciałem dodać oświetlenie typu diffuse oraz ambient, dlatego do vertex shadera przesłałem tablice macierzy identyczną jak tamta poprzednia, ale pozbawiona view oraz projection matrix. W vertex shaderze na jej podstawie jest obliczana pozycja wierzchołka, która jest następnie przesyłana do fragment shadera i bierze tam udział w obliczeniach świetlnych. W fragment shaderze stworzyłem wektor z pozycją źródła światła, jednak na wyjściowym modelu pozycja światła jest jakby obrócona przez co oświetlane są nie te pozycje które bym chciał. Czy istnieje jakiś sposób aby zniwelować efekt obrócenia osi
while (!glfwWindowShouldClose(window)) {
glClearColor(0.f, 0.f, 0.f, 1.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
TimePoint now = Clock::now();
float time = std::chrono::duration_cast<Duration>(now - tp_start).count();
float dt = std::chrono::duration_cast<Duration>(now - tp_last).count();
tp_last = now;
handleKeyboard(window, dt);
glm::mat4 V = camera.updateView();
glm::mat4 P = glm::perspective(glm::radians(45.f), static_cast<float>(WSZ_X) / WSZ_Y, 1.f, 500.f);
glm::mat4 R = glm::rotate(glm::mat4(1.f), glm::radians(-90.f), glm::vec3(1.f, 0.f, 0.f));
glm::mat4 MVP[3]{
P * V * (glm::translate(glm::mat4(1.f), glm::vec3(0.f,-20.f,-70.f)) * R),
P * V * (glm::translate(glm::mat4(1.f), glm::vec3(70.f,-20.f,-70.f)) * R),
P * V * (glm::translate(glm::mat4(1.f), glm::vec3(70.f,-20.f, 0.f)) * R)
};
glm::mat4 M[3]{
glm::translate(glm::mat4(1.f), glm::vec3(0.f,-20.f,-70.f)) * R,
glm::translate(glm::mat4(1.f), glm::vec3(70.f,-20.f,-70.f)) * R,
glm::translate(glm::mat4(1.f), glm::vec3(70.f,-20.f, 0.f)) * R
};
glProgramUniformMatrix4fv(vs, 0, 3, GL_FALSE, glm::value_ptr(MVP[0]));
glProgramUniformMatrix4fv(vs, 3, 3, GL_FALSE, glm::value_ptr(M[0]));
for (asset::Mesh& m : meshes) {
glBindVertexArray(m.vao);
glBindTextureUnit(0, m.texture);
glDrawElementsInstanced(GL_TRIANGLES, m.indexCount, GL_UNSIGNED_INT, nullptr, 3);
}
glfwSwapBuffers(window);
glfwPollEvents();
}
vertex shader
#version 450 core
layout (location=0) in vec3 inPos;
layout (location=1) in vec2 inTexCoords;
layout (location=2) in vec3 inNormal;
layout (location=0) uniform mat4 MVP[3];
layout (location=3) uniform mat4 M[3];
out gl_PerVertex{
vec4 gl_Position;
};
out vec2 vertTexCoords;
out vec3 vertNormal;
out vec3 fragPosition;
void main(){
gl_Position = MVP[gl_InstanceID] * vec4(inPos,1.f);
vertTexCoords = inTexCoords;
vertNormal = inNormal;
fragPosition = (vec4(inPos,1.f)*M[gl_InstanceID]).xyz;
}
fragment shader
#version 450 core
in vec2 vertTexCoords;
in vec3 vertNormal;
in vec3 fragPosition;
layout (binding=0) uniform sampler2D tex;
out vec4 Color;
void main(){
vec3 lightPosition=vec3(0.f,200.f,0.f);
vec3 negLightDir=normalize(lightPosition-fragPosition);
vec3 normal=normalize(vertNormal);
float diffuse=max(dot(normal,negLightDir),0.f);
const float AMBIENT=0.15f;
Color=vec4((AMBIENT+diffuse*2.f)*texture(tex,vertTexCoords).rgb,1.f);
}
pozycja światła 0.f,0.f,0.f powinna być oświetlona twarz pierwszego kota oraz boki dwóch pozostałych natomiast
pozycja 0.f,0.f,-200.f powinny być tylko oświetlone tylnie części kotów
pozycja 0.f,200.f,0.f powinny być oświetlone grzbiety kotów