Strange lighting problem

Duncanla
Unregistered
 
Post: #1
OK.....so ive been creating a graphics engine for the first time and i am currently working on lighting. I have been using the spacesimulator.net and the nehe tutorials to guide me. So i created a program that loads 2 .3ds models and then calculates their normals and then generates the lighting. I used the same models from the spacesimulator tutorials as well as the same lighting set up to test it out.

The problem is...the lighting seems very choppy. I know the smooth shading is working and all that but it seems like on my models, the vertices dont gradual shift colors, they seem to shift between white, gray, and black which gives it an effect that resembles what it would look like if i used polygon normals instead of vertex normals. I debugged both programs and found that the normals in both programs were the same and I ran the spacesimulator program to be sure it wasnt a hardware issue. I just cant find any inconsistencies between the two programs in my lighting. Very frustrating.

Theres gotta be something stupid im just completely missing. If anybody would like to see how the program is working i can e-mail you the executable and data files, or i could send you my code if you want that. Anything to get this thing working. Thanks!

Luke
Quote this message in a reply
Moderator
Posts: 1,560
Joined: 2003.10
Post: #2
Maybe you need a call to glShadeModel(GL_SMOOTH)?

You say you calculate the normals after loading the models. First, doesn't your .3ds file store normals already? Second, how exactly do you go about calculating the normals?

Have you enabled GL_COLOR_MATERIAL? (I don't remember if this could cause the effect you describe, but it's a good thing to have on anyway.)

- Alex Diener
Quote this message in a reply
Duncanla
Unregistered
 
Post: #3
I have already called set the shade model to smooth and no i havent used color material. I make my calls to glMaterial() and then use the texture. I will try the color material the next chance i get. Also, I dont know if the normals are included, i was just following the spacesimulator tutorial.

To calculate the normals I take two sides of each triangle as a vector and then normalize the corss product of the sides to get the normal of each polygon. And then i keep track of how many times each vertex is used and average the normals of each vertex.

I am getting the same normals as the tutorial's program but the transition of the from light to dark is not as smooth for each polygon. For instance, in the tutorial, it seems like the shade for each pixel changes very smoothly from light to dark as you rotate the object, but in mine, they seem to jump from black to gray to white.

Any other ideas?

thanks for your help so far!
Quote this message in a reply
Member
Posts: 184
Joined: 2004.07
Post: #4
It sounds like your normals are not normalized then, though you said you did that. Do you have any screenshots?
Quote this message in a reply
MarkJ
Unregistered
 
Post: #5
A quick fix to see if its a problem with un-normalized normals is to call glEnable(GL_NORMALIZE); right before you render your model.
Quote this message in a reply
Duncanla
Unregistered
 
Post: #6
I have tried the program with GL_NORMALIZE enabled as well as renormalizing all of the normalize after they are all averaged and i get the same result. I will be able to get some screenshots up soon
Quote this message in a reply
Duncanla
Unregistered
 
Post: #7
http://www.geocities.com/duncanla22/badSphere.JPG

There is a screenshot of a simple sphere using the glut libraries so i would not have to find any normals. You can see how it is very choppy around the shaddow...also as the sphere spins you can see the add choppiness ass the jagged edge moves around...

would anyone like to see my code? i wont post it if nobody wants to bother...im just completely shot on any ideas thanks for the help
Quote this message in a reply
Duncanla
Unregistered
 
Post: #8
Ok here is a simplified version of my code that still achieves the same bad effect
...there has got to be something im missing. This is an over simplified version that used a glut sphere so i dont have to caclulate any normals (or should i?)

Code:
#include <GL/glut.h>

void display();
void init();

double xrotate=0;

GLfloat ambient[] = {0.1f, 0.1f, 0.1f, 0.1f};
GLfloat specular[] = {1.0f, 1.0f, 1.0f, 0.0f};
GLfloat diffuse[] = {1.0f, 1.0f, 1.0f, 0.0f};

GLfloat materialAmbient[]= { 0.2f, 0.2f, 0.2f, 0.0f };
GLfloat materialDiffuse[]= { 0.2f, 0.2f, 0.2f, 0.0f };
GLfloat materialSpecular[]= { 1.0f, 1.0f, 1.0f, 0.0f };
GLfloat materialShininess[]= { 1.0f };

