Lighting for 3d gravity sim

Hello! Im having trouble with the lighting in my 3d gravity sim. I am trying to programm stars but the lighting function in processing doesnt give of direct light to the camera, so the stars appear like planets, but they make other planets glow. How can i make the stars glow aswell?

code:


ArrayList<Planet> planets = new ArrayList<Planet>();

PVector camPos = new PVector(0, 0, 0);
PVector camDir = new PVector(0, 0, 0);

float aYZ = 0;
float aXZ;



// Create Planets with 'c'
float PlanetSize;
float Scroll;
boolean PlanetBeingCreated = false;
float distCreatePlanet = 100;





float G = 1;


void setup() {
  size(1200, 1000, P3D);
  //fullScreen();

  perspective(PI / 2, float(width) / float(height), 0.1, 1000000);

  aXZ = height / 2;

  planets.add(new Planet(new PVector(-100, 0, 0), 50, true));
  planets.add(new Planet(new PVector(100, 100, 500), 50,true));
  planets.add(new Planet(new PVector(200, 400, 300), 80));
}


void draw() {

  background(0);





  if (aXZ > height) {
    aXZ = height;
  } else if (aXZ < 0) {
    aXZ = 0;
  }


  float angle = map (aYZ, 0, width, -PI, TWO_PI); 

  float camDirX = 700 * cos(angle) + camPos.x;
  float camDirY = map(aXZ, 0, height, -1333, 1333) + camPos.y;
  float camDirZ = 700 * sin(angle) + camPos.z;

  camDir = new PVector(camDirX, camDirY, camDirZ);
  
  camera(camPos.x, camPos.y, camPos.z, camDir.x, camDir.y, camDir.z, 0, 1, 0);
  
  
  for (Planet p : planets) {
    p.emmitLight();
  }
  ambientLight(100, 100, 100);
  
  for (Planet p : planets) {
    p.show();
  }

  for (Planet p : planets) {
    p.update();
  }



  for (Planet b1 : planets) {
    for (Planet b2 : planets) {
      if (b1 != b2) {

        float r = dist(b1.pos.x, b1.pos.y, b1.pos.z, b2.pos.x, b2.pos.y, b2.pos.z);


        PVector p1 = new PVector(b2.pos.x, b2.pos.y, b2.pos.z);

        p1 = p1.sub(b1.pos);

        float a = G * ((b1.m * b2.m) / (r * r));

        b1.applyForce(p1.mult(a).mult(1));
      }
    }
  }

  if (PlanetBeingCreated) {
    PlanetSize += Scroll;

    if (PlanetSize < 1) {
      PlanetSize = 1;
    }

    float SpherePreviewSize = PlanetSize / 1.3;
    PVector SpherePreviewPos = camDir.copy().sub(camPos).normalize().mult(distCreatePlanet).add(camPos.copy());

    pushMatrix();
    translate(SpherePreviewPos.x, SpherePreviewPos.y, SpherePreviewPos.z);
    sphere(SpherePreviewSize);
    popMatrix();
  }
  println(PlanetSize);
  Scroll = 0;





  //Movement
  if (keyPressed) {
    if (key == 'w') {
      camPos = camPos.add(camDir.copy().sub(camPos).normalize());
      camDir = camDir.add(camDir.copy().sub(camPos).normalize());
    } else if (key == 's') {
      camPos = camPos.add(camDir.copy().sub(camPos).normalize().mult(-1));
      camDir = camDir.add(camDir.copy().sub(camPos).normalize().mult(-1));
    } else if (key == 'W') {
      camPos = camPos.add(camDir.copy().sub(camPos).normalize().mult(100));
      camDir = camDir.add(camDir.copy().sub(camPos).normalize().mult(100));
    } else if (key == 'S') {
      camPos = camPos.add(camDir.copy().sub(camPos).normalize().mult(-100));
      camDir = camDir.add(camDir.copy().sub(camPos).normalize().mult(-100));
    }
  }
}




void mouseDragged() {
  if (mouseButton == LEFT) {
    float dx = mouseX - pmouseX;
    float dy = mouseY - pmouseY;

    aXZ += dy / 1;
    aYZ += dx / 1;
  }
}

void keyPressed() {
  if (key == 'c') {
    PlanetSize = 30;
    PlanetBeingCreated = true;
  }
}


void keyReleased() {
  if (key == 'c') {
    PVector CreatePlanetPos = camDir.copy().sub(camPos).normalize().mult(distCreatePlanet).add(camPos.copy());
    planets.add(new Planet(CreatePlanetPos, PlanetSize));

    PlanetBeingCreated = false;
    PlanetSize = 30;
  }
}

void mouseWheel(MouseEvent event) {
  Scroll = event.getCount();
}


////////////


class Body3D {
  PVector pos;
  PVector vel = new PVector(0, 0, 0);
  PVector acc = new PVector(0, 0, 0);

  float m;

  void applyForce(PVector acc_) {
    acc = acc.add(acc_);
  }


  void update() {
    vel = vel.add(acc.div(m));
    acc = new PVector(0, 0, 0);
    pos = pos.add(vel);

    //stroke(255, 255, 255, 30);
    //strokeWeight(2);
    //line(vel.x * 50 + pos.x, vel.y * 50 + pos.y, vel.z * 50 + pos.z, pos.x, pos.y, pos.z);
  }
}



////////



class Planet extends Body3D {
  boolean emmitsLight = false;

  Planet(PVector pos_, float m_) {
    this.pos = pos_;
    this.m = m_;
  }

