import * as PIXI from 'pixi.js';
const app = new PIXI.Application({ height: 640, resizeTo: window });
document.body.appendChild(app.view);
const geometry = new PIXI.Geometry()
.addAttribute('aVertexPosition',
[0, 0,
200, 0,
200, 200,
0, 200],
2)
.addAttribute('aUvs',
[0, 0,
1, 0,
1, 1,
0, 1],
2)
.addIndex([0, 1, 2, 0, 2, 3]);
const vertexSrc = `
precision mediump float;
attribute vec2 aVertexPosition;
attribute vec2 aUvs;
uniform mat3 translationMatrix;
uniform mat3 projectionMatrix;
varying vec2 vUvs;
void main() {
vUvs = aUvs;
gl_Position = vec4((projectionMatrix * translationMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);
}`;
const perlinTexture = PIXI.Texture.from('https://pixijs.com/assets/perlin.jpg');
const fragmentGridSrc = `
precision mediump float;
varying vec2 vUvs;
uniform float zoom;
void main()
{
//Generate a simple grid.
//Offset uv so that center is 0,0 and edges are -1,1
vec2 uv = (vUvs-vec2(0.5))*2.0;
vec2 gUv = floor(uv*zoom);
vec4 color1 = vec4(0.8, 0.8, 0.8, 1.0);
vec4 color2 = vec4(0.4, 0.4, 0.4, 1.0);
vec4 outColor = mod(gUv.x + gUv.y, 2.) < 0.5 ? color1 : color2;
gl_FragColor = outColor;
}`;
const gridUniforms = {
zoom: 10,
};
const gridShader = PIXI.Shader.from(vertexSrc, fragmentGridSrc, gridUniforms);
const gridTexture = PIXI.RenderTexture.create({ width: 200, height: 200 });
const gridQuad = new PIXI.Mesh(geometry, gridShader);
const gridContainer = new PIXI.Container();
gridContainer.addChild(gridQuad);
const fragmentRippleSrc = `
precision mediump float;
varying vec2 vUvs;
uniform float amount;
uniform float phase;
uniform sampler2D texIn;
void main()
{
//Generate a simple grid.
vec2 uv = vUvs;
//Calculate distance from center
float distance = length( uv - vec2(0.5));
vec4 color = texture2D(texIn, uv);
color.rgb *= sin(distance*25.0+phase) * amount+1.;
gl_FragColor = color;
}`;
const rippleUniforms = {
amount: 0.5,
phase: 0,
texIn: gridTexture,
};
const rippleShader = PIXI.Shader.from(vertexSrc, fragmentRippleSrc, rippleUniforms);
const rippleTexture = PIXI.RenderTexture.create({ width: 200, height: 200 });
const rippleQuad = new PIXI.Mesh(geometry, rippleShader);
const rippleContainer = new PIXI.Container();
rippleContainer.addChild(rippleQuad);
const fragmentNoiseSrc = `
precision mediump float;
varying vec2 vUvs;
uniform float limit;
uniform sampler2D noise;
void main()
{
float color = texture2D(noise, vUvs).r;
color = step(limit, color);
gl_FragColor = vec4(color);
}`;
const noiseUniforms = {
limit: 0.5,
noise: perlinTexture,
};
const noiseShader = PIXI.Shader.from(vertexSrc, fragmentNoiseSrc, noiseUniforms);
const noiseTexture = PIXI.RenderTexture.create({ width: 200, height: 200 });
const noiseQuad = new PIXI.Mesh(geometry, noiseShader);
const noiseContainer = new PIXI.Container();
noiseContainer.addChild(noiseQuad);
const fragmentWaveSrc = `
precision mediump float;
varying vec2 vUvs;
uniform float amplitude;
uniform float time;
void main()
{
//Offset uv so that center is 0,0 and edges are -1,1
vec2 uv = (vUvs-vec2(0.5))*2.0;
vec3 outColor = vec3(0.);
//Simple wavefunctions inversed and with small offsets.
outColor += 5./length(uv.y*200. - 50.0*sin( uv.x*0.25+ time*0.25)*amplitude);
outColor += 4./length(uv.y*300. - 100.0*sin(uv.x*0.5+time*0.5)*amplitude*1.2);
outColor += 3./length(uv.y*400. - 150.0*sin(uv.x*0.75+time*0.75)*amplitude*1.4);
outColor += 2./length(uv.y*500. - 200.0*sin(uv.x+time)*amplitude*1.6);
gl_FragColor = vec4(outColor,1.0);
}`;
const waveUniforms = {
amplitude: 0.75,
time: 0,
};
const waveShader = PIXI.Shader.from(vertexSrc, fragmentWaveSrc, waveUniforms);
const waveTexture = PIXI.RenderTexture.create({ width: 200, height: 200 });
const waveQuad = new PIXI.Mesh(geometry, waveShader);
const waveContainer = new PIXI.Container();
waveContainer.addChild(waveQuad);
const fragmentCombineSrc = `
precision mediump float;
varying vec2 vUvs;
uniform sampler2D texRipple;
uniform sampler2D texNoise;
uniform sampler2D texWave;
void main()
{
//Read color from all
vec4 ripple = texture2D(texRipple, vUvs);
vec4 noise = texture2D(texNoise, vUvs);
vec4 wave = texture2D(texWave, vUvs);
gl_FragColor = mix(ripple, wave,noise.r);
}`;
const combineUniforms = {
texRipple: rippleTexture,
texNoise: noiseTexture,
texWave: waveTexture,
};
const combineShader = PIXI.Shader.from(vertexSrc, fragmentCombineSrc, combineUniforms);
const combineQuad = new PIXI.Mesh(geometry, combineShader);
gridContainer.position.set(10, 10);
rippleContainer.position.set(220, 10);
noiseContainer.position.set(10, 220);
waveContainer.position.set(10, 430);
combineQuad.position.set(430, 220);
app.stage.addChild(gridContainer);
app.stage.addChild(rippleContainer);
app.stage.addChild(noiseContainer);
app.stage.addChild(waveContainer);
app.stage.addChild(combineQuad);
let time = 0;
app.ticker.add((delta) =>
{
time += 1 / 60;
rippleQuad.shader.uniforms.phase = -time;
waveQuad.shader.uniforms.time = time;
noiseQuad.shader.uniforms.limit = Math.sin(time * 0.5) * 0.35 + 0.5;
app.renderer.render(gridQuad, { renderTexture: gridTexture });
app.renderer.render(rippleQuad, { renderTexture: rippleTexture });
app.renderer.render(noiseQuad, { renderTexture: noiseTexture });
app.renderer.render(waveQuad, { renderTexture: waveTexture });
});