Kaleidoscope

The above pictures were created using a shader in processing. The shader tiles a triangular slice of the images to create a kaleidoscope effect.

PShader shaderK;
PGraphics backgroundG;
//number of slices
int viewAngleMod = 10;
//size of the slice to use for the kaleidoscope
float viewAngle =  TWO_PI/viewAngleMod;
//rotation of kaleidoscope
float rotation =  0;

void setup() {
  size(960, 640, P3D);
  //load shader
  shaderK = loadShader("shaderFrag.glsl");
  backgroundG = createGraphics(width, height, P3D);
  drawBackground();
}

void draw() {
  background(0);
  shader(shaderK);
  //set shader uniforms
  shaderK.set("viewAngle", viewAngle);
  shaderK.set("rotation", rotation);
  //apply shader to backgroundG
  image(backgroundG, 0, 0);
  
  //rotate kaleidoscope
  rotation+= QUARTER_PI/100;
  if (rotation >= TWO_PI) 
    rotation = 0;
}

//create random background
void drawBackground() {
  backgroundG.beginDraw(); 
  backgroundG.background(255);
  backgroundG.noStroke();
  for (int i = 0; i < 500; i++) {
    backgroundG.fill(random(255),random(255),random(255),random(255));
    backgroundG.ellipse(random(width), random(height), random(300), random(300));
  }
  backgroundG.endDraw();
}

public void keyReleased() {
  if (key == 'p')
    saveFrame("snapShot-####.png");
  if (key == 'r')
    drawBackground();
  if (key == '=')
    viewAngleMod++;
  if (key == '-') {
    viewAngleMod--;
    if (viewAngleMod <0)
      viewAngleMod = 0;
  }
  viewAngle =  TWO_PI/viewAngleMod;
}

Fragment Shader

precision highp float;

uniform sampler2D texture;
uniform float viewAngle;
uniform float rotation;

varying vec4 vertColor;
varying vec4 vertTexCoord;
varying vec4 pos;

void main() {
	//shift center of the vertTex to the bottom left corner
	vec2 newPos = vertTexCoord.xy - vec2(0.5);
    
	//find the distance of newPos from the bottom left corner
	float distance = length(newPos.xy);
	//find the angle of newPos in relation to the bottom left corner
	float angle = atan(newPos.y, newPos.x);
	
	//map every viewAngle in angle to viewAngle/2, 0 and viewAngle/2
	//e.g. viewAngle = 90 degrees, angle = 0 -> angle = 45, angle = 45 -> angle = 0, angle = 90 -> angle = 45, angle = 135 -> angle = 0, angle = 180 -> angle = 45
	angle = abs(mod(angle, viewAngle) - viewAngle/2.0);
	//add rotation of kaleidoscope to angle
	angle += rotation;
	//set newPos to the position of the new angle
	newPos = distance * vec2(cos(angle), sin(angle));
	//move center of newPos to the center of the screen
	newPos += vec2(0.5);
	//set gl_FragColor to color of the pixel at newPos 
    gl_FragColor = texture2D(texture, newPos) * vertColor;
}