GLfloat lightPos[] = {100.0f, 20.0f, -10.0f, 1.0f};

int main(int argc, char** argv)
{
    //create a window using glut
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
  glutInitWindowSize(640,480);
  glutInitWindowPosition(0,0);
  glutCreateWindow("Luke's Engine");
  glutDisplayFunc(display);
  glutIdleFunc(display);
    
  init();
  glutMainLoop();

  return 0;
}


void display()   //draw to the screen
{
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();

  glTranslatef(0, 0, -100);
  glRotatef(xrotate, 1.0, 0.0, 0.0);
  glutSolidSphere(20,20,20);

  //rotate object
  xrotate+=.5;
  if (xrotate == 360)
    xrotate = 0;

  glFlush();
  glutSwapBuffers();
}

void init()   //initialize openGL
{
  //background clearing color
  glClearColor(0.0, 0.0, 0.0, 0.0);

  //viewing values
  glViewport(0,0,640,480);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(45.0f, (GLfloat) 640 / (GLfloat) 480, 5.0f, 10000.0f);

  //lighting
  glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
  glLightfv(GL_LIGHT1, GL_SPECULAR, specular);
  glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
  glLightfv(GL_LIGHT1, GL_POSITION, lightPos);
  glEnable(GL_LIGHT1);
  glEnable(GL_LIGHTING);

  //material
  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, materialAmbient);
  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, materialSpecular);
  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, materialDiffuse);
  glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, materialShininess);


  //other
  glShadeModel(GL_SMOOTH);
  glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
  glEnable(GL_TEXTURE_2D);
  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  glEnable(GL_CULL_FACE);
  glEnable(GL_DEPTH_TEST);

}

Either im suffering from major mental illness or something really weird is goin on....which one is it? Rasp
Quote this message in a reply
Member
Posts: 184
Joined: 2004.07
Post: #9
I think what's going on is your total specular highlight is too high. Those sharp falloff symptoms could be of specular highlighting being overpowering. Since it multiplies the light specular by the material specular, I think the value is going to be higher than you want. Have you played around with the light values?

Also, you might want to try giving your sphere a higher tesselation. It may be easier to tell what's going on.

Edit: To clarify, since your SHININESS is 1.0, the specular highlight will actually just create a +k value on half of the sphere. Since the light value is interpolated across the vertices, this "half" of the sphere will end up being approximated producing a jagged edge like the one you are seeing. To eliminate this you can either remove your specular lighting, or make your SHININESS factor much higher, and your specular lighting numbers lower.
Quote this message in a reply
Duncanla
Unregistered
 
Post: #10
Changing the shininess seems to have helped a bit...but it can still be seen. Another question....why would it work in the spacesimulator.net tutorials and not in mine when im using the same values?
Quote this message in a reply
Duncanla
Unregistered
 
Post: #11
http://www.geocities.com/duncanla22/goodSphere.JPG

This is a screen shot of the spacesimulator tutorial that i modified to do the same thing as mine but it looks much better... i have no idea why....


Here is the code:
Code:
/*
* ---------------- www.spacesimulator.net --------------
*   ---- Space simulators and 3d engine tutorials ----
*
* Author: Damiano Vitulli <info@spacesimulator.net>
*
* ALL RIGHTS RESERVED
*
*
* Tutorial 5: Vectors and OpenGL lighting
*
*
*
* To compile this project you must include the following libraries:
* opengl32.lib,glu32.lib,glut32.lib
* You need also the header file glut.h in your compiler directory.
*  
*/

/*
* Spaceships credits:
* fighter1.3ds - created by: Dario Vitulli
*/

#ifdef __WIN32__
#include <windows.h>
#endif

#include <GL/glut.h>
#include "load_bmp.h"
#include "load_3ds.h"
#include "object.h"



/**********************************************************
*
* VARIABLES DECLARATION
*
*********************************************************/

// The width and height of your window, change them as you like
int screen_width=640;
int screen_height=480;

// Absolute rotation values (0-359 degrees) and rotation increments for each frame
double rotation_x=0, rotation_x_increment=0.1;
double rotation_y=0, rotation_y_increment=0.05;
double rotation_z=0, rotation_z_increment=0.03;

