introducing a lot of new operators

This commit is contained in:
2025-07-06 15:03:51 +02:00
parent ec8786ab9b
commit 3a5b38bd70
3 changed files with 68 additions and 7 deletions

View File

@ -56,6 +56,7 @@ class ShaderWorker {
private imageDataCache: LRUCache<string, ImageData> = new LRUCache(PERFORMANCE.IMAGE_DATA_CACHE_SIZE); private imageDataCache: LRUCache<string, ImageData> = new LRUCache(PERFORMANCE.IMAGE_DATA_CACHE_SIZE);
private compilationCache: LRUCache<string, ShaderFunction> = new LRUCache(PERFORMANCE.COMPILATION_CACHE_SIZE); private compilationCache: LRUCache<string, ShaderFunction> = new LRUCache(PERFORMANCE.COMPILATION_CACHE_SIZE);
private colorTables: Map<string, Uint8Array> = new Map(); private colorTables: Map<string, Uint8Array> = new Map();
private feedbackBuffer: Float32Array | null = null;
constructor() { constructor() {
self.onmessage = (e: MessageEvent<WorkerMessage>) => { self.onmessage = (e: MessageEvent<WorkerMessage>) => {
@ -156,6 +157,15 @@ class ShaderWorker {
'y', 'y',
't', 't',
'i', 'i',
'r',
'a',
'u',
'v',
'c',
'f',
'd',
'n',
'b',
'mouseX', 'mouseX',
'mouseY', 'mouseY',
'mousePressed', 'mousePressed',
@ -295,6 +305,11 @@ class ShaderWorker {
const data = imageData.data; const data = imageData.data;
const startTime = performance.now(); const startTime = performance.now();
const maxRenderTime = PERFORMANCE.MAX_RENDER_TIME_MS; const maxRenderTime = PERFORMANCE.MAX_RENDER_TIME_MS;
// Initialize feedback buffer if needed
if (!this.feedbackBuffer || this.feedbackBuffer.length !== width * height) {
this.feedbackBuffer = new Float32Array(width * height);
}
try { try {
// Use tiled rendering for better timeout handling // Use tiled rendering for better timeout handling
@ -392,11 +407,34 @@ class ShaderWorker {
const actualY = y + yOffset; const actualY = y + yOffset;
try { try {
// Calculate additional coordinate variables
const u = x / fullWidth;
const v = actualY / fullHeight;
const centerX = fullWidth / 2;
const centerY = fullHeight / 2;
const radius = Math.sqrt((x - centerX) ** 2 + (actualY - centerY) ** 2);
const angle = Math.atan2(actualY - centerY, x - centerX);
const maxDistance = Math.sqrt(centerX ** 2 + centerY ** 2);
const normalizedDistance = radius / maxDistance;
const frameCount = Math.floor(time * 60);
const manhattanDistance = Math.abs(x - centerX) + Math.abs(actualY - centerY);
const noise = (Math.sin(x * 0.1) * Math.cos(actualY * 0.1) + 1) * 0.5;
const feedbackValue = this.feedbackBuffer ? this.feedbackBuffer[pixelIndex] || 0 : 0;
const value = this.compiledFunction!( const value = this.compiledFunction!(
x, x,
actualY, actualY,
time, time,
pixelIndex, pixelIndex,
radius,
angle,
u,
v,
normalizedDistance,
frameCount,
manhattanDistance,
noise,
feedbackValue,
message.mouseX || 0, message.mouseX || 0,
message.mouseY || 0, message.mouseY || 0,
message.mousePressed ? 1 : 0, message.mousePressed ? 1 : 0,
@ -436,6 +474,11 @@ class ShaderWorker {
data[i + 1] = g; data[i + 1] = g;
data[i + 2] = b; data[i + 2] = b;
data[i + 3] = 255; data[i + 3] = 255;
// Update feedback buffer with current processed value
if (this.feedbackBuffer) {
this.feedbackBuffer[pixelIndex] = safeValue;
}
} catch (error) { } catch (error) {
data[i] = 0; data[i] = 0;
data[i + 1] = 0; data[i + 1] = 0;

View File

@ -58,6 +58,30 @@ export function HelpPopup() {
<p> <p>
<strong>i</strong> - Pixel index <strong>i</strong> - Pixel index
</p> </p>
<p>
<strong>r</strong> - Distance from center
</p>
<p>
<strong>a</strong> - Angle from center (radians)
</p>
<p>
<strong>u, v</strong> - Normalized coordinates (0.0 to 1.0)
</p>
<p>
<strong>c</strong> - Normalized center distance (0.0 to 1.0)
</p>
<p>
<strong>f</strong> - Frame count (discrete timing)
</p>
<p>
<strong>d</strong> - Manhattan distance from center
</p>
<p>
<strong>n</strong> - Noise value (0.0 to 1.0)
</p>
<p>
<strong>b</strong> - Previous frame's value (feedback)
</p>
<p> <p>
<strong>mouseX, mouseY</strong> - Mouse position (0.0 to 1.0) <strong>mouseX, mouseY</strong> - Mouse position (0.0 to 1.0)
</p> </p>

View File

@ -74,13 +74,7 @@ export function ShaderCanvas() {
// Handle animation // Handle animation
useEffect(() => { useEffect(() => {
if (shaderRef.current) { if (shaderRef.current) {
const hasTime = shader.code.includes('t'); shaderRef.current.startAnimation();
if (hasTime) {
shaderRef.current.startAnimation();
} else {
shaderRef.current.stopAnimation();
shaderRef.current.render(false);
}
} }
}, [shader.code]); }, [shader.code]);