From f499b78fd5373989bb265992dc7a49bdfbe5fc2a Mon Sep 17 00:00:00 2001 From: Lobo Date: Fri, 20 Feb 2026 17:25:42 +0100 Subject: [PATCH] Adding uniform buffers But still resolution problem --- .../algorithms/pendulum/pendulum.component.ts | 51 +++++++------------ .../algorithms/pendulum/pendulum.shader.ts | 19 ++++--- .../canvas/babylon-canvas.component.ts | 2 + 3 files changed, 31 insertions(+), 41 deletions(-) diff --git a/src/app/pages/algorithms/pendulum/pendulum.component.ts b/src/app/pages/algorithms/pendulum/pendulum.component.ts index 3a22779..572474a 100644 --- a/src/app/pages/algorithms/pendulum/pendulum.component.ts +++ b/src/app/pages/algorithms/pendulum/pendulum.component.ts @@ -17,13 +17,15 @@ import {PENDULUM_FRAGMENT_SHADER_WGSL, PENDULUM_PHYSIC_COMPUTE_SHADER_WGSL, PEND styleUrl: './pendulum.component.scss', }) export class PendulumComponent { + renderConfig: RenderConfig = { mode: '2D', initialViewSize: 2, shaderLanguage: ShaderLanguage.WGSL, vertexShader: PENDULUM_VERTEX_SHADER_WGSL, fragmentShader: PENDULUM_FRAGMENT_SHADER_WGSL, - uniformNames: ["params"] + uniformNames: [], + uniformBufferNames: ["params"] }; onSceneReady(event: SceneReadyEvent) { @@ -36,17 +38,11 @@ export class PendulumComponent { const height = engine.getRenderHeight(); const totalPixels = width * height; - console.log("Width and Height ", width, height); - - // A. Buffer Setup - // 1. Pixel Buffer (wie gehabt) const pixelBuffer = new StorageBuffer(engine, totalPixels * 4); - // 2. State Buffer (4 Floats: theta1, theta2, v1, v2) const stateBuffer = new StorageBuffer(engine, 4 * 4); stateBuffer.update(new Float32Array([Math.PI / 4, Math.PI / 2, 0, 0])); - // 3. Params Uniform Buffer const ubo = new UniformBuffer(engine); ubo.addUniform("resolution", 2); ubo.addUniform("time", 1); @@ -57,13 +53,10 @@ export class PendulumComponent { ubo.addUniform("l1", 1); ubo.addUniform("l2", 1); ubo.addUniform("damping", 1); - ubo.addUniform("pad1", 1); //Alignment - ubo.addUniform("pad2", 1); //Alignment + ubo.addUniform("pad1", 1); + ubo.addUniform("pad2", 1); ubo.update(); - // B. Compute Shaders Setup - - // CS1: Physics const csPhysics = new ComputeShader("physics", engine, { computeSource: PENDULUM_PHYSIC_COMPUTE_SHADER_WGSL }, { @@ -75,7 +68,6 @@ export class PendulumComponent { csPhysics.setStorageBuffer("state", stateBuffer); csPhysics.setUniformBuffer("p", ubo); - // CS2: Render/Trail const csRender = new ComputeShader("render", engine, { computeSource: PENDULUM_RENDER_COMPUTE_SHADER_WGSL }, { @@ -89,7 +81,6 @@ export class PendulumComponent { csRender.setUniformBuffer("p", ubo); csRender.setStorageBuffer("state", stateBuffer); - // C. Material Setup (Anzeige) const plane = scene.getMeshByName("plane"); if (plane?.material) { const mat = plane.material as any; @@ -97,39 +88,33 @@ export class PendulumComponent { mat.setUniformBuffer("params", ubo); } - // D. Simulation Loop let time = 0; - - // Physik Parameter const dt = 0.015; - const g = 9.81; - const m1 = 2.0; - const m2 = 1.0; - const l1 = 1.5; - const l2 = 1.2; - const damping = 0.99; + // Du hast die Physik wieder drin gelassen, das ist super: scene.onBeforeRenderObservable.add(() => { time += dt; - // Update Params - ubo.updateFloat2("resolution", width, height); + const currentWidth = engine.getRenderWidth(); + const currentHeight = engine.getRenderHeight(); + + ubo.updateFloat2("resolution", currentWidth, currentHeight); ubo.updateFloat("time", time); ubo.updateFloat("dt", dt); - ubo.updateFloat("g", g); - ubo.updateFloat("m1", m1); - ubo.updateFloat("m2", m2); - ubo.updateFloat("l1", l1); - ubo.updateFloat("l2", l2); - ubo.updateFloat("damping", damping); + ubo.updateFloat("g", 9.81); + ubo.updateFloat("m1", 2.0); + ubo.updateFloat("m2", 1.0); + ubo.updateFloat("l1", 1.5); + ubo.updateFloat("l2", 1.2); + ubo.updateFloat("damping", 0.99); ubo.updateFloat("pad1", 0); ubo.updateFloat("pad2", 0); ubo.update(); - // Do physics (1 thread) + // Physik Dispatch an csPhysics.dispatch(1, 1, 1); - // Paint per pixel + const totalPixels = currentWidth * currentHeight; const dispatchCount = Math.ceil(totalPixels / 64); csRender.dispatch(dispatchCount, 1, 1); }); diff --git a/src/app/pages/algorithms/pendulum/pendulum.shader.ts b/src/app/pages/algorithms/pendulum/pendulum.shader.ts index c736647..a5fd52f 100644 --- a/src/app/pages/algorithms/pendulum/pendulum.shader.ts +++ b/src/app/pages/algorithms/pendulum/pendulum.shader.ts @@ -15,7 +15,7 @@ export const PENDULUM_FRAGMENT_SHADER_WGSL = ` varying vUV : vec2; var pixelBuffer : array; - var params : Params; + var params : Params; // Zurück zum bewährten Struct! struct Params { resolution: vec2, @@ -27,23 +27,26 @@ export const PENDULUM_FRAGMENT_SHADER_WGSL = ` l1: f32, l2: f32, damping: f32, - pad1: f32, // <-- Alignment - pad2: f32 // <-- Alignment + pad1: f32, + pad2: f32 }; @fragment fn main(input : FragmentInputs) -> FragmentOutputs { let width = u32(params.resolution.x); - let x = u32(input.vUV.x * params.resolution.x); - let y = u32(input.vUV.y * params.resolution.y); + let height = u32(params.resolution.y); + + // clamp schützt uns vor Abstürzen durch Rundungsfehler am Bildschirmrand + let x = clamp(u32(input.vUV.x * params.resolution.x), 0u, width - 1u); + let y = clamp(u32(input.vUV.y * params.resolution.y), 0u, height - 1u); + let index = y * width + x; let val = pixelBuffer[index]; - // Hintergrund = Dunkelgrau, Linien = Grau, Massen = Weiß var color = vec3(0.1, 0.1, 0.15); - if (val > 0.1) { color = vec3(0.5, 0.5, 0.5); } // Linie - if (val > 0.8) { color = vec3(1.0, 1.0, 1.0); } // Masse + if (val > 0.1) { color = vec3(0.5, 0.5, 0.5); } + if (val > 0.8) { color = vec3(1.0, 1.0, 1.0); } fragmentOutputs.color = vec4(color, 1.0); return fragmentOutputs; diff --git a/src/app/shared/rendering/canvas/babylon-canvas.component.ts b/src/app/shared/rendering/canvas/babylon-canvas.component.ts index 18dbd76..a0170f0 100644 --- a/src/app/shared/rendering/canvas/babylon-canvas.component.ts +++ b/src/app/shared/rendering/canvas/babylon-canvas.component.ts @@ -8,6 +8,7 @@ export interface RenderConfig { vertexShader: string; fragmentShader: string; uniformNames: string[]; + uniformBufferNames?: string[]; } export type RenderCallback = (material: ShaderMaterial, camera: Camera, canvas: HTMLCanvasElement, scene: Scene) => void; @@ -142,6 +143,7 @@ export class BabylonCanvas implements AfterViewInit, OnDestroy { { attributes: ["position", "uv"], uniforms: ["resolution", "cameraPosition", ...this.config.uniformNames], + uniformBuffers: this.config.uniformBufferNames ?? [], shaderLanguage: this.config.shaderLanguage ?? ShaderLanguage.GLSL } );