(Before you start this little tutorial, make sure you're running Lightjams version 399 or more. If not, download from here: http://www.lightjams.com/history.html)
Let's have some fun with 3D and the shader mode. Just a little reminder about the shader mode. Basically, it's a way to use a formula to paint each cell of the grid based on its x and y positions and any other parameters you want.
We'll see how to use the shader mode to paint a sphere (yes, it's in 3D!) and move it inside a cube (think of a cube made of LEDs). The idea is that the power of a cell will be inversely proportional to its distance to the centre of the sphere. So the closer a cell is to the centre, the more power it has.
To represent the cube in Lightjams, we can use one grid per depth unit we want. So if we want a 10x10x10 cube, we could create ten grids of 10x10. This works well but the downside is that we need to configure at least one source per grid and change the formula of each source to set its Z index, which is needed in the computations.
A nicer way to create a cube is to put the ten 10x10 grids side-by-side on one larger grid. So we end up with one grid of 100x10. Look at the attached project file to see the result. This way, with the shader mode, we only need one formula to paint the sphere inside the cube.
The centre of the sphere is controlled via three global sliders. Go in the view/sliders to see them. So we have the x,y and z sliders. We also have the “sphere width” slider, allowing to control the size of the sphere. Feel free linked those sliders to any input you want.
The formula using the shader mode to compute the power of each cell is:
restrain(slider(4)-(distance((x%(grid.lasty+1))/grid.lasty*100, py, floor(x/(grid.lasty+1))/(grid.lasty)*100, slider(1),slider(2), slider(3))) /distance(0,0,0, 100,100,100)*100, 0, 100)/slider(4)*100
Let' go over each part.
distance((x%(grid.lasty+1))/grid.lasty*100, py, floor(x/(grid.lasty+1))/grid.lasty*100, slider(1),slider(2), slider(3))
This part computes the distance between two 3D points. The first point x,y and z coordinates are:
x1: (x%(grid.lasty+1))/grid.lasty*100
y1: py
z1: floor(x/(grid.lasty+1))/grid.lasty*100
All points are in percent. The formula has been generalized to use grid.lasty+1 to get the height of the cube. So you could use the same formula to create a 15x15x15 cube for example.
To compute x1, we use the modulo operator (%), which returns the reminder of a division. x%(grid.lasty+1) gives the cell's x position. Then we scale the value in percent by doing /grid.lasty*100.
Y1 is the easy one since it's exactly the cell's y position in percent (py).
We compute z1 by extracting the z index. The z index increases by 1 each time we advance of 10 position horizontally. So x/(grid.lasty+1) gives the z-index but with a fractional part. We then use floor to remove the fractional part, which results in the exact z-index.
The second point used to compute the distance is given by the x,y and z sliders. In this case, they are slider 1, 2 and 3.
So now we have the distance of a cell to the centre of the sphere. For convenience, we want to work with a number in percent. So we divide the distance by the max distance we can obtain, which is computed by distance(0,0,0, 100,100,100). Then we multiply by 100 to get a percent number.
Then we want to inverse the distance so that the closer a cell is to the centre, the more power it has:
slider(4)-distancePercent
The slider 4 is the width of the sphere. So if the width is 50%, all cells farther than 50% will be giving a negative power, meaning they are outside the sphere. To avoid having negative power on our grid, we use the restrain function:
restrain(slider(4)-distancePercent, 0, 100)
Then we get a power in percent with a maximum value of slider(4). Since we want that the cell at the sphere's centre to be 100%, we do a last scaling:
restrain(slider(4)-distancePercent, 0, 100) / slider(4) * 100
So now, a cell right at the centre will get 100% power (we can simplify this formula to use only slider(4) once, but it makes it a bit more obscure).
Once you understand how the shader mode works and how to create 3D grids, you can change the shader formula to obtain all kind of crazy shapes. But that's material for another forum post :)
Enjoy!
Mathieu