Context
I've been working on creating a ring of lights with the following function implementation
function createLightRing(radius, options) {
let nopIsDefault = false;
...
However, upon running it, I encountered this error
THREE.WebGLProgram: shader error: 0 35715 false gl.getProgramInfoLog invalid shaders THREE.WebGLShader: gl.getShaderInfoLog() fragment
ERROR: too many uniforms
1: #version 300 es
2: #define varying in
3: out highp vec4 pc_fragColor;
4: #define gl_FragColor pc_fragColor
5: #define gl_FragDepthEXT gl_FragDepth
6: #define texture2D texture
7: #define textureCube texture
...
It's frustrating that my intention was just to create a simple ring :(
My Attempts
- Reducing the radius
- Lowering the quality
Highlighted CODE!!!
You can find the live code on repl.it, check it out here
The Function:
function createLightRing(radius, options) {
let nopIsDefault = false;
let lights = [];
const defaultOptions = {
start: 0,
end: 360,
copyLights: [],
color: 0xffffff, // White
lightType: "PointLight",
intensity: 1,
copyLightMap: "loop", // loops the arrays from colors and other values like it
rotation: new p5.Vector(0, 0, 0),
target: null,
quality: 6,
numberOfPoints: null,
override: false
}
// applying the default options
options = {...defaultOptions, ...options}
const copyLightMap = options.copyLightMap.toString().toLowerCase();
// executed only if "numberOfPoints" exists
if (!options.numberOfPoints) {
options.numberOfPoints = (options.end - options.start) * options.quality
nopIsDefault = true;
}
// Mode 1 (soft / soft-(force / end) / 1, forces the loop to end when it finishes looping through "copyLights", but ensures completing the loop. TL;DR: Sets "numberOfPoints" to "copyLights"'s length)
if (copyLightMap == '1' || copyLightMap == 'soft' || copyLightMap == 'soft-end' || copyLightMap == 'soft-force') {
options.numberOfPoints = options.copyLights.length
nopIsDefault = true;
}
// updating "quality" to the right value
options.quality = nopIsDefault ? options.quality : options.numberOfPoints / (options.end - options.start)
for (let i = options.start; i <= options.end; i += 1 / options.quality) {
let light;
let dontCheck = false;
let realI = (1 / options.quality) * i;
const x = radius * cos(i);
const y = radius * sin(i);
// try to create a light with the specified type
try {
light = new THREE[options.lightType]();
}
// if it fails, use the default
catch(err) {
light = new THREE[defaultOptions.lightType]();
}
light = setLightProperties(light, options); // initializes the light properties
// run the switch only if both "copyLights" has at least one element and it can run in the first place
if (options.copyLights[0] && dontCheck) {
const copyLightMap = options.copyLightMap.toString().toLowerCase();
switch (copyLightMap) {
// Mode 0 (force / end / 0, forces the loop to end when done)
case 'force':
case 'end':
case '0':
if (realI < circleLoop) {
dontCheck = true;
break;
}
light = options.copyLights[realI];
break;
// Mode 2 (loop / 2, go back to beginning copyLights when there are no more values left in it)
case 'loop':
case '2':
light = options.copyLights[realI % options.copyLights.lenght];
break;
}
}
if (options.override) {
light = setLightProperties(light, options); // updates light's properties
}
light.position.set(x, y, 0); // sets the light's position
lights.push(light); // adds the new light to the array
}
return lights;
}
You can find all other details about my work on repl.it, so feel free to explore!