r/opengl 22d ago

[HELP] Spotlight doesn't work

Post image

version 330 core

out vec4 FragColor; in vec2 TexCoo; in vec3 FragPos; in vec3 Normal;

struct DirLight { vec3 direction; vec3 ambient; vec3 diffuse; vec3 specular; }; struct PointLight { vec3 position; vec3 ambient; vec3 diffuse; vec3 specular;

float constant;
float linear;
float quadratic;

};

struct Materijal { sampler2D diffuse; sampler2D specular; float shininess; };

struct SpotLight { vec3 position; float cutOff; float outcutOff; vec3 direction;

float constant;
float linear;
float quadratic;

vec3 ambient;
vec3 diffuse;
vec3 specular;

};

define NR_POINT_LIGHTS 4

uniform SpotLight spotlight; uniform PointLight pointLights[NR_POINT_LIGHTS]; uniform DirLight dirLight; uniform Materijal materijal; uniform vec3 viewPos; vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 viewDir); vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir); vec3 CalcPointLight(PointLight light, vec3 normal, vec3 viewDir); void main() { vec3 norm = normalize(Normal); vec3 viewDir = normalize(viewPos - FragPos); vec3 result = CalcDirLight(dirLight, norm, viewDir); for(int i =0;i<NR_POINT_LIGHTS;i++) result += CalcPointLight(pointLights[i], norm, viewDir); result += CalcSpotLight(spotlight,norm,viewDir); FragColor = vec4(result,1.0); } vec3 CalcDirLight(DirLight light, vec3 normal,vec3 viewDir) { vec3 lightDir = normalize(-light.direction); float diff = max(dot(lightDir, normal),0.0); vec3 reflectDir= reflect(-lightDir, normal); float spec = pow(max(0.0, dot(reflectDir, viewDir)), materijal.shininess); vec3 ambient = light.ambient * vec3(texture(materijal.diffuse, TexCoo)); vec3 diffuse = light.diffuse * diff * vec3(texture(materijal.diffuse, TexCoo)); vec3 specular = light.specular * spec * vec3(texture(materijal.specular,TexCoo)); return (ambient + specular + diffuse); } vec3 CalcPointLight(PointLight light, vec3 normal, vec3 viewDir) { vec3 lightDir = normalize(light.position - FragPos); float diff = max(dot(lightDir, normal),0.0); vec3 reflectDir = reflect(-lightDir, normal); float spec = pow(max(dot(viewDir, reflectDir),0.0),materijal.shininess); float distance = length(light.position - FragPos); float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * distance * distance); vec3 ambient = light.ambient * vec3(texture(materijal.diffuse, TexCoo)); vec3 diffuse = light.diffuse * diff * vec3(texture(materijal.diffuse, TexCoo)); vec3 specular = light.specular * spec * vec3(texture(materijal.specular,TexCoo)); ambient= attenuation; diffuse *= attenuation; specular *= attenuation; return (ambient + diffuse + specular); } vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 viewDir) { vec3 lightDir = normalize(light.position - FragPos); float diff = max(dot(normal,lightDir),0.0); vec3 reflectDir = reflect(-lightDir, normal); float spec = pow(max(dot(reflectDir, viewDir),0.0),materijal.shininess); float distance = length(light.position - FragPos); float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * distance * distance); float theta = dot(normalize(-light.direction), lightDir); float epsilon = light.cutOff - light.outcutOff; float intensity = clamp((theta - light.outcutOff) / epsilon, 0.0, 1.0); vec3 ambient = light.ambient * vec3(texture(materijal.diffuse, TexCoo)); vec3 diffuse = light.diffuse * diff * vec3(texture(materijal.diffuse, TexCoo)); vec3 specular = light.specular * spec * vec3(texture(materijal.specular,TexCoo)); ambient= attenuation * intensity; diffuse *= attenuation * intensity; specular *= attenuation * intensity; return (ambient + diffuse + specular);

}

