Skip to content

Optimize WebGL motion performance - #15

Merged
aomona merged 3 commits into
mainfrom
optimize/webgl-motion-performance
May 28, 2026
Merged

Optimize WebGL motion performance#15
aomona merged 3 commits into
mainfrom
optimize/webgl-motion-performance

Conversation

@aomona

@aomona aomona commented May 28, 2026

Copy link
Copy Markdown
Owner

Summary

  • stop the WebGL render loop when motion is disabled
  • move animated blob geometry calculations out of the fragment shader and into per-frame uniforms
  • add motionMaxPixelRatio and make animated defaults lighter with fps 30 and motionMaxPixelRatio 0.75
  • document the WebGL performance defaults and tuning options

Tests

  • npm run typecheck
  • npm test

Summary by CodeRabbit

Release Notes

  • New Features

    • Added motionMaxPixelRatio option to control device pixel density during animation playback
    • Added fps configuration option for motion control
  • Documentation

    • Updated WebGL usage guide with performance tuning recommendations
    • Added examples for lightweight animated presets with explicit configuration
    • Documented new animation configuration options
  • Tests

    • Enhanced test coverage for animation configuration resolution

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@aomona, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 46 minutes and 14 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ff89cce3-f961-4f85-a08d-f4f28798fc8b

📥 Commits

Reviewing files that changed from the base of the PR and between 590ef84 and dc2c11c.

📒 Files selected for processing (2)
  • docs/API.md
  • src/webgl.ts
📝 Walkthrough

Walkthrough

This PR introduces a new motionMaxPixelRatio option to cap device pixel density during WebGL animation, refactors the shader to compute blob geometry on the CPU, restructures the animation loop with motion-aware lifecycle management, and updates documentation with the new option and performance defaults.

Changes

Motion Pixel Ratio Optimization and Animation Refactor

Layer / File(s) Summary
Option type definitions and resolution
src/webgl.ts, tests/library.test.mjs
New motionMaxPixelRatio field added to both WebGLMeshGradientOptions and ResolvedWebGLMeshGradientOptions with clamping logic in the resolver, and test assertion verifies default resolution to 0.75.
Fragment shader refactoring for CPU-driven blob geometry
src/webgl.ts
Fragment shader updated to read layer-specific blob positions and sizes from u_positions/u_sizes uniforms provided by the CPU, removing in-shader motion offset and radius-boost calculations.
Animation loop and renderer refactoring
src/webgl.ts
Introduces CPU-updated animated geometry buffers (animatedPositions, animatedSizes) with updateAnimatedGeometry helper; refactors render timing and motion-aware draw loop; updates lifecycle methods (update, start, stop, resize) to conditionally manage animation loop based on motion.enabled and apply motionMaxPixelRatio as pixel ratio cap during motion.
React component memoization
src/webgl-react.tsx
Adds options.motionMaxPixelRatio to the webglKey dependency array so memoized WebGL computations re-run when this option changes.
API reference and usage documentation
docs/API.md, README.md
Updates API docs with new motionMaxPixelRatio and fps options in createWebGLMeshRenderer, renderer.update, and WebGLGrainGradient examples; adds performance notes and default tuning (fps: 30, motionMaxPixelRatio: 0.75); updates README with lightweight motion defaults and new animated fullscreen preset example showing explicit option usage.

Possibly Related PRs

  • aomona/grain-gradient#14: Extends the experimental WebGL renderer introduced in PR #14 by adding motionMaxPixelRatio performance tuning and refactoring the animation/uniform update flow with CPU-driven geometry buffers.

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 Pixels dance lighter when motion takes flight,
With CPU-drawn blobs, the shader shines bright.
Capped ratios twirl at 0.75 per frame,
Smooth animation and performance—a beautiful game! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Optimize WebGL motion performance' directly aligns with the primary objectives: stopping the render loop when motion is disabled, moving blob calculations to uniforms, and tuning motion performance defaults.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch optimize/webgl-motion-performance

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/webgl.ts (1)

366-376: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Reset the animation clock when motion is turned back on.

If this renderer has been running in static mode, startTime still points at the original start(). Re-enabling motion here makes the first animated frame jump away from the updateAnimatedGeometry(0) state that setStaticUniforms() just uploaded.

Suggested fix
       update(nextOptions) {
+        const wasMotionEnabled = motion.enabled;
         rawOptions = { ...rawOptions, ...nextOptions };
         options = resolveWebGLMeshGradientOptions(rawOptions);
         setStaticUniforms();
         renderer.resize();
         if (!running) return;
-        if (motion.enabled) requestLoop();
+        if (motion.enabled) {
+          if (!wasMotionEnabled) {
+            startTime = performance.now();
+            lastFrame = 0;
+          }
+          requestLoop();
+        }
         else {
           cancelLoop();
           render(performance.now());
         }
       },
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/webgl.ts` around lines 366 - 376, The update function merges options and
sets static uniforms but doesn't reset the animation clock when motion is
re-enabled; modify update (the block that checks motion.enabled/else) to detect
when motion.enabled is true and the renderer was previously not running or
motion was previously disabled, then set startTime = performance.now() (and
reset any related timing state like lastFrameTime if present) before calling
requestLoop(); reference the update function, motion.enabled, requestLoop,
cancelLoop, render, setStaticUniforms, and performance.now when making the
change.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/webgl.ts`:
- Around line 366-376: The update function merges options and sets static
uniforms but doesn't reset the animation clock when motion is re-enabled; modify
update (the block that checks motion.enabled/else) to detect when motion.enabled
is true and the renderer was previously not running or motion was previously
disabled, then set startTime = performance.now() (and reset any related timing
state like lastFrameTime if present) before calling requestLoop(); reference the
update function, motion.enabled, requestLoop, cancelLoop, render,
setStaticUniforms, and performance.now when making the change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 02f1c698-62b7-4791-962a-70b3a34bab0c

📥 Commits

Reviewing files that changed from the base of the PR and between 2952ba3 and 590ef84.

📒 Files selected for processing (5)
  • README.md
  • docs/API.md
  • src/webgl-react.tsx
  • src/webgl.ts
  • tests/library.test.mjs

@aomona
aomona merged commit cec4ce7 into main May 28, 2026
2 checks passed
@aomona
aomona deleted the optimize/webgl-motion-performance branch May 28, 2026 13:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant