Skip to content

feat: 增加 WebGL 动态壁纸支持 - #641

Open
March7th-OvO wants to merge 2 commits into
CuteLeaf:masterfrom
March7th-OvO:codex/webgl-wallpaper-upstream
Open

March7th-OvO wants to merge 2 commits into
CuteLeaf:masterfrom
March7th-OvO:codex/webgl-wallpaper-upstream

Conversation

@March7th-OvO

@March7th-OvO March7th-OvO commented Sep 14, 2026 •

Copy link
Copy Markdown

新增可配置的 WebGL 动态壁纸模式、按需加载与资源释放的场景宿主。提供 Cloud Train 与通用片元着色器场景,WebGL 不可用时保留图片壁纸回退;并接入布局、导航栏、显示设置、国际化和文档。\n\n验证:pnpm check、pnpm type-check、pnpm build。

Sourcery 总结

新增可配置的 WebGL 动态壁纸,支持可扩展场景、优雅的图像回退机制以及集成的显示设置。

新功能:

  • 新增可配置的 WebGL 壁纸模式,支持延迟加载的 Cloud Train 和自定义片段着色器场景。
  • 提供 WebGL 壁纸设置集成,支持共享的全屏布局、导航行为、本地化以及回退图像渲染。

错误修复:

  • 当 WebGL 2 不可用、场景加载失败、着色器编译失败或图形上下文中断时,保留现有的图像壁纸。

增强功能:

  • 管理 WebGL 场景生命周期、动画暂停、减少动态效果行为、响应式渲染以及 GPU 资源清理。

文档:

  • 记录 WebGL 壁纸配置、自定义着色器和可扩展场景模块。
Original summary in English

Sourcery 摘要

新增可扩展的 WebGL 动态壁纸,支持优雅的图像回退机制,并集成显示设置。

新功能:

  • 添加可配置的 WebGL 壁纸模式,支持延迟加载 Cloud Train 和自定义片段着色器场景。
  • 通过显示设置提供 WebGL 壁纸选择,并支持共享的全屏布局、导航行为、本地化和图像回退渲染。

Bug 修复:

  • 当 WebGL 不可用,或场景、着色器或图形上下文发生故障时,保留现有的图像壁纸。

增强功能:

  • 管理 WebGL 场景生命周期、动画暂停、减少动态效果行为、自适应渲染和 GPU 资源清理。

文档:

  • 记录 WebGL 壁纸配置、自定义着色器和可扩展场景模块。
Original summary in English

Summary by Sourcery

Add extensible WebGL dynamic wallpapers with graceful image fallback and integrated display settings.

New Features:

  • Add a configurable WebGL wallpaper mode with lazy-loaded Cloud Train and custom fragment-shader scenes.
  • Expose WebGL wallpaper selection through display settings with shared fullscreen layouts, navigation behavior, localization, and image fallback rendering.

Bug Fixes:

  • Preserve the existing image wallpaper when WebGL is unavailable or a scene, shader, or graphics context fails.

Enhancements:

  • Manage WebGL scene lifecycle, animation pausing, reduced-motion behavior, responsive rendering, and GPU resource cleanup.

Documentation:

  • Document WebGL wallpaper configuration, custom shaders, and extensible scene modules.

@netlify

netlify Bot commented Sep 14, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for demo-firefly ready!

Name Link
🔨 Latest commit bcb648f
🔍 Latest deploy log https://app.netlify.com/projects/demo-firefly/deploys/6aa7fdfefea7b60008d307a3
😎 Deploy Preview https://deploy-preview-641--demo-firefly.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@sourcery-ai

sourcery-ai Bot commented Sep 14, 2026 •

Copy link
Copy Markdown

审查者指南

该 PR 引入了一个可配置的 WebGL 动态壁纸系统:通过通用场景宿主按需加载 Cloud Train 或外部片元着色器,负责首帧回退、生命周期与 GPU 资源释放,并将 webgl 模式完整接入布局、显示设置、导航栏、样式、国际化和文档。

