(Edit: I’ve been slowly updating this scene, adding a little more architecture. The “sparking effect” is in a corridor behind the camera, so you have to rotate around with the thumbstick or mouse, and then move forward by teleporting (VR) or using the arrow keys (PC). This scene is part of a larger project, and is in its infancy–so there’s no physics added yet.)
Good afternoon! I’m working on a webXR project (work in progress) with dilapidated, run-down corridors, and wanted to show a broken light fixture with wires hanging down, shorting out and throwing sparks, just like the light fixtures in my own house. I wanted it to be erratic, so I experimented with a few ideas I had in mind, only to accidentally stumble upon something that worked better than I expected. I included the rough “sparking” code below the link. There’s probably a more elegant way to do it, but I’m not an elegant person…
I’m only using two lights in the scene–a hemispheric light for general lighting, and a green-glowing point light underneath the small box that emits the sparks. The rest is mostly baked lighting and materials. My intention was to have both the point light and sparks turn off and on in a randomized way. Each of the five “on” states was supposed to set the light to a different intensity while turning on the particle emitter and having them both run for a few seconds (using settimeout). And each of the “off” states was supposed to turn off the light and the sparks for a different length of time before switching to the “on” state again. I set the timeout to one or several seconds just to test whether or not the timeout and randomized “on” and “off” states would work. When I tried it, however, I was surprised to discover that the code worked exactly as I intended it to. Somehow the code is both acknowledging the timeouts while running right past them at the same time, causing the rapid yet erratic sparking effect. lol.
Anyway, here’s the link (a page on my website) and the code. The demo has no sound and is intended for VR (webXR), but it can be viewed on a PC, using the mouse for turning and arrow keys. (Edit: The camera starts off facing a small cube and has to be rotated with the thumbstick (or mouse) to face the corridor)
.:
https://secrettreasurepath.com/Hidden/ClearTheRubbleUrbexXR.html:
.
// Default intensity is 1. Let's dim the light a small amount
light.intensity = 6.0;
light.diffuse = new BABYLON.Color3(0.55, 0.37, 0.67);
light.setEnabled(true);
let lightOffMesh = 1;
let lightFlicker = 0;
var lightPoint = new BABYLON.PointLight("light", new BABYLON.Vector3(0.14,5.97,24.55), scene);
lightPoint.diffuse = new BABYLON.Color3(0.09,0.94,0.45);
//lightPoint.specular = new BABYLON.Color3(0, 1, 0);
lightPoint.intensity = 0;
lightPoint.setEnabled(false);
// Create a particle system
const particleSystem = new BABYLON.ParticleSystem("particles", 4000);
particleSystem.particleTexture = new BABYLON.Texture("ParticleGreen.png", scene);
particleSystem.blendMode = BABYLON.ParticleSystem.BLENDMODE_STANDARD;
// Position where the particles are emiited from
particleSystem.emitter = boxSparkSource;
particleSystem.minEmitBox = new BABYLON.Vector3(-0.1, -0.1, -0.1); // Starting all from
particleSystem.maxEmitBox = new BABYLON.Vector3(0.1, 0.1, 0.1);
particleSystem.emitRate = 100;
particleSystem.minScaleX = 0.04;
particleSystem.maxScaleX = 0.06;
particleSystem.minScaleY = 0.04;
particleSystem.maxScaleY = 0.06;
particleSystem.direction1 = new BABYLON.Vector3(0, -4, 0).normalize();
particleSystem.direction2 = new BABYLON.Vector3(0, -4, 0).normalize();
particleSystem.minAngularSpeed = 0;
particleSystem.maxAngularSpeed = Math.PI;
particleSystem.minEmitPower = 4;
particleSystem.maxEmitPower = 6;
particleSystem.stop();
scene.actionManager.registerAction(
new BABYLON.ExecuteCodeAction({
trigger: BABYLON.ActionManager.OnEveryFrameTrigger
},
function(){
let SMGR = scene.getMeshByName("ShadowMeshGateRusted");
if (lightOffMesh == 1){
light.excludeMeshes = [SMGR, boxSparkSource];
lightOffMesh = 2;
}
else if (lightOffMesh == 2){
lightFlicker = 1;
lightOffMesh = 3;
}
}//ends function
)
);//ends everyframe trig
//boxSparkSource.emissiveTexture = new BABYLON.Texture("GreenGlow.png", scene);
boxSparkSource.material = new BABYLON.StandardMaterial('myMaterial', scene);
scene.actionManager.registerAction(
new BABYLON.ExecuteCodeAction({
trigger: BABYLON.ActionManager.OnEveryFrameTrigger
},
function(){
if (lightFlicker == 1){
lightPoint.setEnabled(true);
//light.setEnabled(false);
lightPoint.intensity = 50;
boxSparkSource.material.emissiveColor = BABYLON.Color3.Green();
particleSystem.start();
setTimeout(function(){
lightPointOff();
}, 2000);
//lightFlicker = 0;
}
else if (lightFlicker == 2){
lightPoint.setEnabled(true);
//light.setEnabled(false);
lightPoint.intensity = 30;
boxSparkSource.material.emissiveColor = BABYLON.Color3.Green();
particleSystem.start();
setTimeout(function(){
lightPointOff();
}, 1000);
//lightFlicker = 0;
}
else if (lightFlicker == 3){
lightPoint.setEnabled(true);
//light.setEnabled(false);
lightPoint.intensity = 70;
boxSparkSource.material.emissiveColor = BABYLON.Color3.Green();
particleSystem.start();
setTimeout(function(){
lightPointOff();
}, 4000);
//lightFlicker = 0;
}
else if (lightFlicker == 4){
lightPoint.setEnabled(true);
//light.setEnabled(false);
lightPoint.intensity = 100;
boxSparkSource.material.emissiveColor = BABYLON.Color3.Green();
particleSystem.start();
setTimeout(function(){
lightPointOff();
}, 2000);
//lightFlicker = 0;
}
else if (lightFlicker == 5){
lightPoint.setEnabled(true);
//light.setEnabled(false);
lightPoint.intensity = 70;
boxSparkSource.material.emissiveColor = BABYLON.Color3.Green();
particleSystem.start();
setTimeout(function(){
lightPointOff();
}, 10000);
//lightFlicker = 0;
}
else if (lightFlicker == 6){
//light.setEnabled(true);
lightPoint.setEnabled(false);
boxSparkSource.material.emissiveColor = BABYLON.Color3.Black();
particleSystem.stop();
setTimeout(function(){
lightPointOn();
}, 3000);
//lightFlicker = 0;
}
else if (lightFlicker == 7){
//light.setEnabled(true);
lightPoint.setEnabled(false);
boxSparkSource.material.emissiveColor = BABYLON.Color3.Black();
particleSystem.stop();
setTimeout(function(){
lightPointOn();
}, 20000);
//lightFlicker = 0;
}
else if (lightFlicker == 8){
//light.setEnabled(true);
lightPoint.setEnabled(false);
boxSparkSource.material.emissiveColor = BABYLON.Color3.Black();
particleSystem.stop();
setTimeout(function(){
lightPointOn();
}, 2000);
//lightFlicker = 0;
}
else if (lightFlicker == 9){
//light.setEnabled(true);
lightPoint.setEnabled(false);
boxSparkSource.material.emissiveColor = BABYLON.Color3.Black();
particleSystem.stop();
setTimeout(function(){
lightPointOn();
}, 1000);
//lightFlicker = 0;
}
else if (lightFlicker == 10){
//light.setEnabled(true);
lightPoint.setEnabled(false);
boxSparkSource.material.emissiveColor = BABYLON.Color3.Black();
particleSystem.stop();
setTimeout(function(){
lightPointOn();
}, 1000);
//lightFlicker = 0;
}
}//ends function
)
);//ends everyframe trig
function lightPointOn(){
lightFlicker = Math.floor(Math.random() * (5 - 1 + 1) ) + 5;
}
function lightPointOff(){
lightFlicker = Math.floor(Math.random() * (10 - 6 + 1) ) + 10;
}