5. Lighting

Lighting #

Problem statement #

Exercises

Implement a scene having the following lighting equation: a = ambient ambient4, where ambient4 is the ambient light color.

Background #

Ambient light #

An ambient light source represents an omni-directional, fixed-intensity and fixed-color light source that affects all objects in the scene equally (is omni-present). During rendering, all objects in the scene are brightened with the specified intensity and color. This type of light source is mainly used to provide the scene with a basic view of the different objects in it. This is the simplest type of lighting to implement, and models how light can be scattered or reflected many times, thereby producing a uniform effect.

Ambient lighting can be combined with ambient occlusion to represent how exposed each point of the scene is, affecting the amount of ambient light it can reflect. This produces diffused, non-directional lighting throughout the scene, casting no clear shadows, but with enclosed and sheltered areas darkened. The result is usually visually similar to an overcast day.

Code #

Code Lighting .js
let easycam;
let ambientShader;
let items;
let trange;
let lightSlider;
let itemsSlider;
let color_picker;
let colorValue;

function preload() {
  ambientShader = readShader('/vc_page/sketches/shaders/lighting/ambient.frag', {varyings: Tree.NONE,});
}

function setup() {
  createCanvas(400, 400, WEBGL);
  colorMode(RGB, 1);
  
  // easycam stuff
  let state = {
    distance: 250,           // scalar
    center: [0, 0, 0],       // vector
    rotation : [-0.285, -0.257, -0.619, 0.685],  // quaternion
  };
  
  easycam = createEasyCam();
  easycam.state_reset = state;   // state to use on reset (double-click/tap)
  easycam.setState(state, 2000); // now animate to that state
  
  trange = 80;
  items = [];
  
  for (let i = 0; i < 100; i++) {
    items.push({
      position: createVector(
        (random()*2-1) * trange,
        (random()*2-1) * trange,
        (random()*2-1) * trange
      ),
      size: random() * 45 ,
      color: color(random(), random(), random()),
    });
  }
  
  itemsSlider = createSlider(1, items.length, int(items.length / 3), 1);
  itemsSlider.position(20, 20);
  itemsSlider.style('width', '80px');
  
  ambientLightSlider = createSlider(0, 1, 0.5, 0.05);
  ambientLightSlider.position(300, 20);
  ambientLightSlider.style('width', '80px');
  ambientLightSlider.input(ambientLightEvent);  

  color_picker = createColorPicker(color(1.0, 1.0, 1.0));
  color_picker.position(20, 50)
  color_picker.input(colorPickerEvent);
  
  shader(ambientShader);
  ambientShader.setUniform("ambient", ambientLightSlider.value());
  ambientShader.setUniform("lightColor", [1.0, 1.0, 1.0, 1.0]);
  
}

function ambientLightEvent(){
  ambientLightValue = ambientLightSlider.value();
  
  ambientShader.setUniform("ambient", ambientLightValue);
}

function colorPickerEvent(){
  colorValue = color_picker.color();
  
  ambientShader.setUniform("lightColor", [red(colorValue),green(colorValue),blue(colorValue),1.0]);
}

function draw() {
  background(0);
  
  push();
  stroke("green");
  axes();
  grid();
  pop();
  
  for (let i = 0; i < itemsSlider.value(); i++) {
    push();
    noStroke();
    fill(items[i].color);
    translate(items[i].position);
    let radius = items[i].size / 2;
    i % 3 === 0
      ? box(radius)
      : i % 3 === 1
      ? sphere(radius)
      : torus(radius, radius / 4);
    pop(); 
  }
}
Code Lighting .frag
precision mediump float;

// emitted by p5 color-group commands
// https://p5js.org/reference/#group-Color
uniform vec4 uMaterialColor;
uniform float ambient;

uniform vec4 lightColor;

void main() {
  vec4 ambient4 = lightColor * ambient;
  gl_FragColor = ambient4 * uMaterialColor;
}

Conclusions #

  • Ambient lighting provides constant lighting for a scene.
  • It lights all object vertices the same because it is not dependent on any other lighting factors such as vertex normals, light direction, light position, range, or attenuation.
  • Ambient lighting is constant in all directions and it colors all pixels of an object the same. It is fast to calculate but leaves objects looking flat and unrealistic.

References #