WebGL 壁纸加载与回退时序图

sequenceDiagram
    participant User
    participant Settings as DisplaySettingsIntegrated
    participant Host as WebGLWallpaperHost
    participant Loader as SceneLoader
    participant Scene as WebGLScene
    participant Image as ImageFallback

    User->>Settings: switchWallpaperMode(WALLPAPER_WEBGL)
    Settings->>Host: wallpaperModeChange
    Host->>Loader: loadScene()
    Loader-->>Host: scene module
    Host->>Scene: createScene(context)
    Scene->>Scene: WebGL2 initialization and first frame
    alt first frame succeeds
        Scene-->>Host: onFirstFrame()
        Host-->>Image: hide fallback image
    else WebGL unavailable or scene fails
        Scene-->>Host: error
        Host-->>Image: keep fallback image visible
    end
    User->>Settings: leave WebGL mode
    Settings->>Host: wallpaperModeChange
    Host->>Scene: dispose()
    Host->>Host: abort pending load and remove canvas
Loading

文件级变更

变更 详细信息 文件
新增可配置、按需加载且可安全销毁的 WebGL 壁纸场景体系。
  • 扩展壁纸配置与类型,增加 webgl 模式及场景参数。
  • 通过 import.meta.glob 按场景懒加载,并用 AbortController、generation 校验和 dispose 管理切换及页面生命周期。
  • 首帧成功前保留图片回退,WebGL 不可用、加载失败或着色器失败时降级。
  • 定义通用场景接口,支持 Cloud Train 多通道反馈渲染和外部片元着色器场景。
  • 处理画布尺寸、DPR、可见性、减少动态效果、性能质量分级及 WebGL context 丢失恢复。
src/utils/webgl-wallpaper/host.ts
src/utils/webgl-wallpaper/types.ts
src/utils/webgl-wallpaper/scenes/cloud-train.ts
src/utils/webgl-wallpaper/scenes/fragment.ts
public/assets/shaders/example-wallpaper.frag
将 WebGL 壁纸接入显示设置、布局状态和运行时壁纸切换。
  • 新增 WebGL 壁纸模式常量、联合类型、默认 Cloud Train 配置和显示设置入口。
  • 让 WebGL 复用全屏图片的 classic/hero 布局、标题、导航栏、波纹及卡片相关设置。
  • 在布局初始化中注册宿主,并在壁纸容器内持久化 WebGL host,同时保留图片回退。
  • 扩展壁纸可见性、模式同步、全屏覆盖层及导航栏透明度逻辑。
src/components/controls/DisplaySettingsIntegrated.svelte
src/components/layout/WallpaperSection.astro
src/components/layout/Navbar.astro
src/config/backgroundWallpaper.ts
src/config/displaySettingsConfig.ts
src/constants/constants.ts
src/layouts/Layout.astro
src/types/backgroundWallpaper.ts
src/types/displaySettingsConfig.ts
src/types/siteConfig.ts
src/utils/banner-utils.ts
src/utils/banner-visibility-utils.ts
src/utils/fullscreen-wallpaper-utils.ts
src/utils/layout-init.ts
src/utils/setting-utils.ts
完善 WebGL 模式的全屏样式与多语言支持。
  • 将全屏定位、classic/hero 内容流、导航栏、波纹、渐变、暗色文字和回退图片样式扩展到 webgl。
  • 首帧完成后隐藏图片,画布保持覆盖层级且不拦截交互。
  • 补充 WebGL 模式的中英文、日文、韩文、俄文及简繁中文标签。
