Build games as easily as you play them — join the Phaser Beam waitlist for Early Access.
const fragmentShader = ` //@machine_shaman precision mediump float; uniform float time; uniform vec2 mouse; uniform vec2 resolution; #define FOV 90. #define imod(n, m) n - (n / m * m) #define VERTICES 12 #define FACES 20 float iX = .525731112119133606; float iZ = .850650808352039932; void icoVertices(out vec3[VERTICES] shape) { shape[0] = vec3(-iX, 0.0, iZ); shape[1] = vec3( iX, 0.0, iZ); shape[2] = vec3(-iX, 0.0, -iZ); shape[3] = vec3( iX, 0.0, -iZ); shape[4] = vec3( 0.0, iZ, iX); shape[5] = vec3( 0.0, iZ, -iX); shape[6] = vec3( 0.0, -iZ, iX); shape[7] = vec3( 0.0, -iZ, -iX); shape[8] = vec3( iZ, iX, 0.0); shape[9] = vec3( -iZ, iX, 0.0); shape[10] = vec3( iZ, -iX, 0.0); shape[11] = vec3( -iZ, -iX, 0.0); } mat2 rotate(float a) { float c = cos(a); float s = sin(a); return mat2(c, s, -s, c); } float line(vec2 p, vec2 a, vec2 b) { vec2 pa = p - a; vec2 ba = b - a; float t = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0); return length(pa - ba * t); } vec3 v[12]; vec2 p[12]; // using define trick to render different triangles // not possible in loop on glslsandbox #define tri(a, b, c) min(min(min(d, line(uv, p[a], p[b])), line(uv, p[b], p[c])), line(uv, p[c], p[a])) void main() { vec2 uv = (2. * gl_FragCoord.xy - resolution) / resolution.y; uv.y += .08 * sin(uv.x + time); uv = floor(uv * 100.) / 100.; uv *= 3.; float t = 0.001 + abs(uv.y); float scl = 1. / t; vec2 st = uv * scl + vec2(0, scl + time); // setup vertices icoVertices(v); // project for (int i = 0; i < 12; i++) { v[i].xz *= rotate(time * 0.5); float scl = 1.0 / (1. + v[i].z * 0.2); float dist = distance(v[i].xyz, vec3(0, 0, -3)); p[i] = v[i].xy * scl;// - vec2(0, 0); } // ico faces float d = 1.0; d = min(d, tri(0, 4, 1)); d = min(d, tri(0, 9, 4)); d = min(d, tri(9, 5, 4)); d = min(d, tri(4, 5, 8)); d = min(d, tri(4, 8, 1)); d = min(d, tri(8, 10, 1)); d = min(d, tri(8, 3, 10)); d = min(d, tri(5, 3, 8)); d = min(d, tri(5, 2, 3)); d = min(d, tri(2, 7, 3)); d = min(d, tri(7, 10, 3)); d = min(d, tri(7, 6, 10)); d = min(d, tri(7, 11, 6)); d = min(d, tri(11, 0, 6)); d = min(d, tri(0, 1, 6)); d = min(d, tri(6, 1, 10)); d = min(d, tri(9, 0, 11)); d = min(d, tri(9, 11, 2)); d = min(d, tri(9, 2, 5)); d = min(d, tri(7, 2, 11)); // color the scene vec3 col = vec3(0); col += mix(vec3(0), .5 + .5 * cos(time + st.x + 2. * st.y + vec3(0, 1, 2)), sign(cos(st.x * 10.)) * sign(cos(st.y * 20.))) * t * t; //col += smoothstep(0.3, 0., d); col *= smoothstep(0.0, 0.1, d); col += smoothstep(0.1, 0., d) * (.5 + .5 * cos(time + d * 20. + vec3(33, 66, 99))); col += abs(.01 / d); // thanks for the dithering effect :) col += floor(uv.y - fract(dot(gl_FragCoord.xy, vec2(0.5, 0.75))) * 10.0) * 0.1; gl_FragColor = vec4(col, 1.); }`; class Example extends Phaser.Scene { constructor() { super(); } preload() { this.load.setBaseURL('https://cdn.phaserfiles.com/v385'); this.load.image('logo', 'assets/sprites/phaser3-logo-small.png'); this.load.image('mask', 'assets/tests/camera/grunge-mask.png'); } create() { const maskImage = this.make.image({ x: 400, y: 300, key: 'mask', add: false }); const mask = maskImage.createBitmapMask(); this.cameras.main.setMask(mask, false); const baseShader = new Phaser.Display.BaseShader('BufferShader', fragmentShader); const shader = this.add.shader(baseShader, 400, 300, 800, 600); this.add.image(400, 300, 'logo'); } } const config = { type: Phaser.WEBGL, parent: 'phaser-example', width: 800, height: 600, scene: Example }; const game = new Phaser.Game(config);
const fragmentShader = `
//@machine_shaman
precision mediump float;
uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;
#define FOV 90.
#define imod(n, m) n - (n / m * m)
#define VERTICES 12
#define FACES 20
float iX = .525731112119133606;
float iZ = .850650808352039932;
void icoVertices(out vec3[VERTICES] shape) {
shape[0] = vec3(-iX, 0.0, iZ);
shape[1] = vec3( iX, 0.0, iZ);
shape[2] = vec3(-iX, 0.0, -iZ);
shape[3] = vec3( iX, 0.0, -iZ);
shape[4] = vec3( 0.0, iZ, iX);
shape[5] = vec3( 0.0, iZ, -iX);
shape[6] = vec3( 0.0, -iZ, iX);
shape[7] = vec3( 0.0, -iZ, -iX);
shape[8] = vec3( iZ, iX, 0.0);
shape[9] = vec3( -iZ, iX, 0.0);
shape[10] = vec3( iZ, -iX, 0.0);
shape[11] = vec3( -iZ, -iX, 0.0);
}
mat2 rotate(float a) {
float c = cos(a);
float s = sin(a);
return mat2(c, s, -s, c);
}
float line(vec2 p, vec2 a, vec2 b) {
vec2 pa = p - a;
vec2 ba = b - a;
float t = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0);
return length(pa - ba * t);
}
vec3 v[12];
vec2 p[12];
// using define trick to render different triangles
// not possible in loop on glslsandbox
#define tri(a, b, c) min(min(min(d, line(uv, p[a], p[b])), line(uv, p[b], p[c])), line(uv, p[c], p[a]))
void main() {
vec2 uv = (2. * gl_FragCoord.xy - resolution) / resolution.y;
uv.y += .08 * sin(uv.x + time);
uv = floor(uv * 100.) / 100.;
uv *= 3.;
float t = 0.001 + abs(uv.y);
float scl = 1. / t;
vec2 st = uv * scl + vec2(0, scl + time);
// setup vertices
icoVertices(v);
// project
for (int i = 0; i < 12; i++) {
v[i].xz *= rotate(time * 0.5);
float scl = 1.0 / (1. + v[i].z * 0.2);
float dist = distance(v[i].xyz, vec3(0, 0, -3));
p[i] = v[i].xy * scl;// - vec2(0, 0);
}
// ico faces
float d = 1.0;
d = min(d, tri(0, 4, 1));
d = min(d, tri(0, 9, 4));
d = min(d, tri(9, 5, 4));
d = min(d, tri(4, 5, 8));
d = min(d, tri(4, 8, 1));
d = min(d, tri(8, 10, 1));
d = min(d, tri(8, 3, 10));
d = min(d, tri(5, 3, 8));
d = min(d, tri(5, 2, 3));
d = min(d, tri(2, 7, 3));
d = min(d, tri(7, 10, 3));
d = min(d, tri(7, 6, 10));
d = min(d, tri(7, 11, 6));
d = min(d, tri(11, 0, 6));
d = min(d, tri(0, 1, 6));
d = min(d, tri(6, 1, 10));
d = min(d, tri(9, 0, 11));
d = min(d, tri(9, 11, 2));
d = min(d, tri(9, 2, 5));
d = min(d, tri(7, 2, 11));
// color the scene
vec3 col = vec3(0);
col += mix(vec3(0), .5 + .5 * cos(time + st.x + 2. * st.y + vec3(0, 1, 2)), sign(cos(st.x * 10.)) * sign(cos(st.y * 20.))) * t * t;
//col += smoothstep(0.3, 0., d);
col *= smoothstep(0.0, 0.1, d);
col += smoothstep(0.1, 0., d) * (.5 + .5 * cos(time + d * 20. + vec3(33, 66, 99)));
col += abs(.01 / d);
// thanks for the dithering effect :)
col += floor(uv.y - fract(dot(gl_FragCoord.xy, vec2(0.5, 0.75))) * 10.0) * 0.1;
gl_FragColor = vec4(col, 1.);
}`;
class Example extends Phaser.Scene
{
constructor()
{
super();
}
preload()
{
this.load.setBaseURL('https://cdn.phaserfiles.com/v385');
this.load.image('logo', 'assets/sprites/phaser3-logo-small.png');
this.load.image('mask', 'assets/tests/camera/grunge-mask.png');
}
create()
{
const maskImage = this.make.image({
x: 400,
y: 300,
key: 'mask',
add: false
});
const mask = maskImage.createBitmapMask();
this.cameras.main.setMask(mask, false);
const baseShader = new Phaser.Display.BaseShader('BufferShader', fragmentShader);
const shader = this.add.shader(baseShader, 400, 300, 800, 600);
this.add.image(400, 300, 'logo');
}
}
const config = {
type: Phaser.WEBGL,
parent: 'phaser-example',
width: 800,
height: 600,
scene: Example
};
const game = new Phaser.Game(config);