  Planet(PVector pos_, float m_, boolean emmitsLight_) {
    this.pos = pos_;
    this.m = m_;
    emmitsLight = emmitsLight_;
  }

  void emmitLight() {
    if (emmitsLight) {
      pointLight(255, 200, 200, pos.x, pos.y, pos.z);
    }
  }

  void show() {
    pushMatrix();

    noStroke();
    fill(255);

    translate(pos.x, pos.y, pos.z);
    sphereDetail(60);
    
    //if (!emmitsLight) {
      sphere(this.m / 1.3);
    //}

    popMatrix();
  }
}

Hello, not sure I understand what you need, but it seems to me that you are talking about 2 different things.

A point light does not glow itself, its a point in space that emits light but has no “matter” that could glow.
So the light rays can hit an object and be reflected. Those rays that then travel to your camera is what makes you see the object.

For a glowing object you need “substance” which is - in my experience with model/render software - often a post-processing effect calculated upon the representation of an object within an image.

Thats probably where shaders can be very helpful…

If you want a glow effect you could get help from some libraries out there. The last one I used and found great was the PixelFlow library. Look at the example called BloomDemo under Miscellaneous there once you loaded the library. Its a bit hard to fine-tune, but it worked really great even on a 4K resolution.

I assume you want to select wich objects should glow, so just for the sake of completeness I want to mention that your stars could go into a separate PGraphics from your planets. Which might be a little issue, since hypothetically a star could be in front of a planet…

Thanks, but that might be to complicated…
Is there a way I can just make the stars white?
The light keeps messing with it, but noLight()
Will disable all lighting. push() and pop() don’t store lighting . Thx

im not sure what it actually is you want :slight_smile:
if some objects should not receive light (planets) and others should (stars), you could draw them into a separate buffer (= PGraphics).

Another option is to change the material with emissive() specular() shininess() or ambient()

Planet objects will need some light too, but do not reflect that much of it.

size(200, 200, P3D);
background(0);
noStroke();
directionalLight(153, 153, 153, .5, 0, -1);
ambientLight(153, 102, 0);
ambient(51, 26, 0);
translate(70, 100, 0);
sphere(30);
ambient(251, 226, 200);
translate(70,0, 0);
sphere(30)

Bildschirmfoto 2020-10-10 um 10.41.47

Right now the problem is, that stars recive light from other stars, which makes them look like planets. Imagine 3 objects, 2 stars and 1 planet. The planet will have 2 light spots where the stars are shining, but the stars will have 1 light spot from the other star. Can i disable lighting, when the stars are drawn, so that they dont have light spots and are coulored uniformaly?

it think the basic problem is that we can mainly set the color of an object but not things like “real” reflectivity.

As you can see, setting all the values to zero on the blue sphere will make it very “flat” - could be a planet.
Playing around with shininess or emissive maybe gives the impression of a star, but still, the 3rd sphere “emits” red light, yet it seems this doesn’t travel to the other objects.

Maybe someone else knows more, but first its a shaded renderer and seconds the spheres themselves do not emit light that influences the other spheres. In my opinion, at this point, tuning the appearance of the objects is as far as it goes.

As you can see in the example, adding another light might provide some nice effects to an object, maybe controlling falloff() might also help. (click the mouse !)

But in the end I think it is about designing the material of an object and controlling its properties (how much color it reflects).

To me it seems weird to use ambient() to control the colorization of a sphere. Usually there should be a light source of a certain color -> the light hits an object of another color and is changed, traveling on.
Its like making a red object reflecting blue light - that does not make much sense to me.
Ambient light should actually be the “background light” that is created by ALL objects in the scene. That is, in a room with orange chairs, ambient light will become more orange…

Same goes for specular -> high specularity means that the surface is very smooth and reflective (like metal) resulting in a bigger area ON the object hat reflects light strongly.
Again setting the specular “color” seems strange to me. I know render environments where you set the level of specularity and then there may be an additional option to tune the color that gets reflected, not the color of the specular spot on the primary object itself.

Not being an expert, I feel there is not a big room for making materials or light reflections in processing. On this basic level its still a shaded rendering, not raytracing or radiosity…
(btw, thats actually a feature that I always missed with processing.) but higher level rendering in realtime… well I guess we will have to wait for that another couple of decades :wink:

anyway:

float zLight = 0;
int swap = 1;
boolean showLight = false;
void setup() {
  size(800, 600, P3D);
  noStroke();
}

void draw () {
  background(0);
  ambientLight(150, 100, 50);
  translate(width/2, height/2);

  pointLight(255, 255, 255, 0, 0, zLight);
  zLight += 4.0*swap;
  if (zLight > 400 || zLight < -400) swap *= -1;

  pushMatrix();
  fill(50,50,255);
  ambient(0, 0, 0);
  specular (0,0,0);
  shininess(0);
  emissive(0);
  translate(-200, -200, 0);
  sphere(30);
  popMatrix();

  pushMatrix();
  fill(250,250,255);
  ambient(0, 0, 0);
  specular (0,0,0);
  shininess(0.01);
  emissive(200);
  translate(200, 0, 0);
  sphere(30);
  popMatrix();

  pushMatrix();
  ambient(255, 255, 150);
  specular (110,110,30);
  shininess(1.0);
  emissive(255, 0, 0);
  translate(-200, 200, 0);
  if (showLight)pointLight(255, 255, 120, 200,50, 0);
  sphere(30);
  emissive(0,0,0);
  popMatrix();
}

void mouseClicked () {
showLight = !showLight;
}
1 Like