Skip to content

Commit

Permalink
feat(webgl-shadertoy): fix & update drawPass viewport, add update() m…
Browse files Browse the repository at this point in the history
…ethod
  • Loading branch information
postspectacular committed Sep 18, 2019
1 parent 48b8906 commit 5d2c17e
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 34 deletions.
1 change: 1 addition & 0 deletions packages/webgl-shadertoy/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export interface ShaderToyOpts {
export interface ShaderToy {
start(): void;
stop(): void;
update(time?: number): void;
recompile(main: MainImageFn): void;
model: ModelSpec;
}
63 changes: 35 additions & 28 deletions packages/webgl-shadertoy/src/multipass.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
ShaderUniformSpecs,
texture,
TextureOpts,
UniformDecl,
UniformValues
} from "@thi.ng/webgl";
import { ShaderToy } from "./api";
Expand All @@ -39,10 +40,17 @@ export interface ShaderPipelinePassOpts {
fn: ShaderFn;
inputs: string[];
outputs: string[];
uniforms?: ShaderUniformSpecs;
uniforms?: Partial<PipelinePassUniforms>;
uniformVals?: UniformValues;
}

export interface PipelinePassUniforms {
resolution: "vec2";
time: "float";
inputs: ["sampler2D[]", number, number[]];
[id: string]: UniformDecl;
}

export const multipassToy = (opts: ShaderPipelineOpts) => {
const gl = opts.gl;
const isGL2 = isGL2Context(gl);
Expand Down Expand Up @@ -71,15 +79,11 @@ export const multipassToy = (opts: ShaderPipelineOpts) => {
attribs: {
position: "vec2"
},
uniforms: {
uniforms: <ShaderUniformSpecs>{
...passOpts.uniforms,
...(numIns
? {
inputs: [
"sampler2D[]",
numIns,
<any>[...range(numIns)]
]
inputs: ["sampler2D[]", numIns, [...range(numIns)]]
}
: null)
},
Expand Down Expand Up @@ -122,49 +126,52 @@ export const multipassToy = (opts: ShaderPipelineOpts) => {
const model = quad(false);
compileModel(gl, model);

let active: boolean;
let t0: number;

const drawPass = (i: number, res: number[], time: number) => {
const drawPass = (i: number, time: number) => {
const shader = shaders[i];
const pass = opts.passes[i];
const size = pass.outputs.length
? textures[pass.outputs[0]].size
: [gl.drawingBufferWidth, gl.drawingBufferHeight];
model.uniforms = {
...opts.passes[i].uniformVals
...pass.uniformVals
};
const shader = shaders[i];
shader.uniforms.resolution && (model.uniforms!.resolution = size);
shader.uniforms.time && (model.uniforms!.time = time);
shader.uniforms.resolution && (model.uniforms!.resolution = res);
model.shader = shader;
model.textures = opts.passes[i].inputs.map((id) => textures[id]);
model.textures = pass.inputs.map((id) => textures[id]);
gl.viewport(0, 0, size[0], size[1]);
draw(model);
};

const update = () => {
const w = gl.drawingBufferWidth;
const h = gl.drawingBufferHeight;
const time = (Date.now() - t0) * 1e-3;
const res = [w, h];

gl.viewport(0, 0, w, h);
const update = (time: number) => {
for (let i = 0; i < fbos.length; i++) {
fbos[i].bind();
drawPass(i, res, time);
drawPass(i, time);
fbos[i].unbind();
}
drawPass(shaders.length - 1, res, time);
drawPass(shaders.length - 1, time);
};

if (active) {
requestAnimationFrame(update);
}
const updateRAF = () => {
update((Date.now() - t0) * 1e-3);
active && requestAnimationFrame(updateRAF);
};

let active: boolean;
let t0 = Date.now();

const instance: ShaderToy = {
start() {
t0 = Date.now();
active = true;
requestAnimationFrame(update);
requestAnimationFrame(updateRAF);
},
stop() {
active = false;
},
update(time: number) {
update(time);
},
recompile() {},
model
};
Expand Down
16 changes: 10 additions & 6 deletions packages/webgl-shadertoy/src/shadertoy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,29 +39,33 @@ export const shaderToy = (opts: ShaderToyOpts) => {
let active: boolean;
let t0: number;

const update = () => {
const update = (time: number) => {
const w = gl.drawingBufferWidth;
const h = gl.drawingBufferHeight;
model.uniforms!.time = (Date.now() - t0) * 1e-3;
model.uniforms!.time = time;
model.uniforms!.resolution = [w, h];

gl.viewport(0, 0, w, h);
draw(model);
};

if (active) {
requestAnimationFrame(update);
}
const updateRAF = () => {
update((Date.now() - t0) * 1e-3);
active && requestAnimationFrame(updateRAF);
};

const instance: ShaderToy = {
start() {
t0 = Date.now();
active = true;
requestAnimationFrame(update);
requestAnimationFrame(updateRAF);
},
stop() {
active = false;
},
update(time: number) {
update(time);
},
recompile(main: MainImageFn) {
if (model.shader) {
model.shader.release();
Expand Down

0 comments on commit 5d2c17e

Please sign in to comment.