Skip to content
This repository was archived by the owner on Jun 19, 2025. It is now read-only.

Commit f8a2414

Browse files
Add uniform pattern function doc
1 parent 1baa6da commit f8a2414

File tree

2 files changed

+41
-14
lines changed

2 files changed

+41
-14
lines changed

packages/shader/shader.mjs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class UniformValue {
4444

4545
get(elapsed) {
4646
// Adjust the value according to the rate of change
47-
const offset = (this.desired - this.value) / (this.slow * Math.min(1, elapsed * 60));
47+
const offset = (this.desired - this.value) / (this.slow * Math.max(1, elapsed * 60));
4848
// Ignore small changes
4949
if (Math.abs(offset) > 1e-3) this.value += offset;
5050
return this.value;
@@ -72,7 +72,6 @@ export function setUniform(instanceName, name, value, incr, position, slow) {
7272
uniformValue = uniform.value[idx];
7373
}
7474
uniformValue.slow = slow;
75-
// TODO: handle direct assignment, this is incrementing by default
7675
if (incr) uniformValue.desired += value;
7776
else uniformValue.desired = value;
7877
} else {

packages/shader/uniform.mjs

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,31 @@ Copyright (C) 2024 Strudel contributors
44
This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
55
*/
66

7-
import { Pattern, reify, register, logger } from '@strudel/core';
7+
import { reify, register, logger } from '@strudel/core';
88
import { setUniform } from './shader.mjs';
99

1010
/**
11-
* Update a shader.
11+
* Update a shader uniform value. A uniform name consists of
12+
*
13+
* - a name
14+
* - optional array position seperated by ':'. The position can be an index number, or 'seq' | 'random' to assign a different index per events.
15+
*
16+
* The uniform can also be configured with an object to pass extra options:
1217
*
1318
* @name uniform
19+
* @param {string} name: the uniform name and optional position.
20+
* @param {number} gain: the value multiplier - defaults to 1.
21+
* @param {number} slow: the value change rate, set to 1 for instant update - defaults to 10.
22+
* @param {boolean} onTrigger: update the uniform only when the pattern trigger. In that case, the uniform position is mapped to the event note/sound when it is not explicity set.
23+
*
1424
* @example
1525
* pan(sine.uniform("iColor"))
1626
* @example
17-
* gain("<.5 .3>".uniform("rotations:seq"))
27+
* gain(".5 .3").uniform("mod:0 mod:1")
1828
* @example
19-
* s("bd sd").uniform({onTrigger: true, dest: "moveFWD"})
29+
* dist("<.5 .3>".uniform("rotations:seq"))
30+
* @example
31+
* s("bd sd").uniform({name: 'rotations', gain: 0.2, slow: "<5 20>", onTrigger: true})
2032
*/
2133
export const uniform = register('uniform', (options, pat) => {
2234
// The shader instance name
@@ -25,13 +37,7 @@ export const uniform = register('uniform', (options, pat) => {
2537
// Are the uniform updated on trigger
2638
const onTrigger = options.onTrigger || false;
2739

28-
const setCtx = (uniformParam) => (ctx) => ({
29-
uniformParam,
30-
onTrigger: () => {},
31-
dominantTrigger: true,
32-
...ctx,
33-
});
34-
40+
// Helper to assign uniform position
3541
const pitches = { _count: 0 };
3642
const getPosition = (value, dest) => {
3743
if (typeof dest === 'number') return dest;
@@ -45,9 +51,10 @@ export const uniform = register('uniform', (options, pat) => {
4551
}
4652
return pitches[note];
4753
} else {
48-
throw 'Invalid position' + dest;
54+
logger('Invalid position' + dest, 'error');
4955
}
5056
};
57+
// Helper to decode the uniform position
5158
const getUniformPosition = (value, dest) => {
5259
if (typeof dest === 'string') {
5360
return [dest, 0];
@@ -56,15 +63,31 @@ export const uniform = register('uniform', (options, pat) => {
5663
}
5764
};
5865

66+
// The option pattern context
67+
const setCtx = (uniformParam) => (ctx) => ({
68+
// The option name
69+
uniformParam,
70+
// Disable event trigger
71+
onTrigger: () => {},
72+
dominantTrigger: true,
73+
...ctx,
74+
});
75+
76+
// Collect the option patterns
5977
const optionsPats = [];
6078
if (Array.isArray(options) || typeof options === 'string')
6179
optionsPats.push(reify(options).withContext(setCtx('dest')));
6280
else {
81+
// dest was the initial name, that can be removed
6382
if (options.dest) optionsPats.push(reify(options.dest).withContext(setCtx('dest')));
83+
if (options.name) optionsPats.push(reify(options.name).withContext(setCtx('dest')));
6484
if (options.gain) optionsPats.push(reify(options.gain).withContext(setCtx('gain')));
6585
if (options.slow) optionsPats.push(reify(options.slow).withContext(setCtx('slow')));
6686
}
87+
88+
// Run the base pattern along with all the options
6789
return stack(pat, ...optionsPats).withHaps((haps) => {
90+
// Collect the current options
6891
let dest;
6992
let gain = 1;
7093
let slow = 10;
@@ -80,18 +103,23 @@ export const uniform = register('uniform', (options, pat) => {
80103
source = hap;
81104
}
82105
});
106+
83107
if (dest && source) {
84108
if (onTrigger) {
109+
// Set the uniform when the source trigger
85110
source.context.onTrigger = (_, hap) => {
86111
const [uniform, position] = getUniformPosition(hap.value, dest);
87112
setUniform(instance, uniform, (hap.value.gain || 1) * gain, true, position, slow);
88113
};
89114
source.context.dominantTrigger = false;
90115
} else {
116+
// Set the uniform now.
91117
const [uniform, position] = getUniformPosition(source.value, dest);
92118
setUniform(instance, uniform, source.value * gain, false, position, slow);
93119
}
94120
}
121+
122+
// The options haps are kept so that the current values are highlighted on screen
95123
return haps;
96124
});
97125
});

0 commit comments

Comments
 (0)