// Flag for rendering as lines or filled polygons
int filling=1; //0=OFF 1=ON

//Lights settings
GLfloat light_ambient[]= { 0.1f, 0.1f, 0.1f, 0.1f };
GLfloat light_diffuse[]= { 1.0f, 1.0f, 1.0f, 0.0f };
GLfloat light_specular[]= { 1.0f, 1.0f, 1.0f, 0.0f };
GLfloat light_position[]= { 100.0f, 0.0f, -10.0f, 1.0f };

//Materials settings
GLfloat mat_ambient[]= { 0.2f, 0.2f, 0.2f, 0.0f };
GLfloat mat_diffuse[]= { 0.2f, 0.2f, 0.2f, 0.0f };
GLfloat mat_specular[]= { 1.0f, 1.0f, 1.0f, 0.0f };
GLfloat mat_shininess[]= { 1.0f };



/**********************************************************
*
* SUBROUTINE init(void)
*
* Used to initialize OpenGL and to setup our world
*
*********************************************************/

void init(void)
{
    glClearColor(0.0, 0.0, 0.0, 0.0); // Clear background color to black

    // Viewport transformation
    glViewport(0,0,screen_width,screen_height);  

    // Projection transformation
    glMatrixMode(GL_PROJECTION); // Specifies which matrix stack is the target for matrix operations
    glLoadIdentity(); // We initialize the projection matrix as identity
    gluPerspective(45.0f,(GLfloat)screen_width/(GLfloat)screen_height,5.0f,10000.0f); // We define the "viewing volume"
  
    //Lights initialization and activation
    glLightfv (GL_LIGHT1, GL_AMBIENT, light_ambient);
    glLightfv (GL_LIGHT1, GL_DIFFUSE, light_diffuse);
    glLightfv (GL_LIGHT1, GL_DIFFUSE, light_specular);
    glLightfv (GL_LIGHT1, GL_POSITION, light_position);    
    glEnable (GL_LIGHT1);
    glEnable (GL_LIGHTING);

    //Materials initialization and activation
    glMaterialfv (GL_FRONT, GL_AMBIENT, mat_ambient);
    glMaterialfv (GL_FRONT, GL_DIFFUSE, mat_diffuse);
    glMaterialfv (GL_FRONT, GL_DIFFUSE, mat_specular);
    glMaterialfv (GL_FRONT, GL_POSITION, mat_shininess);    

    //Other initializations
    glShadeModel(GL_SMOOTH); // Type of shading for the polygons
    glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Texture mapping perspective correction (OpenGL... thank you so much!)
    glEnable(GL_TEXTURE_2D); // Texture mapping ON
    glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); // Polygon rasterization mode (polygon filled)
    glEnable(GL_CULL_FACE); // Enable the back face culling
    glEnable(GL_DEPTH_TEST); // Enable the depth test (also called z buffer)

    //Objects loading
    ObjLoad ("fighter1.3ds","skull.bmp");
}



/**********************************************************
*
* SUBROUTINE resize(int p_width, int p_height)
*
* This routine must be called everytime we resize our window.
*
* Input parameters: p_width = width in pixels of our viewport
*                     p_height = height in pixels of our viewport
*
*********************************************************/

void resize (int p_width, int p_height)
{
    if (screen_width==0 && screen_height==0) exit(0);
    screen_width=p_width; // We obtain the new screen width values and store it
    screen_height=p_height; // Height value

    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // We clear both the color and the depth buffer so to draw the next frame
    glViewport(0,0,screen_width,screen_height); // Viewport transformation

    glMatrixMode(GL_PROJECTION); // Projection transformation
    glLoadIdentity(); // We initialize the projection matrix as identity
    gluPerspective(45.0f,(GLfloat)screen_width/(GLfloat)screen_height,5.0f,10000.0f);

    glutPostRedisplay (); // This command redraw the scene (it calls the same routine of glutDisplayFunc)
}


/**********************************************************
*
* SUBROUTINE display(void)
*
* This is our main rendering subroutine, called each frame
*
*********************************************************/

