diff --git a/assets/shaders/skybox.fs b/assets/shaders/skybox.fs new file mode 100644 index 0000000..d1debe6 --- /dev/null +++ b/assets/shaders/skybox.fs @@ -0,0 +1,108 @@ +#version 330 core + +// Implements the Phong lighting model with respect to materials and lighting materials + +// Structs + +struct Material { + vec3 diffuse; + vec3 specular; + float shininess; +}; + +struct DirLight { + vec3 direction; + vec3 ambient; + vec3 diffuse; + vec3 specular; +}; + +struct PointLight { + vec3 position; + // vec3 direction; + vec3 ambient; + vec3 diffuse; + vec3 specular; + + float constant; + float linear; + float quadratic; +}; + +// I/O + +in vec3 vPos; +in vec3 vNormal; +in vec2 vTexCoords; + +out vec4 FragColor; + +#define NR_POINT_LIGHTS 4 + +uniform vec3 viewPos; +uniform PointLight pointLights[NR_POINT_LIGHTS]; +uniform int numPointLights; +uniform DirLight sunLight; +uniform Material material; + +// Functions + +vec3 calculateDirectionalLight(DirLight light); +vec3 calculatePointLight(PointLight light); + + +// Main + +void main() { + vec3 result = vec3(0.0); + + result += calculateDirectionalLight(sunLight); + + for (int i = 0; i < numPointLights; i++) { + result += calculatePointLight(pointLights[i]); + } + + FragColor = vec4(result, 1.0); +} + +vec3 calculateDirectionalLight(DirLight light) { + // Calculate diffuse + vec3 norm = normalize(vNormal); + vec3 lightDir = normalize(-light.direction); + float diff = max(dot(norm, lightDir), 0.0); + + // Calculate specular + vec3 viewDir = normalize(viewPos - vPos); + vec3 reflectDir = reflect(-lightDir, norm); + float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); + + vec3 ambient = light.ambient * material.diffuse; + vec3 diffuse = light.diffuse * diff * material.diffuse; + vec3 specular = light.specular * spec * material.specular; + + return (ambient + diffuse + specular); +} + +vec3 calculatePointLight(PointLight light) { + // Calculate ambient light + + // Calculate diffuse light + vec3 norm = normalize(vNormal); + vec3 lightDir = normalize(light.position - vPos); + float diff = max(dot(norm, lightDir), 0.0); + + // Calculate specular + vec3 viewDir = normalize(viewPos - vPos); + vec3 reflectDir = reflect(-lightDir, norm); + float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); + + // Calculate attenuation + float distance = length(light.position - vPos); + float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance)); + + vec3 ambient = light.ambient * material.diffuse; + vec3 diffuse = light.diffuse * diff * material.diffuse; + vec3 specular = light.specular * spec * material.specular; + + return (ambient + diffuse + specular) * attenuation; +} \ No newline at end of file diff --git a/assets/shaders/skybox.vs b/assets/shaders/skybox.vs new file mode 100644 index 0000000..48ea430 --- /dev/null +++ b/assets/shaders/skybox.vs @@ -0,0 +1,20 @@ +#version 330 core +layout (location = 0) in vec3 aPos; +layout (location = 1) in vec3 aNormal; +layout (location = 2) in vec2 aTexCoords; + +out vec3 vPos; +out vec3 vNormal; +out vec2 vTexCoords; + +uniform mat4 model; +uniform mat3 normalMatrix; +uniform mat4 view; +uniform mat4 projection; + +void main() +{ + gl_Position = projection * vec4(vec3(view * vec4(aPos, 0.0)), 1.0); + vPos = vec3(vec4(aPos, 1.0)); + vNormal = aNormal; +} diff --git a/src/rendering/renderer.cpp b/src/rendering/renderer.cpp index 6a5fba7..2562fae 100644 --- a/src/rendering/renderer.cpp +++ b/src/rendering/renderer.cpp @@ -17,6 +17,7 @@ #include "renderer.h" Shader *shader = NULL; +Shader *skyboxShader = NULL; extern Camera camera; extern std::vector parts; @@ -29,11 +30,10 @@ void renderInit(GLFWwindow* window) { // Compile shader shader = new Shader("assets/shaders/phong.vs", "assets/shaders/phong.fs"); + skyboxShader = new Shader("assets/shaders/skybox.vs", "assets/shaders/skybox.fs"); } -void render(GLFWwindow* window) { - glClearColor(0.1f, 0.1f, 0.1f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +void renderParts() { // Use shader shader->use(); @@ -85,4 +85,60 @@ void render(GLFWwindow* window) { CUBE_MESH->bind(); glDrawArrays(GL_TRIANGLES, 0, 36); } +} + +void renderSkyBox() { + skyboxShader->use(); + + // glm::mat4 projection = glm::perspective(glm::radians(45.f), (float)1200 / (float)900, 0.1f, 100.0f); + // glm::mat4 view = camera.getLookAt(); + + // shader->set("projection", projection); + // shader->set("view", view); + // shader->set("material", Material { + // // .ambient = glm::vec3(1.0f, 0.5f, 0.31f), + // .diffuse = glm::vec3(1.0f, 0.5f, 0.31f), + // .specular = glm::vec3(0.5f, 0.5f, 0.5f), + // .shininess = 32.0f, + // }); + + // shader->set("viewPos", camera.cameraPos); + +// view/projection transformations + glm::mat4 projection = glm::perspective(glm::radians(45.f), (float)1200 / (float)900, 0.1f, 100.0f); + glm::mat4 view = camera.getLookAt(); + skyboxShader->set("projection", projection); + skyboxShader->set("view", view); + skyboxShader->set("material", Material { + // .ambient = glm::vec3(1.0f, 0.5f, 0.31f), + .diffuse = glm::vec3(1.0f, 0.5f, 0.31f), + .specular = glm::vec3(0.5f, 0.5f, 0.5f), + .shininess = 32.0f, + }); + skyboxShader->set("sunLight", DirLight { + .direction = glm::vec3(-0.2f, -1.0f, -0.3f), + .ambient = glm::vec3(0.2f, 0.2f, 0.2f), + .diffuse = glm::vec3(0.5f, 0.5f, 0.5f), + .specular = glm::vec3(1.0f, 1.0f, 1.0f), + }); + skyboxShader->set("numPointLights", 0); + + glm::mat4 model = glm::mat4(1.0f); + // model = glm::translate(model, part.position); + // model = model * glm::mat4_cast(part.rotation); + // model = glm::scale(model, part.scale); + shader->set("model", model); + glm::mat3 normalMatrix = glm::mat3(glm::transpose(glm::inverse(model))); + shader->set("normalMatrix", normalMatrix); + + CUBE_MESH->bind(); + glDrawArrays(GL_TRIANGLES, 0, 36); +} + +void render(GLFWwindow* window) { + glClearColor(0.1f, 0.1f, 0.1f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + renderSkyBox(); + // renderParts(); } \ No newline at end of file