src/styles/layout-base.css
src/styles/layout-styles.css
src/styles/main.css
src/styles/waves.css
src/i18n/i18nKey.ts
src/i18n/languages/en.ts
src/i18n/languages/ja.ts
src/i18n/languages/ko.ts
src/i18n/languages/ru.ts
src/i18n/languages/zh_CN.ts
src/i18n/languages/zh_TW.ts
提供 WebGL 壁纸配置、扩展开发和回退行为文档。
  • 记录模式配置、Cloud Train 参数范围、减少动态效果及资源释放行为。
  • 说明外部片元着色器的接口约束和 URL 加载方式。
  • 说明新增场景模块的工厂接口、首帧通知、dispose 和异步取消要求。
docs/WEBGL-WALLPAPER.md

提示与命令

与 Sourcery 交互

  • 触发新的审查: 在 pull request 中评论 @sourcery-ai review。
  • 继续讨论: 直接回复 Sourcery 的审查评论。
  • 根据审查评论生成 GitHub issue: 回复审查评论,请 Sourcery 根据该评论创建 issue。你也可以回复 @sourcery-ai issue,根据该评论创建 issue。
  • 生成 pull request 标题: 在 pull request 标题的任意位置输入 @sourcery-ai,即可随时生成标题。你也可以在 pull request 中评论 @sourcery-ai title,随时重新生成标题。
  • 生成 pull request 摘要: 在 pull request 正文中需要生成摘要的位置输入 @sourcery-ai summary,即可在指定位置随时生成 PR 摘要。你也可以在 pull request 中评论 @sourcery-ai summary,随时重新生成摘要。
  • 生成审查者指南: 在 pull request 中评论 @sourcery-ai guide,即可随时重新生成审查者指南。
  • 解决所有 Sourcery 评论: 在 pull request 中评论 @sourcery-ai resolve,即可解决所有 Sourcery 评论。如果你已经处理完所有评论且不想再看到它们,此功能会很有用。
  • 忽略所有 Sourcery 审查: 在 pull request 中评论 @sourcery-ai dismiss,即可忽略所有现有的 Sourcery 审查。如果你想从新的审查开始,这一功能尤其有用——别忘了评论 @sourcery-ai review 以触发新的审查!

自定义使用体验

访问你的控制面板以:

  • 启用或停用审查功能,例如 Sourcery 生成的 pull request 摘要、审查者指南等。
  • 更改审查语言。
  • 添加、移除或编辑自定义审查说明。
  • 调整其他审查设置。

获取帮助

Original review guide in English

Reviewer's Guide

该 PR 引入了一个可配置的 WebGL 动态壁纸系统:通过通用场景宿主按需加载 Cloud Train 或外部片元着色器,负责首帧回退、生命周期与 GPU 资源释放,并将 webgl 模式完整接入布局、显示设置、导航栏、样式、国际化和文档。

Sequence diagram for WebGL wallpaper loading and fallback

sequenceDiagram
    participant User
    participant Settings as DisplaySettingsIntegrated
    participant Host as WebGLWallpaperHost
    participant Loader as SceneLoader
    participant Scene as WebGLScene
    participant Image as ImageFallback

    User->>Settings: switchWallpaperMode(WALLPAPER_WEBGL)
    Settings->>Host: wallpaperModeChange
    Host->>Loader: loadScene()
    Loader-->>Host: scene module
    Host->>Scene: createScene(context)
    Scene->>Scene: WebGL2 initialization and first frame
    alt first frame succeeds
        Scene-->>Host: onFirstFrame()
        Host-->>Image: hide fallback image
    else WebGL unavailable or scene fails
        Scene-->>Host: error
        Host-->>Image: keep fallback image visible
    end
    User->>Settings: leave WebGL mode
    Settings->>Host: wallpaperModeChange
    Host->>Scene: dispose()
    Host->>Host: abort pending load and remove canvas
Loading

File-Level Changes

Change Details Files
新增可配置、按需加载且可安全销毁的 WebGL 壁纸场景体系。
  • 扩展壁纸配置与类型,增加 webgl 模式及场景参数。
  • 通过 import.meta.glob 按场景懒加载,并用 AbortController、generation 校验和 dispose 管理切换及页面生命周期。
  • 首帧成功前保留图片回退,WebGL 不可用、加载失败或着色器失败时降级。
  • 定义通用场景接口,支持 Cloud Train 多通道反馈渲染和外部片元着色器场景。
  • 处理画布尺寸、DPR、可见性、减少动态效果、性能质量分级及 WebGL context 丢失恢复。
