Directional Light on Shape Changed Direction or Bug?

edited October 2015 in Questions about Code

Hi, I have some simple code with a shape I made and notices that the directional light axis are flipped with Processing v3 as compared to Processing v2.2.1. This is also contrary to the documentation now. Is this intentional or is it a bug? If it is a bug, I will file an issue for it. Thanks!

// Testing directional lighting

void settings() {
        size(600, 600, P3D);
    }

void setup() {
        frameRate(60);
        noStroke();
    }

void draw() {
        // For Processing v2.2.1, z = -1 is correct for directional light
        // For Processing v3, z = 1 is correct for directional light 
        directionalLight(255, 255, 255, 0, 0, 1);
        background(0);
        fill(color(160, 220, 50));
        translate((width / 2), (height / 2));
        float m = (frameCount * 0.01f);
        rotateY(m);
        
        beginShape(QUAD_STRIP);
        normal(-0.289784f, 0, 0.957092f);
        vertex(50, 20, 0);
        normal(-0.289784f, 0, 0.957092f);
        vertex(50, 75, 0);
        normal(0.289784f, 0, 0.957092f);
        vertex(80, 20, 0);
        normal(0.289784f, 0, 0.957092f);
        vertex(80, 75, 0);
        normal(1, 0, 0);
        vertex(110, 20, -45);
        normal(1, 0, 0);
        vertex(110, 75, -45);
        normal(0.289784f, 0, -0.957092f);
        vertex(80, 20, -90);
        normal(0.289784f, 0, -0.957092f);
        vertex(80, 75, -90);
        normal(-0.289784f, 0, -0.957092f);
        vertex(50, 20, -90);
        normal(-0.289784f, 0, -0.957092f);
        vertex(50, 75, -90);
        normal(-1, 0, 0);
        vertex(20, 20, -45);
        normal(-1, 0, 0);
        vertex(20, 75, -45);
        normal(-0.289784f, 0, 0.957092f);
        vertex(50, 20, 0);
        normal(-0.289784f, 0, 0.957092f);
        vertex(50, 75, 0);
        endShape();
    }
Tagged:

Answers

  • macksize contacted me a few days ago about the Shapes3D library with issues about visual artifacts in the wire frame view and shading of solid objects.

    In the course of my research/experimentation I stated a couple of points with macksize which I would like to share with you all


    Point 1
    In OpenGL the coordinate system is +X left +Y up and +Z towards the viewer i.e. out of the display. It appears that Processing 3 has reversed the Y axis and I don't know why but it a question worth asking.

    Point 2
    In the documentation for direction lights it says

    The nx, ny, and nz parameters specify the direction the light is facing. For example, setting ny to -1 will cause the geometry to be lit from below (since the light would be facing directly upward).

    I believe this is wrong the "OpenGL Programming Guide" (which is the official learning guide for OpenGL) states, and I quote verbatim -

    "By default, GL_POSITION is (0, 0, 1), which defines a directional light that points along the negative z-axis."


    The sketch below draws a toroid and you can change the directional light axis and direction. Key Legend
    x/y/z axis to use for directional light
    d reverse current direction

    My experiments using this sketch show that Point 1 above is correct and P3D uses a different coordinate system from the OpenGL standard.

    In point 2 I was wrong. The documentation is correct but ONLY because of the coordinate system used by PS3

    Also trying it with PS 2.2.1 and 3 show that they behave in the same way.

    Toroid t1;
    
    int nx, ny, nz;
    String dlight;
    
    void setup() {
      size(640, 480, P3D);
      nx = nz = 0;
      ny = 1;
      dlight = dlCoods();
      t1 = new Toroid();
      frameRate(60);
    }
    
    void draw() {
      pushMatrix();
      background(200, 200, 255);
      translate(width/2, height/2, -200);
      rotateY(0.1);
      rotateX(-0.05);
      // basic lighting setup
      ambientLight(120, 120, 120);
      directionalLight(255, 255, 255, nx, ny, nz);
    
      strokeWeight(4);
      stroke(255, 0, 0);
      line(0, 0, 0, 400, 0, 0); // Red x axis
      stroke(0, 255, 0);
      line(0, 0, 0, 0, 400, 0); // Green y axis
      stroke(0, 0, 255);
      line(0, 0, 0, 0, 0, 400); // Blue z axis
    
      // draw toroid
      t1.draw();
      popMatrix();
      fill(0);
      text(dlight, 20, 20);
    }
    
    String dlCoods() {
      return "[" + nx + ", " + ny + ", " + nz + "]";
    }
    
    void keyTyped() {
      switch(key) {
      case 'd':
        nx *= -1;  
        ny *= -1;  
        nz *= -1;
        break;
      case 'x':
        nx = 1; 
        ny = 0; 
        nz = 0;
        break;
      case 'y':
        nx = 0; 
        ny = 1; 
        nz = 0;
        break;
      case 'z':
        nx = 0; 
        ny = 0; 
        nz = 1;
        break;
      }
      dlight = dlCoods();
    }
    
    class Toroid {
      int pts = 40; 
      float angle = 0;
      float radius = 50.0;
    
      // lathe segments
      int segments = 160;
      float latheAngle = 0;
      float latheRadius = 100.0;
    
      PVector vertices[], vertices2[];
    
      public Toroid() {
        fillVertexArrays();
      }
    
      void fillVertexArrays() {
        // initialize point arrays
        vertices = new PVector[pts+1];
        vertices2 = new PVector[pts+1];
    
        // fill arrays
        for (int i=0; i<=pts; i++) {
          vertices[i] = new PVector();
          vertices2[i] = new PVector();
          vertices[i].x = latheRadius + sin(radians(angle))*radius;
          vertices[i].z = cos(radians(angle))*radius;
          angle+=360.0/pts;
        }
      }
    
      void draw() {
        pushMatrix();
        noStroke();
        fill(200, 200, 100);
        // draw toroid
        latheAngle = 0;
        for (int i=0; i<=segments; i++) {
          beginShape(QUAD_STRIP);
          for (int j=0; j<=pts; j++) {
            if (i>0) {
              vertex(vertices2[j].x, vertices2[j].y, vertices2[j].z);
            }
            vertices2[j].x = cos(radians(latheAngle))*vertices[j].x;
            vertices2[j].y = sin(radians(latheAngle))*vertices[j].x;
            vertices2[j].z = vertices[j].z;
            vertex(vertices2[j].x, vertices2[j].y, vertices2[j].z);
          }
          latheAngle+=360.0/segments;
          endShape();
        }
        popMatrix();
      }
    }
    
Sign In or Register to comment.