This demo is a sandbox application to write effects and see them update in realtime on the right side.
async function runDemo()
{
// init shaku
await Shaku.init();
document.body.appendChild(Shaku.gfx.canvas);
___custom_effect_code___
// create custom effect instance and set as active
let effect;
try {
effect = new CustomEffect();
}
catch (e) {
document.body.innerHTML = e.toString() + " See developer console for details.";
}
// load textures
let texture = await Shaku.assets.loadTexture('assets/shaku.png');
// create a SpriteBatch
let spritesBatch = new Shaku.gfx.SpriteBatch(10);
// do a main loop step.
function step()
{
// make fullscreen
Shaku.gfx.maximizeCanvasSize(false);
// start frame and clear screen
Shaku.startFrame();
Shaku.gfx.clear(Shaku.utils.Color.cornflowerblue);
// custom updates code
CustomEffect.preRenderInit(effect, texture);
// draw with custom effect
spritesBatch.begin(undefined, effect);
const position = Shaku.gfx.getRenderingSize().mul(0.5, 0.5);
spritesBatch.drawSprite(Shaku.gfx.Sprite.build(texture, position, 400));
spritesBatch.end();
// end frame and request next frame
Shaku.endFrame();
Shaku.requestAnimationFrame(step);
}
// start main loop
step();
}
// start demo
runDemo();
// define our custom effect
// don't rename it from 'CustomEffect' or it won't work for this demo
class CustomEffect extends Shaku.gfx.SpritesEffect
{
/**
* Override the vertex shader for our custom effect.
*/
get vertexCode()
{
const vertexShader = `
attribute vec3 position;
attribute vec2 uv;
attribute vec4 color;
uniform mat4 projection;
uniform mat4 world;
varying vec2 v_texCoord;
varying vec4 v_color;
void main(void) {
gl_Position = projection * world * vec4(position, 1.0);
gl_PointSize = 1.0;
v_texCoord = uv;
v_color = color;
}
`;
return vertexShader;
}
/**
* Override the fragment shader for our custom effect.
*/
get fragmentCode()
{
const fragmentShader = `
#ifdef GL_ES
precision highp float;
#endif
uniform sampler2D mainTexture;
uniform float elapsedTime;
varying vec2 v_texCoord;
varying vec4 v_color;
void main(void) {
gl_FragColor = texture2D(mainTexture, v_texCoord) * v_color;
gl_FragColor.r *= sin(v_texCoord.y * 10.0 + elapsedTime) + 0.1;
gl_FragColor.g *= sin(1.8 + v_texCoord.y * 10.0 + elapsedTime) + 0.1;
gl_FragColor.b *= sin(3.6 + v_texCoord.y * 10.0 + elapsedTime) + 0.1;
gl_FragColor.rgb *= gl_FragColor.a;
}
`;
return fragmentShader;
}
/**
* Override the uniform types dictionary to add our custom uniform types.
*/
get uniformTypes()
{
let ret = super.uniformTypes;
ret['elapsedTime'] = { type: Shaku.gfx.Effect.UniformTypes.Float };
return ret;
}
/**
* This method is called before we render with the effect, to do custom setups
* It's not part of Shaku, its something we add for this specific demo.
*/
static preRenderInit(effectInstance, sprite)
{
// update effect custom uniform
effectInstance.uniforms.elapsedTime(Shaku.gameTime.elapsed);
}
}