#version 330 core // Fragment shader for basic lighting with texture mapping out vec4 outputColor; // The final output color of the fragment // --- INPUTS --- // These come from the Vertex Shader in vec3 FragPos; in vec3 Normal; in vec2 TexCoord; struct MaterialProperty { vec3 ambientColour; vec3 diffuseColour; vec3 specularColour; float shininess; }; struct LightProperty { vec3 position; vec3 ambientColour; vec3 diffuseColour; vec3 specularColour; }; // --- UNIFORMS --- uniform sampler2D uTexture; // Image Texture uniform vec3 uViewPos; // Camera Position uniform MaterialProperty uMaterial; // Material Properties uniform LightProperty uPointLight; // Light Properties void main() { // --- LIGHTING CALCULATIONS --- // Lighting Setup (hardcoded for simplicity) vec3 lightPos = vec3(1.2f, 1.0f, 2.0f); vec3 lightColor = vec3(1.0f, 1.0f, 1.0f); // 1. Get Texture Color // Sample the texture at the given texture coordinates vec4 objColor = texture(uTexture, TexCoord); // 2. Ambient strength // A constant, dim light that ensure s object are not completely dark // It simply multiplies the light color by a small factor float ambientStrength = 0.1f; vec3 ambient = uMaterial.ambientColour * uPointLight.ambientColour; // 3. Diffuse // Creates the "matte" effect by calculating the angle between the light direction and the surface normal // Normalize the normal vector and calculate the light direction vec3 norm = normalize(Normal); vec3 lightDir = normalize(uPointLight.position - FragPos); // The dot product gives us the cosine of the angle between the two vectors // The max function ensures we don't get negative values (light coming from behind the surface) float diff = max(dot(norm, lightDir), 0.0f); vec3 diffuse = (uPointLight.diffuseColour * diff) * uMaterial.diffuseColour; // 4. Specular // Creates the shiny highlights on the surface float shininess = 32.0f; // Calculate the view direction and the reflection direction vec3 viewDirection = normalize(uViewPos - FragPos); // If the light is coming from the light direction, we need to negate it for reflection vec3 reflectDirection = reflect(-lightDir, normalize(Normal)); // Calculate the specular component using the dot product and shininess factor float spec = pow(max(dot(viewDirection, reflectDirection), 0.0f), shininess); vec3 specular = uMaterial.specularColour * spec * uPointLight.specularColour; // 5. Combine // We multiply (Ambient + Diffuse) by the Texture Color. // We ADD Specular afterwards so the highlights look bright white (like plastic/metal). vec3 result = (ambient + diffuse) * objColor.rgb + specular; outputColor = vec4(result, objColor.a); }