diff --git a/src/Engine/Engine.vcxproj b/src/Engine/Engine.vcxproj index 7717332..2feed00 100644 --- a/src/Engine/Engine.vcxproj +++ b/src/Engine/Engine.vcxproj @@ -168,6 +168,7 @@ + diff --git a/src/Engine/Engine.vcxproj.filters b/src/Engine/Engine.vcxproj.filters index 2ee4601..859cca1 100644 --- a/src/Engine/Engine.vcxproj.filters +++ b/src/Engine/Engine.vcxproj.filters @@ -85,6 +85,9 @@ Resource Files + + Resource Files + diff --git a/src/Engine/main.cpp b/src/Engine/main.cpp index 0baa483..b1d5b28 100644 --- a/src/Engine/main.cpp +++ b/src/Engine/main.cpp @@ -16,7 +16,7 @@ #include "vertices.h" // Continue: https://learnopengl.com/Lighting/Multiple-lights -// Chapter: Not yet started +// Chapter: Putting it all together // // TODO: look at project->properties->VC++ Directories-> change everything to the Environment var // For the "real" Nebulix Engine setup everything so it can be compiled/used with VSCode/CLion and not just VS @@ -222,17 +222,17 @@ int main() lighting->SetInt("material.specularMap", 1); lighting->SetFloat("material.specularColour", 0.5f, 0.5f, 0.5f); lighting->SetFloat("material.shininess", 32.0f); - lighting->SetFloat("light.ambientIntensity", ambientColour); - lighting->SetFloat("light.diffuseIntensity", diffuseColour); - lighting->SetFloat("light.specularIntensity", 1.0f, 1.0f, 1.0f); - lighting->SetFloat("light.position", cam.Position); - lighting->SetFloat("light.direction", cam.Front); - lighting->SetFloat("light.cutOffAngle", glm::cos(glm::radians(12.5f))); - lighting->SetFloat("light.outerCutOffAngle", glm::cos(glm::radians(20.0f))); + lighting->SetFloat("spotLight.ambientIntensity", ambientColour); + lighting->SetFloat("spotLight.diffuseIntensity", diffuseColour); + lighting->SetFloat("spotLight.specularIntensity", 1.0f, 1.0f, 1.0f); + lighting->SetFloat("spotLight.position", cam.Position); + lighting->SetFloat("spotLight.direction", cam.Front); + lighting->SetFloat("spotLight.cutOffAngle", glm::cos(glm::radians(12.5f))); + lighting->SetFloat("spotLight.outerCutOffAngle", glm::cos(glm::radians(20.0f))); lighting->SetFloat("viewPosition", cam.Position); - lighting->SetFloat("light.constant", 1.0f); - lighting->SetFloat("light.linear", 0.09f); - lighting->SetFloat("light.quadratic", 0.032f); + lighting->SetFloat("spotLight.constant", 1.0f); + lighting->SetFloat("spotLight.linear", 0.09f); + lighting->SetFloat("spotLight.quadratic", 0.032f); diffuseMap.BindTexture(); diffuseMap.BindTexture(GL_TEXTURE1); diff --git a/src/Engine/shaders/default/default.frag b/src/Engine/shaders/default/default.frag index 041b560..b1460ff 100644 --- a/src/Engine/shaders/default/default.frag +++ b/src/Engine/shaders/default/default.frag @@ -1,10 +1,13 @@ #version 330 core + +#define NR_POINT_LIGHTS 4 + struct Material { sampler2D diffuseMap; sampler2D specularMap; float shininess; }; -struct Light { +struct SpotLight { vec3 position; vec3 direction; float cutOffAngle; @@ -19,42 +22,107 @@ struct Light { float quadratic; }; +struct DirectionalLight { + vec3 direction; + + vec3 ambient; + vec3 diffuse; + vec3 specular; +}; +struct PointLight { + vec3 position; + + float constant; + float linear; + float quadratic; + + vec3 ambient; + vec3 diffuse; + vec3 specular; +}; + out vec4 FragColor; uniform vec3 viewPosition; uniform Material material; -uniform Light light; +uniform DirectionalLight dirLight; +uniform PointLight pointLights[NR_POINT_LIGHTS]; +uniform SpotLight spotLight; in vec2 TexCoords; -in vec3 FragmentPos; +in vec3 FragPos; in vec3 Normal; -void main() +vec3 CalculateDirectionalLight(DirectionalLight light, vec3 normal, vec3 viewDir) { - vec3 ambientLight = light.ambientIntensity * texture(material.diffuseMap, TexCoords).rgb; + vec3 lightDir = normalize(-light.direction); - vec3 normal = normalize(Normal); - vec3 lightDir = normalize(light.position - FragmentPos); + float diff = max(dot(normal, lightDir), 0); + + vec3 reflectionDir = reflect(-lightDir, normal); + float spec = pow(max(dot(viewDir, reflectionDir), 0), material.shininess); + + vec3 ambient = light.ambient * vec3(texture(material.diffuseMap, TexCoords)); + vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuseMap, TexCoords)); + vec3 specular = light.specular * spec * vec3(texture(material.specularMap, TexCoords)); + + return ambient + diffuse + specular; +} + +vec3 CalculatePointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir) +{ + vec3 lightDir = normalize(light.position - fragPos); + + float diff = max(dot(normal, lightDir), 0.0); + + vec3 reflectionDir = reflect(-lightDir, normal); + float spec = pow(max(dot(viewDir, reflectionDir), 0.0), material.shininess); + + float distance = length(light.position - fragPos); + float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance)); + + vec3 ambientLight = light.ambient * texture(material.diffuseMap, TexCoords).rgb * attenuation; + vec3 diffuseLight = light.diffuse * diff * texture(material.diffuseMap, TexCoords).rgb * attenuation; + vec3 specularLight = light.specular * spec * texture(material.specularMap, TexCoords).rgb * attenuation; + + return ambientLight + diffuseLight + specularLight; +} + +vec3 CalculateSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir) +{ + vec3 lightDir = normalize(light.position - fragPos); float theta = dot(lightDir, normalize(-light.direction)); float epsilon = light.cutOffAngle - light.outerCutOffAngle; float intensity = clamp((theta - light.outerCutOffAngle) / epsilon, 0.0, 1.0); float diff = max(dot(normal, lightDir), 0.0); - vec3 diffuseLight = light.diffuseIntensity * diff * texture(material.diffuseMap, TexCoords).rgb; - vec3 viewDir = normalize(viewPosition - FragmentPos); vec3 reflectDir = reflect(-lightDir, normal); float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); - vec3 specularLight = light.specularIntensity * spec * texture(material.specularMap, TexCoords).rgb; - float distance = length(light.position - FragmentPos); + float distance = length(light.position - fragPos); float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance)); - ambientLight *= attenuation; - diffuseLight *= attenuation * intensity; - specularLight *= attenuation * intensity; + vec3 ambientLight = light.ambientIntensity * texture(material.diffuseMap, TexCoords).rgb * attenuation; + vec3 diffuseLight = light.diffuseIntensity * diff * texture(material.diffuseMap, TexCoords).rgb * attenuation * intensity; + vec3 specularLight = light.specularIntensity * spec * texture(material.specularMap, TexCoords).rgb * attenuation * intensity; + + return ambientLight + diffuseLight + specularLight; +} + + +void main() +{ + vec3 normal = normalize(Normal); + vec3 viewDir = normalize(viewPosition - FragPos); + + //vec3 result = CalculateDirectionalLight(dirLight, normal, viewDir); + + //for(int i = 0; i < NR_POINT_LIGHTS; i++) + // result += CalculatePointLight(pointLights[i], normal, FragPos, viewDir); + + vec3 result = CalculateSpotLight(spotLight, normal, FragPos, viewDir); - vec3 result = ambientLight + diffuseLight + specularLight; FragColor = vec4(result, 1.0); } \ No newline at end of file diff --git a/src/Engine/shaders/default/default.vert b/src/Engine/shaders/default/default.vert index a443705..9df84ad 100644 --- a/src/Engine/shaders/default/default.vert +++ b/src/Engine/shaders/default/default.vert @@ -8,14 +8,14 @@ uniform mat4 viewMatrix; uniform mat4 projectionMatrix; out vec2 TexCoords; -out vec3 FragmentPos; +out vec3 FragPos; out vec3 Normal; void main() { // NOTE: inverse() is very costly to calculate, so the normal matrix should be calculated on the CPU and sent over (just like we do with the model matrix) Normal = mat3(transpose(inverse(modelMatrix))) * normalVector; - FragmentPos = vec3((modelMatrix) * vec4(aPos, 1.0)); + FragPos = vec3((modelMatrix) * vec4(aPos, 1.0)); TexCoords = texCoords; // note that we read the multiplication from right to left gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(aPos, 1.0);