src/utils/webgl-wallpaper/host.ts
src/utils/webgl-wallpaper/types.ts
src/utils/webgl-wallpaper/scenes/cloud-train.ts
src/utils/webgl-wallpaper/scenes/fragment.ts
public/assets/shaders/example-wallpaper.frag
将 WebGL 壁纸接入显示设置、布局状态和运行时壁纸切换。
  • 新增 WebGL 壁纸模式常量、联合类型、默认 Cloud Train 配置和显示设置入口。
  • 让 WebGL 复用全屏图片的 classic/hero 布局、标题、导航栏、波纹及卡片相关设置。
  • 在布局初始化中注册宿主,并在壁纸容器内持久化 WebGL host,同时保留图片回退。
  • 扩展壁纸可见性、模式同步、全屏覆盖层及导航栏透明度逻辑。
src/components/controls/DisplaySettingsIntegrated.svelte
src/components/layout/WallpaperSection.astro
src/components/layout/Navbar.astro
src/config/backgroundWallpaper.ts
src/config/displaySettingsConfig.ts
src/constants/constants.ts
src/layouts/Layout.astro
src/types/backgroundWallpaper.ts
src/types/displaySettingsConfig.ts
src/types/siteConfig.ts
src/utils/banner-utils.ts
src/utils/banner-visibility-utils.ts
src/utils/fullscreen-wallpaper-utils.ts
src/utils/layout-init.ts
src/utils/setting-utils.ts
完善 WebGL 模式的全屏样式与多语言支持。
  • 将全屏定位、classic/hero 内容流、导航栏、波纹、渐变、暗色文字和回退图片样式扩展到 webgl。
  • 首帧完成后隐藏图片,画布保持覆盖层级且不拦截交互。
  • 补充 WebGL 模式的中英文、日文、韩文、俄文及简繁中文标签。
src/styles/layout-base.css
src/styles/layout-styles.css
src/styles/main.css
src/styles/waves.css
src/i18n/i18nKey.ts
src/i18n/languages/en.ts
src/i18n/languages/ja.ts
src/i18n/languages/ko.ts
src/i18n/languages/ru.ts
src/i18n/languages/zh_CN.ts
src/i18n/languages/zh_TW.ts
提供 WebGL 壁纸配置、扩展开发和回退行为文档。
  • 记录模式配置、Cloud Train 参数范围、减少动态效果及资源释放行为。
  • 说明外部片元着色器的接口约束和 URL 加载方式。
  • 说明新增场景模块的工厂接口、首帧通知、dispose 和异步取消要求。
docs/WEBGL-WALLPAPER.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai 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.

嘿——我发现了 1 个问题

面向 AI Agent 的提示
请处理本次代码审查中的评论:

## 具体评论

