Add experimental WebGL mesh renderer - #14
Conversation
|
Warning Review limit reached
More reviews will be available in 17 minutes and 59 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 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 configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughThis PR adds experimental WebGL-based mesh gradient rendering as an alternative to the default CSS/SVG renderer. Core changes include a new WebGL renderer implementation with React component wrapper, simplification of CSS motion keyframes to transform-only, playground integration with mode switching, and comprehensive documentation. ChangesWebGL Renderer Feature Addition
Sequence DiagramsequenceDiagram
participant User
participant Playground
participant WebGLGrainGradient
participant createWebGLMeshRenderer
participant Canvas
participant WebGLProgram
User->>Playground: select WebGL renderer mode
Playground->>WebGLGrainGradient: mount with WebGL options
WebGLGrainGradient->>Canvas: ref.current acquired
WebGLGrainGradient->>createWebGLMeshRenderer: create renderer with canvas
createWebGLMeshRenderer->>WebGLProgram: compile shaders, link program
createWebGLMeshRenderer->>WebGLProgram: set uniforms (colors, motion, resolution)
createWebGLMeshRenderer-->>WebGLGrainGradient: return renderer
WebGLGrainGradient->>Canvas: renderer.start()
Canvas->>WebGLProgram: requestAnimationFrame loop (fps throttled)
WebGLProgram->>Canvas: draw animated mesh gradient
Canvas-->>User: WebGL canvas visible
User->>Playground: switch back to CSS mode
Playground->>Canvas: renderer.stop(), renderer.destroy()
Playground->>Canvas: show CSS/SVG fallback
Estimated Code Review Effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly Related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (2)
README.md (2)
81-103: ⚡ Quick winConsider documenting SSR constraints explicitly.
The phrase "CSS/SVG renderer remains the SSR-safe fallback" implies WebGL is not SSR-safe, but this constraint isn't stated explicitly. Since the React section above provides detailed SSR guidance with user-agent examples (lines 66-77), users might expect similar guidance here.
Consider adding a brief note that WebGL components require a browser environment and should be wrapped in client-only boundaries for SSR frameworks (e.g., Next.js
'use client'directive or dynamic imports withssr: false).📝 Example addition
After line 83, add:
For SSR frameworks, ensure the WebGL component renders client-side only: \`\`\`tsx // Next.js example import dynamic from 'next/dynamic'; const WebGLGrainGradient = dynamic( () => import('grain-gradient/webgl/react').then(mod => mod.WebGLGrainGradient), { ssr: false } ); \`\`\`🤖 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 `@README.md` around lines 81 - 103, Add an explicit SSR note to the WebGL experimental section stating that WebGL components (e.g., WebGLGrainGradient) require a browser environment and must be rendered client-side only; update the text after the WebGL paragraph to instruct users to wrap these components in client-only boundaries (for example using Next.js "use client" in a client component or dynamic imports with ssr: false) and include a concise Next.js example referencing WebGLGrainGradient so readers know how to safely render it in SSR frameworks.
95-95: 💤 Low valueConsider adding a brief explanation of
maxPixelRatio.The
maxPixelRatioprop purpose may not be immediately clear to users. A brief inline comment or sentence explaining it controls canvas resolution (e.g., "caps canvas pixel density for performance") would improve discoverability.🤖 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 `@README.md` at line 95, Add a short explanatory note next to the maxPixelRatio prop to clarify its purpose: mention that maxPixelRatio controls the canvas pixel density (device pixel ratio) and is used to cap rendering resolution for performance (e.g., to avoid excessive GPU/CPU usage on high-DPI displays). Update the README example where maxPixelRatio={1.25} appears to include a one-line comment or parenthetical sentence describing this behavior and recommended usage.
🤖 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.
Inline comments:
In `@playground/index.html`:
- Around line 936-942: The ready message in render() unconditionally overwrites
any error/fallback set by ensureWebGLRenderer(); modify the logic so
setFeedback("ready", ...) is only called when no renderer error occurred — for
example have ensureWebGLRenderer() return a success boolean or set
state.renderer to "error" on failure, then in render() only call
setFeedback("ready", ...) when that success flag is true (or when state.renderer
!== "error") and preserve existing feedback otherwise; update references to
ensureWebGLRenderer(), render(), setFeedback(), and state.renderer accordingly.
- Around line 760-768: The webglcontextlost handler falls back UI to CSS but
doesn't update the application state, so update the shared renderer state when
handling the event: inside the "webglcontextlost" listener (the block that calls
webglRenderer?.destroy(), sets canvas.dataset.ready and
elements.preview.dataset.renderer, and calls setFeedback), also set
state.renderer = "css" (and if you have a state.ready or similar flag, set it
false) so controls reflect the CSS renderer; ensure any UI-binding code that
reads state.renderer will now show the correct selection.
In `@src/webgl.ts`:
- Around line 321-323: The update(nextOptions) method currently replaces options
wholesale; instead merge the incoming partial nextOptions into the existing
options before resolving so unspecified fields are preserved. In the update
function, merge nextOptions into the current options object (e.g., Object.assign
or spread) and then call resolveWebGLMeshGradientOptions with the merged object,
then call setStaticUniforms(); ensure you update references to the same options
variable used elsewhere so partial patches (like only swirl) do not reset
colors/motion/etc.
---
Nitpick comments:
In `@README.md`:
- Around line 81-103: Add an explicit SSR note to the WebGL experimental section
stating that WebGL components (e.g., WebGLGrainGradient) require a browser
environment and must be rendered client-side only; update the text after the
WebGL paragraph to instruct users to wrap these components in client-only
boundaries (for example using Next.js "use client" in a client component or
dynamic imports with ssr: false) and include a concise Next.js example
referencing WebGLGrainGradient so readers know how to safely render it in SSR
frameworks.
- Line 95: Add a short explanatory note next to the maxPixelRatio prop to
clarify its purpose: mention that maxPixelRatio controls the canvas pixel
density (device pixel ratio) and is used to cap rendering resolution for
performance (e.g., to avoid excessive GPU/CPU usage on high-DPI displays).
Update the README example where maxPixelRatio={1.25} appears to include a
one-line comment or parenthetical sentence describing this behavior and
recommended usage.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: d1118c9d-d07c-432b-a176-eb15d484e9fa
📒 Files selected for processing (9)
README.mddocs/API.mdpackage.jsonplayground/index.htmlsrc/core.tssrc/react.tsxsrc/webgl-react.tsxsrc/webgl.tstests/library.test.mjs
Summary
grain-gradient/webglandgrain-gradient/webgl/reactValidation
Notes
Summary by CodeRabbit
Release Notes
New Features
WebGLGrainGradientReact component for WebGL mesh gradient renderingDocumentation
Improvements