0

How can I make phong lighting without using a shader (university task). Can I manually calculate ambient, diffuse, specular and transfer their sum to glColor?

UPD: I have a good display of the sum from ambient and diffuse. But the specular doesn't render correctly, it gets very scattered.

My problem in picture:

My code:

void GLRenderSystem::renderTriangleSoup(const std::vector<Vertex>& vertices)
{
    glBegin(GL_TRIANGLES);
    for (const auto& vertex : vertices)
    {
        
        glm::vec3 norm = glm::normalize(glm::vec3(glm::mat3(glm::transpose(inverse(model))) * vertex.normal));
        glm::vec3 FragPos = view * model * glm::vec4(vertex.position, 1.0f); 
        glm::vec3 viewDir = glm::normalize(viewPos - FragPos); 
        glm::vec3 result = glm::vec3(0.0f);
    
        for (const auto& light : lightList)
        {
            if (light.isEnable)
            {
                // ambient
                glm::vec3 ambient = (Ka * light.Ia) * vertex.color;
    
                //diffuse
                glm::vec3 lightDir = glm::normalize(light.position - FragPos);      
                float dist = glm::length(light.position - FragPos);                 
                float diff = glm::max(glm::dot(norm, lightDir), 0.0f);              
                float Att = 1.0f / (1.0f + (0.01 * pow(dist, 2)));                  
                glm::vec3 diffuse = (Kd * light.Id) * (diff * vertex.color); 
    
                //reflect
                glm::vec3 reflectDir = glm::reflect(-lightDir, norm);                     
                float spec = glm::pow(glm::max(glm::dot(viewDir, reflectDir), 0.0f), Se); 
                glm::vec3 specular = (Ks * light.Is) * (spec * vertex.color);         
    
                // result color
                result += (ambient + diffuse + specular);
            }
        }
    
        glColor3fv((GLfloat*)&result);
    
        glm::vec4 vr = proj * view * model * glm::vec4(vertex.position, 1.0f);
        glVertex3fv((GLfloat*)&glm::vec3(vr.x / vr.w, vr.y / vr.w, vr.z / vr.w));
        glNormal3fv((GLfloat*)&vertex.normal);
    }
    glEnd();
}
genpfault
  • 51,148
  • 11
  • 85
  • 139
  • 3
    I get the impression that you either misunderstood the assignment, or left out important parts of it in this question. There are several possible ways to achieve the desired output image "without shaders", but the role opengl has to play in the solution is totally unclear. I.e. it would really help to know what you _should_ use, instead of knowing what you should not use. After all, you can do all software rendering, and it would fulfill the requirement as currently stated. – derhass Aug 03 '20 at 14:59

1 Answers1

4

(Original question was: can I produce specular highlights without using glMaterial or shaders)

No.

Take the example of a large triangle where the corners are only lit by diffuse light and you want a specular highlight in the middle. The lighting equation at the corners does not have a (significant) specular contribution, so you can only pass the diffuse color as glColor.

OpenGL will simply linearly interpolate the color between the three corners; it will not magically generate a specular highlight in the middle, unless you a) use glMaterial to tell it how fragments should interact with the lighting setup, or b) write a fragment shader to evaluate the lighting equation for each fragment.

In 2020, just use shaders.

Botje
  • 26,269
  • 3
  • 31
  • 41
  • I have nothing against shaders, they just asked me such a task at the university – Stepan_Radchenko Aug 03 '20 at 14:17
  • 1
    Your assignment is asking for something that is impossible, so either you misunderstood it or the assignment is bogus. – Botje Aug 03 '20 at 14:18
  • then can you help me how to do this task using glMaterial, please – Stepan_Radchenko Aug 03 '20 at 14:19
  • Ask a new question showing what you tried, with actual code. – Botje Aug 03 '20 at 14:20
  • Botje, I revised my post and now I wrote what I really need – Stepan_Radchenko Aug 03 '20 at 14:25
  • Suggest you read your course material on the `glLight` and `glMaterial` calls and/or read [some tutorial on them](https://www.glprogramming.com/red/chapter05.html) I have not used the legacy API in 8 years so could not possibly help you with that. – Botje Aug 03 '20 at 14:29
  • 2
    "(Original question was: can I produce specular highlights without using glMaterial or shaders) No." That's not stricly true. One can still increase the tesselation so that triangle size approaches a single pixel in area. Or one could calculate the shading on the CPU and apply it as texture. Note that for all practical purposes, I agree to your answer, I'm just nitpicking here... – derhass Aug 03 '20 at 15:04