### 评论 1
<location path="src/utils/webgl-wallpaper/scenes/cloud-train.ts" line_range="109" />
<code_context>
+		source
+			.replace(
+				"#define layer(dh, v)  if (uv.y < h + midlevel - (dh) ) return vec4(v, 1.);",
+				"#define layer(dh, v) { float p=openingLayer(dist>=10. ? .08+.60*(100.-dist)/90. : (dist>1.5 ? .78 : .88)); if(dist!=matchedDepth && uv.y < h + midlevel - (dh)) { matchedDepth=dist; accumulated.rgb+=(1.-accumulated.a)*p*(v); accumulated.a+=(1.-accumulated.a)*p; if(accumulated.a>=1.) return accumulated; } }",
+			)
+			.replaceAll(
+				"float midlevel;",
+				"vec4 accumulated=vec4(0.); float matchedDepth=-1.; float midlevel;",
+			)
+			.replace(
</code_context>
<issue_to_address>
**问题 (bug_risk):** opening shader 对 `layer` 的替换会在每个深度的第一层上设置 `matchedDepth`,并跳过后续所有具有相同 `dist` 的层。因此,Cloud Train opening shader 在每个云层深度只会渲染一个材质边界,而不是原本的分层云带。

**触发条件:** intro 动画处于活动状态时。

**建议修复:** 将“某个深度是否已经被累积”的状态与每层的累积状态分开跟踪,或者移除 `dist != matchedDepth` 守卫,以便相同深度的所有层都能参与贡献。

```suggestion
				"#define layer(dh, v) { float p=openingLayer(dist>=10. ? .08+.60*(100.-dist)/90. : (dist>1.5 ? .78 : .88)); if(uv.y < h + midlevel - (dh)) { matchedDepth=dist; accumulated.rgb+=(1.-accumulated.a)*p*(v); accumulated.a+=(1.-accumulated.a)*p; if(accumulated.a>=1.) return accumulated; } }", 
```
</issue_to_address>

Sourcery 评估

等待批准。 请先处理 1 个发现的问题。

阻塞性发现:src/utils/webgl-wallpaper/scenes/cloud-train.ts:109


Sourcery 对开源项目免费——如果您喜欢我们的审查结果,欢迎分享 ✨
Original comment in English

Hey - I've found 1 issue

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location path="src/utils/webgl-wallpaper/scenes/cloud-train.ts" line_range="109" />
<code_context>
+		source
+			.replace(
+				"#define layer(dh, v)  if (uv.y < h + midlevel - (dh) ) return vec4(v, 1.);",
+				"#define layer(dh, v) { float p=openingLayer(dist>=10. ? .08+.60*(100.-dist)/90. : (dist>1.5 ? .78 : .88)); if(dist!=matchedDepth && uv.y < h + midlevel - (dh)) { matchedDepth=dist; accumulated.rgb+=(1.-accumulated.a)*p*(v); accumulated.a+=(1.-accumulated.a)*p; if(accumulated.a>=1.) return accumulated; } }",
+			)
+			.replaceAll(
+				"float midlevel;",
+				"vec4 accumulated=vec4(0.); float matchedDepth=-1.; float midlevel;",
+			)
+			.replace(
</code_context>
<issue_to_address>
**issue (bug_risk):** The opening shader's replacement for `layer` sets `matchedDepth` on the first layer of each depth and skips every subsequent layer with the same `dist`, so the Cloud Train opening shader renders only one material boundary per cloud depth instead of the original layered cloud bands.

**Triggers:** While the intro animation is active.

**Suggested fix:** Track whether a depth has already been accumulated separately from the per-layer accumulation, or remove the `dist != matchedDepth` guard so all layers at the same depth can contribute.

```suggestion
				"#define layer(dh, v) { float p=openingLayer(dist>=10. ? .08+.60*(100.-dist)/90. : (dist>1.5 ? .78 : .88)); if(uv.y < h + midlevel - (dh)) { matchedDepth=dist; accumulated.rgb+=(1.-accumulated.a)*p*(v); accumulated.a+=(1.-accumulated.a)*p; if(accumulated.a>=1.) return accumulated; } }", 
```
</issue_to_address>

Sourcery assessment

Approval pending. 1 finding to address first.

Blocking findings: src/utils/webgl-wallpaper/scenes/cloud-train.ts:109


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

Comment thread src/utils/webgl-wallpaper/scenes/cloud-train.ts Outdated
@March7th-OvO

Copy link
Copy Markdown
Author

已处理:移除了 opening shader 中对 matchedDepth 的限制及其状态变量。现在同一深度的每个云层都会参与累积,恢复分层云带的渲染。已通过 pnpm type-check 与 pnpm check。

@sourcery-ai sourcery-ai 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.

Sourcery assessment

Approved.

This branch has not been deployed

No deployments
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