mirror of
https://codeberg.org/uzu/strudel
synced 2026-07-21 20:55:12 -04:00
Refactor the uniform function and add documentation
This commit is contained in:
@@ -1,3 +1,16 @@
|
||||
# @strudel/shader
|
||||
|
||||
Helpers for drawing shader
|
||||
Helpers for drawing shader.
|
||||
|
||||
## Todos
|
||||
|
||||
Here are the things that needs to be implemented:
|
||||
|
||||
- [ ] Shader source error reporting
|
||||
- [ ] Shader import from url, like shadertoy or git
|
||||
- [ ] Display attribution
|
||||
- [ ] Compilation error reporting, e.g. to show the line number
|
||||
- [ ] Multiple instance and custom canvas position
|
||||
- [ ] Multiple program, to be swapped like a pattern
|
||||
- [ ] Texture inputs
|
||||
- [ ] Buffer inputs, e.g. to generate a texture
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
export {loadShader} from './shader.mjs';
|
||||
export * from './shader.mjs';
|
||||
export * from './uniform.mjs';
|
||||
|
||||
@@ -59,7 +59,7 @@ const decayModulation = (decay) => {
|
||||
|
||||
// Set an uniform value (from a pattern).
|
||||
export function setUniform(instanceName, name, value, position) {
|
||||
const instance = _instances[instanceName || 'default'];
|
||||
const instance = _instances[instanceName];
|
||||
if (!instance) {
|
||||
logger('[shader] not loaded yet', 'warning');
|
||||
return;
|
||||
@@ -104,7 +104,8 @@ function setupUniforms(uniforms, program) {
|
||||
const uname = name.replace('[0]', '');
|
||||
const count = uniform.count | 0;
|
||||
if (!uniforms[uname] || uniforms[uname].count != count) {
|
||||
// TODO: keep the previous value when the count change...
|
||||
// TODO: keep the previous values when the count change:
|
||||
// if the count decreased, then drop the excess, else append new values
|
||||
uniforms[uname] = {
|
||||
name,
|
||||
count,
|
||||
@@ -174,6 +175,7 @@ async function initializeShaderInstance(name, code) {
|
||||
updateUniforms(instance.drawFrame, elapsed, instance.uniforms);
|
||||
|
||||
instance.drawFrame.draw();
|
||||
// After sometime, if no update happened, stop the animation loop
|
||||
if (instance.age++ < 100) requestAnimationFrame(instance.update);
|
||||
else instance.drawing = false;
|
||||
};
|
||||
|
||||
+60
-12
@@ -7,27 +7,75 @@ This program is free software: you can redistribute it and/or modify it under th
|
||||
import { register, logger } from '@strudel/core';
|
||||
import { setUniform } from './shader.mjs';
|
||||
|
||||
export const uniform = register('uniform', (options, pat) => {
|
||||
// Keep track of the pitches value: Map String Int
|
||||
const pitches = { _count: 0 };
|
||||
/**
|
||||
* Update a shader. The destination name consist of
|
||||
*
|
||||
* - the uniform name
|
||||
* - optional array mapping, either a number or an assignment mode ('seq' or 'pitch')
|
||||
*
|
||||
* @name uniform
|
||||
* @example
|
||||
* s("bd").uniform("iColor")
|
||||
* @example
|
||||
* s("bd").uniform("iColors:seq")
|
||||
* @example
|
||||
* note("c3 e3").uniform("iMorph:pitch")
|
||||
*/
|
||||
function parseUniformTarget(name) {
|
||||
if (typeof name === 'string')
|
||||
return {name, mapping: 'single', position: 0}
|
||||
else if (name.length == 2) {
|
||||
const mapping = typeof name[1] === 'string' ? name[1] : 'single'
|
||||
const position = typeof name[1] === 'string' ? null : name[1]
|
||||
return {
|
||||
name: name[0],
|
||||
mapping,
|
||||
position
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Keep track of the pitches value per uniform
|
||||
let _pitches = {}
|
||||
export const uniform = register('uniform', (target, pat) => {
|
||||
// TODO: support multiple shader instance
|
||||
const instance = "default"
|
||||
|
||||
// Decode the uniform defintion
|
||||
const uniformTarget = parseUniformTarget(target)
|
||||
|
||||
// Get the pitches
|
||||
if (!_pitches[uniformTarget.name])
|
||||
_pitches[uniformTarget.name] = {_count: 0}
|
||||
const pitches = _pitches[uniformTarget.name]
|
||||
|
||||
return pat.onTrigger((time_deprecate, hap, currentTime, cps, targetTime) => {
|
||||
const instance = options.instance;
|
||||
// TODO: figure out how to get the desired value, e.g. is this pattern for pan, gain, velocity, ...
|
||||
const value = hap.value ? (hap.value.gain || 1.0) : 1.0;
|
||||
|
||||
const value = options.gain || 1.0;
|
||||
if (options.pitch !== undefined) {
|
||||
// Get the uniform mapping position
|
||||
let position = null
|
||||
if (uniformTarget.mapping == 'pitch') {
|
||||
// Assign one position per pitch
|
||||
const note = hap.value.note || hap.value.s;
|
||||
if (pitches[note] === undefined) {
|
||||
// Assign new value, the first note gets 0, then 1, then 2, ...
|
||||
pitches[note] = Object.keys(pitches).length;
|
||||
}
|
||||
setUniform(instance, options.pitch, value, pitches[note]);
|
||||
} else if (options.seq !== undefined) {
|
||||
setUniform(instance, options.seq, value, pitches._count++);
|
||||
} else if (options.uniform !== undefined) {
|
||||
setUniform(instance, options.uniform, value);
|
||||
position = pitches[note]
|
||||
} else if (uniformTarget.mapping == 'seq') {
|
||||
console.log("HERE", pitches)
|
||||
// Assign a new position per event
|
||||
position = pitches._count++
|
||||
} else if (uniformTarget.mapping == 'single') {
|
||||
// Assign a fixed position
|
||||
position = uniformTarget.position
|
||||
} else {
|
||||
console.error('Unknown shader options, need either pitch or uniform', options);
|
||||
console.error('Unknown uniform target', uniformTarget)
|
||||
}
|
||||
|
||||
// Update the uniform
|
||||
if (position !== null)
|
||||
setUniform(instance, uniformTarget.name, value, position);
|
||||
}, false);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user