Multiple lights PHONG

I’m trying to implement the shaders of this tutorial, but all I get is a black screen. With my old shaders everything is rendering. Could someone give me some advise how to implement it?

I tried adding lights, but that made no difference:


	     glEnable(GL_LIGHTING);
	     glEnable(GL_LIGHT0);
	     glEnable(GL_NORMALIZE);
	     
	     // Light model parameters:
	     // -------------------------------------------
	     
	     FloatBuffer lmKa = BufferUtil.asFloatBuffer(0.0f, 0.0f, 0.0f, 0.0f);
	     lmKa.flip();
	     glLightModel(GL_LIGHT_MODEL_AMBIENT, lmKa);
	     
	     glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, 1.0f);
	     glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, 0.0f);
	     
	     // -------------------------------------------
	     // Spotlight Attenuation
	     
	     FloatBuffer spot_direction = BufferUtil.asFloatBuffer(1.0f, -1.0f, -1.0f, 0f);
	     spot_direction.flip();
	     int spot_exponent = 30;
	     int spot_cutoff = 180;
	     
	     glLight(GL_LIGHT0, GL_SPOT_DIRECTION, spot_direction);
	     glLighti(GL_LIGHT0, GL_SPOT_EXPONENT, spot_exponent);
	     glLighti(GL_LIGHT0, GL_SPOT_CUTOFF, spot_cutoff);
	    
	     float Kc = 1.0f;
	     float Kl = 0.0f;
	     float Kq = 0.0f;
	     
	     glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION,Kc);
	     glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, Kl);
	     glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, Kq);
	     
	     
	     // ------------------------------------------- 
	     // Lighting parameters:

	     FloatBuffer light_pos = BufferUtil.asFloatBuffer(0.0f, 5.0f, 5.0f, 1.0f);
	     FloatBuffer light_Ka  = BufferUtil.asFloatBuffer(1.0f, 0.5f, 0.5f, 1.0f);
	     FloatBuffer light_Kd  = BufferUtil.asFloatBuffer(1.0f, 0.1f, 0.1f, 1.0f);
	     FloatBuffer light_Ks  = BufferUtil.asFloatBuffer(1.0f, 1.0f, 1.0f, 1.0f);
	     light_pos.flip();
	     light_Ka.flip();
	     light_Kd.flip();
	     light_Ks.flip();
	     
	     glLight(GL_LIGHT0, GL_POSITION, light_pos);
	     glLight(GL_LIGHT0, GL_AMBIENT, light_Ka);
	     glLight(GL_LIGHT0, GL_DIFFUSE, light_Kd);
	     glLight(GL_LIGHT0, GL_SPECULAR, light_Ks);

	     // -------------------------------------------
	     // Material parameters:

	     FloatBuffer material_Ka = BufferUtil.asFloatBuffer(0.5f, 0.0f, 0.0f, 1.0f);
	     FloatBuffer material_Kd = BufferUtil.asFloatBuffer(0.4f, 0.4f, 0.5f, 1.0f);
	     FloatBuffer material_Ks = BufferUtil.asFloatBuffer(0.8f, 0.8f, 0.0f, 1.0f);
	     FloatBuffer material_Ke = BufferUtil.asFloatBuffer(0.1f, 0.0f, 0.0f, 0.0f);
	     material_Ka.flip();
	     material_Kd.flip();
	     material_Ks.flip();
	     material_Ke.flip();
	     float material_Se = 20.0f;

	     glMaterial(GL_FRONT_AND_BACK, GL_AMBIENT, material_Ka);
	     glMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE, material_Kd);
	     glMaterial(GL_FRONT_AND_BACK, GL_SPECULAR, material_Ks);
	     glMaterial(GL_FRONT_AND_BACK, GL_EMISSION, material_Ke);
	     glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, material_Se);

Been a while since I’ve used the fixed-function methods, but:


FloatBuffer lmKa = BufferUtil.asFloatBuffer(0.0f, 0.0f, 0.0f, 0.0f);
        lmKa.flip();
        glLightModel(GL_LIGHT_MODEL_AMBIENT, lmKa);

sets the ambient light to black? Maybe that’s the problem?

That was part of the problem, and my Normals were wrong. It is fixed.

But OpenGL only has 8 lights, so how can I add more lights? Do I have to add my own uniforms?

For multiple lights you can use…

  • Use a Texture to tell your Shader about the lights.
  • Use uniforms to tell your Shader about the lights.
  • A system that sorts all visible models against the lightsources, then activates the 8 closest ones for each model.
  • A system that simply uses the 8 closest lightsources.
  • Deffered Lighting
  • Voxel Cone Tracing
  • …?

Mind that it is terribly inperformant to do a lot of lighting-calculations.
The easiest way to get around that is Deffered-Lighting.

Have a nice day.

  • Longor1996

Thank you for the information. I have been looking and think I found something useful:
Tutorial
Is this what you mean?

Yes, that is what I mean with ‘Deferred Lighting’.

Mind that:

  • It is very hard to have translucent objects with this.
  • It is very hard to do antialiasing with this.

Have a nice day!

  • Longor1996

Is deferred lightning possible with older hardware.


Vertex shader failed to compile with the following errors:
ERROR: 0:1: error(#106) Version number not supported by GL2
ERROR: error(#273) 1 compilation errors.  No code generated

Everywhere they use the newer versions :-\

Simplest way to use multiple lights with fixed function is multipass rendering. There you basically render models many times using additive blending and you disable depth writes and set depth test to equal.

Just to make sure, it is’nt possible to do deferred lighting with my hardware? (ATI Mobility Radeon HD 3650 with OpenGL 6.14.10.11672)

Can you run Battlefield 3, Crysis 3, CoD Modern Warfare 4/5/etc. on that computer?
If so, Deferred-Lighting is avaible, since these games use it.

  • Longor1996

I have never tried those games, because I only have 3GB RAM and a 2.00 gHz processor :’(.

Does this make a big impact on the performance when you have much lights in an level? (for example a street with street lamps at night, or even a whole village).

I would step away from deferred lighting and just do something like this:

That’s much easier to do and it should be sufficient for a lot of cases. If you have multiple lights in a village, they usually don’t affect all the models at once.

This is odd, after trying to add the Deferred rendering, the camera doesn’t move/rotate anymore.


        // Perform camera transformations
        camera.apply();

        shader.setUniform("projection", camera.getProjectionMatrix());
        shader.setUniform("view", camera.getViewMatrix());

        // Render the geometry into the FBO
        multipleRenderTarget.start();
        render();
        multipleRenderTarget.stop();
        
        deferredRendering.render();

Vertex shader:


uniform mat4 projection;
uniform mat4 view;

void main( void )
{
    gl_Position = projection * view * gl_Vertex;
    gl_TexCoord[0] = gl_MultiTexCoord0;

    gl_FrontColor = vec4(1.0, 1.0, 1.0, 1.0);
}

The camera was working this way before and when I disable the Deferred rendering.

This is more like it :smiley: