xxxxxxxxxx
135
// 2D Ray Casting
// Original code by Daniel Shiffman
// https://editor.p5js.org/codingtrain/sketches/nf42TaECk
// https://youtu.be/TOEi6T2mtHo
// Modified for coding challenge 145 by JohnyDL
// https://thecodingtrain.com/CodingChallenges/145-2d-ray-casting.html
// https://editor.p5js.org/JohnyDL/sketches/dCnLlChlO
// Ok TLDR of the code:
// the demo at default is a lightsource sending out rainbow rays.
// The rays hit the walls and the light scatters, some scatters as reflection
// some scatters as transmission, like paper diffusers. When the light scatters
// it keeps it's original hue, and the crazy colour effects are mixing hues and
// some persistance of vision.
// There is code for glass, mirrors and more if you want to trace the code, and I think
// I've done an okay job filling it with comments to help any code divers... would love
// to see the wolfenstien version of this... or rather a wolfenstien perspective walking
// round rooms with paper walls and this lighting... may code it eventually if no-one
// beats me to it.
let walls = [];
let wallCount = 40;
let wallLength = 350;
let threshold = 15; //this is the minimum amount of light to be transmitted/reflected from a wall
let transmition = 0.6; //this is the percent of light transmitted
let glass = false;
let tScatter = true;
let refelction = 0.3; // this is the percent of light reflected
let mirror = false;
let rScatter = true;
// the amount of light transmitted and reflected should always sum less than 1.
// glass transmits a single ray
// paper walls would tScatter and rScatter light
// solid walls rScatter light only
// mirror reflects a single ray
// combining these effects can give unusual ways to light up the walls.
// These values have a huge effect on performance. Making the threshold too low or the
// amount of light transmitted/reflected too high will lead to (near) infinite loops
let particle;
let pAngle = 12; //control how far apart rays are in the particle
//(higher number better performance)
let rayCount = Math.floor(Math.sqrt(360/pAngle));
let xoff = 0; //for noisy particle movement
let yoff = 10000; //for noisy particle movement
let points = []; //this will store all the light points
let colOffet = 0; //this allows the colors to change
let colSpin = 0.3; //this sets the speed of the color change
let bgAlpha = 10; //this allows for the light points to slowly fade out
let fade = (255-bgAlpha)/255;
let pixelArray = []; //I'm really proud of this, rather than using the normal pixel
//array since most of the background is black I made my own and then only fill in the
//colors when they're needed, this really reduces the amount of work the simulation has
//to do cause I can skip updating any null pixel in my array. Pixel colours are created //in points.js, this pixel array approach is even faster than drawing every elipse the
//rays generate by coliding with walls and looks better too.
let count = 0;
function setup() {
colorMode(RGB);
createCanvas(windowWidth, windowHeight);
background(0);
for (let i = 0; i < wallCount; i++) {
let b = p5.Vector.random2D()
b.setMag(wallLength);
let x1 = random(width)
let x2 = x1 + b.x;
let y1 = random(height);
let y2 = y1 + b.y;
walls[i] = new Boundary(x1, y1, x2, y2, transmition, refelction);
//the walls on the inside are all the same length but at different angles
//the walls are as if made out of paper transmitting some light through and
//reflecting some light back, scattering in the process.
}
walls.push(new Boundary(5, 5, width - 5, 5, 0, 0));
walls.push(new Boundary(width - 5, 5, width - 5, height - 5, 0, 0));
walls.push(new Boundary(width - 5, height - 5, 5, height - 5, 0, 0));
walls.push(new Boundary(5, height - 5, 5, 5, 0, 0));
//the walls at the edges are inset and don't transmit or reflect the light (black opaque)
particle = new Particle();
}
function draw() {
count = 0;
colorMode(RGB);
// background(0, bgAlpha);
/* for (let wall of walls) {
wall.show();
}
*/ //not showing walls because they're lit up when the light hits them
particle.update(noise(xoff) * width, noise(yoff) * height); //random movement
// particle.update(mouseX, mouseY) //lets mouse control
particle.look(walls);
// points.sort(function(a, b){return a.ints - b.ints});
//sort the points from darkest to lightest
colorMode(HSB);
noStroke()
for (let p of points){
p.show()
}//draw points darkest first
colorMode(RGB);
loadPixels();
for (let i = 0; i < height; i++){
for (let j = 0; j < width; j++){
let px=pixelArray[(width*i)+j]
if (px){
set(j,i,color(px.r,px.g,px.b));
//set the color for this frame
px.addDarkness(fade);
//prepare for next frame rather than making another loop
}
}
}
updatePixels();
particle.show();
points = [];
xoff += 0.003;
yoff += 0.003;
colOffet = (colOffet + colSpin)%360
}