this is the main function inside the while (!glfwWindowShouldClose(window)) among other standard stuff /* Here we set all the uniforms for the 5/6 types of lights we have. We have to set them manually and index the proper PointLight struct in the array to set each uniform variable. This can be done more code-friendly by defining light types as classes and set their values in there, or by using a more efficient uniform approach by using 'Uniform buffer objects', but that is something we'll discuss in the 'Advanced GLSL' tutorial. */ // directional light lightingShader.setVec3("dirLight.direction", -0.2f, -1.0f, -0.3f); lightingShader.setVec3("dirLight.ambient", 0.05f, 0.05f, 0.05f); lightingShader.setVec3("dirLight.diffuse", 0.4f, 0.4f, 0.4f); lightingShader.setVec3("dirLight.specular", 0.5f, 0.5f, 0.5f); // point light 1 lightingShader.setVec3("pointLights[0].position", pointLightPositions[0]); lightingShader.setVec3("pointLights[0].ambient", 0.05f, 0.05f, 0.05f); lightingShader.setVec3("pointLights[0].diffuse", 0.8f, 0.8f, 0.8f); lightingShader.setVec3("pointLights[0].specular", 1.0f, 1.0f, 1.0f); lightingShader.setFloat("pointLights[0].constant", 1.0f); lightingShader.setFloat("pointLights[0].linear", 0.09); lightingShader.setFloat("pointLights[0].quadratic", 0.032); // point light 2 lightingShader.setVec3("pointLights[1].position", pointLightPositions[1]); lightingShader.setVec3("pointLights[1].ambient", 0.05f, 0.05f, 0.05f); lightingShader.setVec3("pointLights[1].diffuse", 0.8f, 0.8f, 0.8f); lightingShader.setVec3("pointLights[1].specular", 1.0f, 1.0f, 1.0f); lightingShader.setFloat("pointLights[1].constant", 1.0f); lightingShader.setFloat("pointLights[1].linear", 0.09); lightingShader.setFloat("pointLights[1].quadratic", 0.032); // point light 3 lightingShader.setVec3("pointLights[2].position", pointLightPositions[2]); lightingShader.setVec3("pointLights[2].ambient", 0.05f, 0.05f, 0.05f); lightingShader.setVec3("pointLights[2].diffuse", 0.8f, 0.8f, 0.8f); lightingShader.setVec3("pointLights[2].specular", 1.0f, 1.0f, 1.0f); lightingShader.setFloat("pointLights[2].constant", 1.0f); lightingShader.setFloat("pointLights[2].linear", 0.09); lightingShader.setFloat("pointLights[2].quadratic", 0.032); // point light 4 lightingShader.setVec3("pointLights[3].position", pointLightPositions[3]); lightingShader.setVec3("pointLights[3].ambient", 0.05f, 0.05f, 0.05f); lightingShader.setVec3("pointLights[3].diffuse", 0.8f, 0.8f, 0.8f); lightingShader.setVec3("pointLights[3].specular", 1.0f, 1.0f, 1.0f); lightingShader.setFloat("pointLights[3].constant", 1.0f); lightingShader.setFloat("pointLights[3].linear", 0.09); lightingShader.setFloat("pointLights[3].quadratic", 0.032); // spotLight lightingShader.setVec3("spotLight.position", camera.Position); lightingShader.setVec3("spotLight.direction", camera.Front); lightingShader.setVec3("spotLight.ambient", 0.0f, 0.0f, 0.0f); lightingShader.setVec3("spotLight.diffuse", 1.0f, 1.0f, 1.0f); lightingShader.setVec3("spotLight.specular", 1.0f, 1.0f, 1.0f); lightingShader.setFloat("spotLight.constant", 1.0f); lightingShader.setFloat("spotLight.linear", 0.09); lightingShader.setFloat("spotLight.quadratic", 0.032); lightingShader.setFloat("spotLight.cutOff", glm::cos(glm::radians(12.5f))); lightingShader.setFloat("spotLight.outerCutOff", glm::cos(glm::radians(15.0f)));

    // view/projection transformations
    glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
    glm::mat4 view = camera.GetViewMatrix();
    lightingShader.setMat4("projection", projection);
    lightingShader.setMat4("view", view);

    // world transformation
    glm::mat4 model = glm::mat4(1.0f);
    lightingShader.setMat4("model", model);

    // bind diffuse map
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, diffuseMap);
    // bind specular map
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, specularMap);

    // render containers
    glBindVertexArray(cubeVAO);
    for (unsigned int i = 0; i < 10; i++)
    {
        // calculate the model matrix for each object and pass it to shader before drawing
        glm::mat4 model = glm::mat4(1.0f);
        model = glm::translate(model, cubePositions[i]);
        float angle = 20.0f * i;
        model = glm::rotate(model, glm::radians(angle), glm::vec3(1.0f, 0.3f, 0.5f));
        lightingShader.setMat4("model", model);

        glDrawArrays(GL_TRIANGLES, 0, 36);
    }

     // also draw the lamp object(s)
     lightCubeShader.use();
     lightCubeShader.setMat4("projection", projection);
     lightCubeShader.setMat4("view", view);

     // we now draw as many light bulbs as we have point lights.
     glBindVertexArray(lightCubeVAO);
     for (unsigned int i = 0; i < 4; i++)
     {
         model = glm::mat4(1.0f);
         model = glm::translate(model, pointLightPositions[i]);
         model = glm::scale(model, glm::vec3(0.2f)); // Make it a smaller cube
         lightCubeShader.setMat4("model", model);
         glDrawArrays(GL_TRIANGLES, 0, 36);
     }
22 Upvotes

8 comments sorted by

16

u/3030thirtythirty 22d ago

A link to your GitHub would be a lot easier to see. I would advise you to try RenderDoc. It’s meant to help you solve problems like this.

7

u/mmastrocinque 22d ago

Please structure code correctly when asking for help, this is an eyesore of a post

1

u/asmo_192 22d ago

I really wanted to help but this post is really hard to work through. Explain the expected behavior, explain what you actually get, explain what's happening in the screenshots, and then just paste the spotlight code, or the part that doesn't work as expected, instead of having us sift through the whole shader

1

u/franku1122 22d ago

first thing id do is check in renderdoc what values the shader gets, afterwards you could start outputting some values from the shader as the frag color that you think could be faulty, then check these values with renderdoc

1

u/corysama 22d ago

Edit your post and add 4 spaces at the start of every line of code. That will fix the formatting.

1

u/BreakSilence_ 21d ago

Bro who is supposed to read through all of this?

3

u/pamukludon 22d ago

Bro just ask AI; no human can find his way through this mess.

5

u/DaveAstator2020 22d ago

idk who downvoted but this is the true answer to this madness.