2

I am struggling with OpenGL lighting. I have the following enabled:

Specular[0] = 1f;
Specular[1] = 1f;
Specular[2] = 1f;
Specular[3] = 1f;
Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_SHININESS, new float[] { 70 });
Gl.glMaterialfv(Gl.GL_FRONT_AND_BACK, Gl.GL_SPECULAR, Specular);

Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_POSITION, LightDef.LightPosToArray);
Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_AMBIENT, LightDef.AmbientToArray);
Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_DIFFUSE, LightDef.DiffuseToArray);
Gl.glEnable(Gl.GL_LIGHT0);
Gl.glEnable(Gl.GL_LIGHTING);
Gl.glShadeModel(Gl.GL_SMOOTH);

When I draw rectangles adjacent to each other and they have the same size everything looks fine. When I draw them at different sizes the lighting changes on each one. How can I make them look seamless?

Gl.glNormal3f(0, 0, 1);
Gl.glRectf(0, 0, 1000, 500);
Gl.glRectf(0, 500, 500, 1000);
Gl.glRectf(500, 500, 700, 700);

lighting problem

Community
  • 1
  • 1
Electron8
  • 43
  • 3

1 Answers1

1

The Legacy OpenGLlight model uses Gouraud Shading. The light is computed for the vertices and interpolated on the fragments which are covered by the polygons.
The specular light depends on the location or direction of the light source, the normal vector of the surface and the viewing direction. Since direction of view is different to each vertex, the lighting of the surfaces is different.
In compare to the specular light, the diffuse light does not depend on the viewing direction. It depends on the location or direction of the light source and the normal vector of the surface. If the normal vectors of the surfaces are equal and the light source is a directional light, then the light would be the same over all the surfaces.

Set the specular light 0:

Specular[0] = 0f;
Specular[1] = 0f;
Specular[2] = 0f;
Specular[3] = 0f;

and ensure that the light source is a directional light (4th component of LightDef.LightPosToArray has to be 0).

Another option would be to tessellate the larger surfaces in that way, that the share the vertices with the smaller ones. e.g.:

+---+---+
|   |   |
+---+---+---+
|   |   |   |
+---+---+---+---+
|   |   |   |   |
+---+---+---+---+

See also GLSL fixed function fragment program replacement

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • Thanks. So there is no way to fix this problem besides changing the light model? Is it complicated to change? – Electron8 Jan 20 '20 at 20:57
  • @Electron8 Use a diffuse light (specular light (0, 0, 0)) and a directional light source. The difference is caused by the specular light and/or a point light source. – Rabbid76 Jan 20 '20 at 20:58
  • Hum.. It makes them look completely flat. – Electron8 Jan 20 '20 at 21:28
  • @Electron8 Of course. Either it is flat or it depends on the vertices. If you want a smooth specular highlights and a gradient transition, then you have to implement per fragment lighting. You have to get rid of the legacy light model and to implement a [Shader](https://www.khronos.org/opengl/wiki/Shader). Note the light model is deprecated and not state of the art. It exist just for backward compatibility. – Rabbid76 Jan 20 '20 at 21:31
  • @Electron8 An option would be to tessellate the larger surfaces in that way, that the share the vertices with the smaller ones – Rabbid76 Jan 20 '20 at 21:40
  • 1
    Thanks. I was hoping for something like Gl.GlEnable(Gl.GL_FIX_THE_PROBLEM); :) – Electron8 Jan 20 '20 at 22:03