void display(void)
{
    //int j;

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // This clear the background color to dark blue
    glMatrixMode(GL_MODELVIEW); // Modeling transformation
    glLoadIdentity(); // Initialize the model matrix as identity

    glTranslatef(0.0,0.0,-20); // We move the object forward (the model matrix is multiplied by the translation matrix)

    rotation_x = rotation_x + rotation_x_increment;
    rotation_y = rotation_y + rotation_y_increment;
    rotation_z = rotation_z + rotation_z_increment;

    if (rotation_x > 359) rotation_x = 0;
    if (rotation_y > 359) rotation_y = 0;
    if (rotation_z > 359) rotation_z = 0;

    glRotatef(rotation_x,1.0,0.0,0.0); // Rotations of the object (the model matrix is multiplied by the rotation matrices)
    glRotatef(rotation_y,0.0,1.0,0.0);
    glRotatef(rotation_z,0.0,0.0,1.0);

    glutSolidSphere(5,20,20);
    glFlush(); // This force the execution of OpenGL commands
    glutSwapBuffers(); // In double buffered mode we invert the positions of the visible buffer and the writing buffer
}



/**********************************************************
*
* The main routine
*
*********************************************************/

int main(int argc, char **argv)
{
    // We use the GLUT utility to initialize the window, to handle the input and to interact with the windows system
    glutInit(&argc, argv);    
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(screen_width,screen_height);
    glutInitWindowPosition(0,0);
    glutCreateWindow("www.spacesimulator.net - 3d engine tutorials - To exit press ESC");    
    glutDisplayFunc(display);
    glutIdleFunc(display);
    glutReshapeFunc (resize);
    init();
    glutMainLoop();

    return(0);    
}


I still cant find any inconsistencies between this code and mine
Quote this message in a reply
Member
Posts: 277
Joined: 2004.10
Post: #12
I remember tool that found "inconsistencies" between code...
(I just wish I knew the name Sad)
Quote this message in a reply
Duncanla
Unregistered
 
Post: #13
Any other ideas or insight?
Quote this message in a reply
Member
Posts: 184
Joined: 2004.07
Post: #14
I think between your code and the example you code there are a few minor parameter differences, so you might just want to start with the example code, then strip things out until it's the way you want it. It does seem very strange.
Quote this message in a reply
Duncanla
Unregistered
 
Post: #15
FINALLY I FOUND IT......

IM NOT CRAZY... i found the difference between the code. The tutorial said to do this:

[CODE]
glLightfv (GL_LIGHT1, GL_AMBIENT, light_ambient);
glLightfv (GL_LIGHT1, GL_DIFFUSE, light_diffuse);
glLightfv (GL_LIGHT1, GL_SPECULAR, light_specular);
glLightfv (GL_LIGHT1, GL_POSITION, light_position);

glMaterialfv (GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv (GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv (GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialfv (GL_FRONT, GL_SHININESS, mat_shininess);
[CODE]

which is correct and its what i did....but in their source code they did this by mistake:

[code]
glLightfv (GL_LIGHT1, GL_AMBIENT, light_ambient);
glLightfv (GL_LIGHT1, GL_DIFFUSE, light_diffuse);
glLightfv (GL_LIGHT1, GL_DIFFUSE, light_specular);
glLightfv (GL_LIGHT1, GL_POSITION, light_position);

glMaterialfv (GL_FRONT, GL_AMBIENT, mat_ambient);
glMaterialfv (GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv (GL_FRONT, GL_DIFFUSE, mat_specular);
glMaterialfv (GL_FRONT, GL_POSITION, mat_shininess);

[\code]

...notice how they gave GL_DIFFUSE the specular value as well...i cant believe it took me this long to figure this out...i swear i checked that about 300000 times....

ok...so now im going to assume that the correct answer to this would be that the specular component IS overpowering the others. Now....as soon as a review the effects of the different components i will be able to accomplish the effect that the tutorial is going for....Thanks everybody for your help!!!!
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Lighting and Multitexturing problem Scribendi 0 2,633 Sep 25, 2005 09:22 PM
Last Post: Scribendi
  Lighting Problem, need help nahid 10 4,128 Apr 13, 2005 10:16 PM
Last Post: nahid
  strange color problem leggo 12 6,003 Aug 27, 2004 08:36 AM
Last Post: leggo
  Strange SDL problem DJBlufire 4 3,288 Sep 24, 2003 09:09 AM
Last Post: MattDiamond