Can this be done (directionalLight)

I am doing a conversion of the headlights on my vehicle so they will work like new high end vehicle. They are going to be curve active and also horizon active. what this means is that they are going to move left or right when the steering on the vehicle changes and they will change their pitch (up/down) when going over things like speed bumps. They are also going to angle up based on how fast the car is going and when the brakes gets stepped on.

Because of the electronic nature of what I am building there is not going to be a way to adjust the lights using anything mechanical. It has to be done in software. I am using an ESP32 for the “processor” for each headlight and the ESP32 has WiFi, this gives me a great way to provide a GUI for adjusting and also for debugging/visual representation of what the headlights are supposed to be doing.

I came across an example of P5 that showed a flashlight type of effect on a sphere. This is really close to what I am looking for to provide a visual in the GUI. It uses the pointLight function to achieve the effect I am looking for. The issue I am having with it is I want to create 2 points of light. each representing a headlight. I need to be able to point the light straight in 2 different locations and then adjust the angle of them pointing based on those 2 locations. I m wanting them to look like car headlights as seen when sitting in the car.

any suggestions on how to go about doing this would be greatly appreciated.

Can you post the example so people can check it out? Are you working in 2D or 3D?



let directionalLightEnable = false; 
  
function preload() { 

} 
  
function setup() { 
  createCanvas(600, 300, WEBGL); 
  textFont(newFont, 16); 
  
  xPosSlider = createSlider(-150, 150, 100, 1); 
  xPosSlider.position(20, 50); 
  
  yPosSlider = createSlider(-300, 300, 0, 1); 
  yPosSlider.position(20, 80); 
  
  zPosSlider = createSlider(0, 250, 150, 1); 
  zPosSlider.position(20, 110); 
  
} 
  
function draw() { 
  background('green'); 
 
  noStroke(); 
  
  xPositionValue = xPosSlider.value(); 
  yPositionValue = yPosSlider.value(); 
  zPositionValue = zPosSlider.value(); 
  
  // Create a point light at the selected location 
  pointLight(255, 0, 0, xPositionValue, yPositionValue, zPositionValue); 
  
  // Create a sphere to show the demonstrate 
  // of the point light location 
  translate(xPositionValue, yPositionValue, zPositionValue); 
  sphere(10); 
  translate(-xPositionValue, -yPositionValue, -zPositionValue); 
  
  specularMaterial(255); 
  
  // Create the sphere on which the point light will work 
  sphere(100); 
} 


let directionalLightEnable = false; 
  
function preload() { 

} 
  
function setup() { 
  createCanvas(900, 300, WEBGL); 
 //textFont(newFont, 16); 
  
  xPosSlider = createSlider(-150, 150, 0, 1); 
  xPosSlider.position(20, 50); 
  
  yPosSlider = createSlider(-300, 300, -60, 1); 
  yPosSlider.position(20, 80); 
  
  zPosSlider = createSlider(0, 250, 150, 1); 
  zPosSlider.position(20, 110); 
  
} 
  
function draw() { 
  background('green'); 
 
  noStroke(); 
  
  xPositionValue = xPosSlider.value(); 
  yPositionValue = yPosSlider.value(); 
  zPositionValue = zPosSlider.value(); 
  
  push();
  // Create a point light at the selected location 
  pointLight(255, 0, 0, xPositionValue, yPositionValue, zPositionValue); 
  
  // Create a sphere to show the demonstrate 
  // of the point light location 
  translate(xPositionValue, yPositionValue, zPositionValue); 
  sphere(10); 
  translate(-xPositionValue-66, -yPositionValue, -zPositionValue); 
  
  specularMaterial(255); 
  
  // Create the sphere on which the point light will work 
  sphere(32); 
  
  pop(); 
  
   push();
  
  xPositionValue+=150;
  
  // Create a point light at the selected location 
  pointLight(255, 0, 0, xPositionValue, yPositionValue, zPositionValue); 
  
  // Create a sphere to show the demonstrate 
  // of the point light location 
  translate(xPositionValue, yPositionValue, zPositionValue); 
  sphere(10); 
  translate(-xPositionValue+66, -yPositionValue, -zPositionValue); 
  
  specularMaterial(255); 
  
  // Create the sphere on which the point light will work 
  sphere(32); 
  
  pop(); 
}


The problem with using translate is the perspective gets all out of wack. You will see that the further you moves the spheres apart from each other.

The point Light function seems to function as if you are holding a flashlight in your hand, when x and y are 0’s it is pointing it straight. if I change x to say 100 what it looks like it is doing is it is rotating the flashlight on the y axis opposite the supplied value for x and also moving the flashlight on the x axis as well. An example would be the supplied 100 for x. the light source is being rotated -100° on the y axis and moved to 100 on the x axis t the same time.

So as a basic idea of the setup I need to have two flashlights one pointing at position x=100, y=100 and the other pointing at x=500, y=100. They need to be square to the canvas when the supplied x and y to pointLight are 0’s and when I change either the x or the y I do not want the position of the flashlight to change, I only want the rotation to change. so if I change the x parameter the light would rotate on the y axis. the x parameter would be where I want the light to shine on the canvas not where I want to move the light source to.

The z parameter at this point in time is irrelevant until I get the x and y correct. the z parameter is going to be for high beams. when the high beams are turned on it would make a larger area lit up.

There are a total of 4 bulbs that I need to work worth. 2 bulbs are low beams and all 4 are high beams.

These would some be something along the lines of what I need for positioning.
left low/high = x: 100, y:100
left high = x: 140, y: 130
right high = x: 460, y: 130
right low/high = x: 500, y: 100

I am pretty confident that p5 is able to do this, I think it is going to be a combination of rotating the canvas 180° shifting it into position and shining the light.

and just to throw a day bit more complexity into it. the range of motion is different between the lamps.
-angle is to the left and + is to the right. the up/down movement is the same for all lamps and + is up and - is down. the - and + for direction can be changed easy enough.

Here is a basic idea of what the min and max angle values for each bulb.
left low/high = -40 to +25
left high = -25 to + 10
right high = -10 to +25
right low/high = -25 to +40

the speed in which the dedicated high beams move is 1/2 the speed of the combination low/high.

The above angles are approximates. I do not have the tooling to manufacturer the headlight housings so they are perfect mirrors of each other so there is going to be variation of the range and also the start and stop angles. The information is going to be fed in from a websocket connection along with the current angle of each bulb. There is also a “trim” feature that alters the min and max angle values for each axis for each bulb. This makes 0, 0 so it points to where it needs to This would be done through the use of 8 sliders 2 for each bulb (x, y). When the slider gets moved that information gets sent to the processor with the new value, once the changes are made the new min and max values would get sent back to the GUI.

This is not going to visually change where 0, 0 is for each lamp in the GUI, it does change the servo positioning in the lamps them selves.

I have been trying to think of the best way to visually display what is going on. This may be overly complex and it might be best to simply display the angles as a numerical value instead. I would personally be OK with only the numerical values. What draws attention tho is “fluff”.

All of the software I am writing is going to be open source, the design and instructions on how to build it for my year make and model vehicle are also going to be available. The build information can be used for information on how to change other vehicles.

I don’t have time to dive into this really, sorry

Two thoughts:

  • don’t use 3D, just use 2D instead. Eg. make a 2D grid # on which you display a circle. Would show the same (in approximation)

  • when 3D and you have perspective problems (I’m not sure which it is), use two PGraphics instead. You can make them with the spheres behind the scenes. Then display them next to each other using image() command. Thus they should both be of central perspective.

Warm regards,

Chrisir