diff --git a/main.cpp b/main.cpp index dda5ce6..79f5786 100644 --- a/main.cpp +++ b/main.cpp @@ -88,6 +88,7 @@ int main() Shader ourShader("resources/shaders/vert.glsl", "resources/shaders/frag.glsl"); Shader directional_lightShader("resources/shaders/vert.glsl", "resources/shaders/directional_light.glsl"); Shader point_lightShader("resources/shaders/vert.glsl", "resources/shaders/point_light.glsl"); + Shader spotlight_lightShader("resources/shaders/vert.glsl", "resources/shaders/spotlight_light.glsl"); Shader light_cubeShader("resources/shaders/vert.glsl", "resources/shaders/light_object.glsl"); // Models @@ -104,10 +105,15 @@ int main() static float positionY = 0.0f; static float positionZ = 0.0f; - static float lightCubePositionX = 1.2f; - static float lightCubePositionY = 1.0f; - static float lightCubePositionZ = 2.0f; + static float lightCubePositionX = 0.0f; + static float lightCubePositionY = 0.0f; + static float lightCubePositionZ = 3.0f; static float* light_color = new float[3]{1.0f, 1.0f, 1.0f}; + static float light_cutoff = 12.5f; + static float light_outerCutoff = 17.5f; + static float light_directionX = 0.0f; + static float light_directionY = 0.0f; + static float light_directionZ = -1.0f; while(!glfwWindowShouldClose(window)) { @@ -133,6 +139,7 @@ int main() ImGui::Begin("Settings"); ImGui::Text("FPS: %.2f", 1.0f / deltaTime); + ImGui::Text("Camera Direction: (%.2f, %.2f, %.2f)", camera.Front.x, camera.Front.y, camera.Front.z); ImGui::SliderFloat("Object 1 Position X", &positionX, -5.0f, 5.0f); ImGui::SliderFloat("Object 1 Position Y", &positionY, -5.0f, 5.0f); ImGui::SliderFloat("Object 1 Position Z", &positionZ, -5.0f, 5.0f); @@ -140,6 +147,11 @@ int main() ImGui::SliderFloat("Light Cube Position Y", &lightCubePositionY, -5.0f, 5.0f); ImGui::SliderFloat("Light Cube Position Z", &lightCubePositionZ, -5.0f, 5.0f); ImGui::ColorEdit3("Light Cube Color", light_color); + ImGui::SliderFloat("Light Cutoff", &light_cutoff, 0.0f, 90.0f); + ImGui::SliderFloat("Light Outer Cutoff", &light_outerCutoff, 0.0f, 90.0f); + ImGui::SliderFloat("Light Direction X", &light_directionX, -1.0f, 1.0f); + ImGui::SliderFloat("Light Direction Y", &light_directionY, -1.0f, 1.0f); + ImGui::SliderFloat("Light Direction Z", &light_directionZ, -1.0f, 1.0f); ImGui::End(); glm::mat4 view = camera.GetViewMatrix(); @@ -178,12 +190,29 @@ int main() point_lightShader.setMat4("view", view); point_lightShader.setMat4("projection", projection); + // Spotlight light + spotlight_lightShader.use(); + spotlight_lightShader.setVec3("viewPos", camera.Position); + spotlight_lightShader.setVec3("light.position", lightCubePositionX, lightCubePositionY, lightCubePositionZ); + spotlight_lightShader.setVec3("light.direction", light_directionX, light_directionY, light_directionZ); + spotlight_lightShader.setVec3("light.color", light_color[0], light_color[1], light_color[2]); + spotlight_lightShader.setVec3("light.ambient", 0.2f, 0.2f, 0.2f); + spotlight_lightShader.setVec3("light.diffuse", 0.5f, 0.5f, 0.5f); + spotlight_lightShader.setVec3("light.specular", 1.0f, 1.0f, 1.0f); + spotlight_lightShader.setFloat("light.constant", 1.0f); + spotlight_lightShader.setFloat("light.linear", 0.09f); + spotlight_lightShader.setFloat("light.quadratic", 0.032f); + spotlight_lightShader.setFloat("light.cutOff", glm::cos(glm::radians(light_cutoff))); + spotlight_lightShader.setFloat("light.outerCutOff", glm::cos(glm::radians(light_outerCutoff))); + spotlight_lightShader.setMat4("view", view); + spotlight_lightShader.setMat4("projection", projection); + object1.setPosition(glm::vec3(positionX, positionY, positionZ)); - object1.Draw(point_lightShader, deltaTime); + object1.Draw(spotlight_lightShader, deltaTime); object2.setAcceleration(glm::vec3(0.0f, 0.001f, 0.0f)); - object2.Draw(point_lightShader, deltaTime); + object2.Draw(spotlight_lightShader, deltaTime); object3.setAcceleration(glm::vec3(0.0f, -0.001f, 0.0f)); - object3.Draw(point_lightShader, deltaTime); + object3.Draw(spotlight_lightShader, deltaTime); // Light cube shader light_cubeShader.use(); diff --git a/resources/shaders/spotlight_light.glsl b/resources/shaders/spotlight_light.glsl new file mode 100644 index 0000000..43cddbb --- /dev/null +++ b/resources/shaders/spotlight_light.glsl @@ -0,0 +1,64 @@ +#version 330 core +out vec4 FragColor; + +in vec3 Normal; +in vec2 TexCoords; +in vec3 FragPos; + +struct Light { + vec3 position; + vec3 direction; + + vec3 ambient; + vec3 diffuse; + vec3 specular; + vec3 color; + + float constant; + float linear; + float quadratic; + float cutOff; + float outerCutOff; +}; + +uniform sampler2D texture_diffuse1; +uniform vec3 viewPos; +uniform Light light; + +void main() +{ + // Calculate the direction of the light + vec3 lightDir = normalize(light.position - FragPos); + + // Calculate the angle between the light direction and the spotlight direction + float theta = dot(lightDir, normalize(-light.direction)); + float epsilon = light.cutOff - light.outerCutOff; + float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0); + float distance = length(light.position - FragPos); + float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance)); + + // ambient + float ambientStrength = 0.1; + vec3 ambient = ambientStrength * light.color; + + // diffuse + vec3 norm = normalize(Normal); + float diff = max(dot(norm, lightDir), 0.0); + vec3 diffuse = diff * light.color; + + // 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 * light.color; + + // Apply attenuation and intensity + ambient *= attenuation; + diffuse *= attenuation * intensity; + specular *= attenuation * intensity; + + vec3 result = ambient + diffuse + specular; + vec4 light = vec4(result, 1.0); + FragColor = texture(texture_diffuse1, TexCoords) * light; +} \ No newline at end of file