Skip to content

fix(shader-compiler, loader): silence verbose-mode noise + drop ShaderLoader dead code#3007

Open
zhuxudong wants to merge 2 commits into
galacean:dev/2.0from
zhuxudong:fix/shader-compiler-warning-logger
Open

fix(shader-compiler, loader): silence verbose-mode noise + drop ShaderLoader dead code#3007
zhuxudong wants to merge 2 commits into
galacean:dev/2.0from
zhuxudong:fix/shader-compiler-warning-logger

Conversation

@zhuxudong
Copy link
Copy Markdown
Member

@zhuxudong zhuxudong commented May 15, 2026

Summary

Two small fixes to the shader build path, both surfaced while integrating ShaderLab into the editor on dev/2.0:

  1. shader-compiler: route SemanticAnalyzer.reportWarning through Logger.warn so verbose-mode warnings stay disabled by default. Embedders that include the verbose bundle (e.g. the editor's viewport) now control whether to see warnings via Logger.enable() / disable().

  2. loader: drop the @builtin placeholder shader path from ShaderLoader — dead code after refactor(shader): migrate GLSL shaders to ShaderLab and clean up shader infrastructure  #2961.

Net: +2 / -13 lines, no behavior change for code that goes through Logger.enable() or that doesn't ship placeholder .shader files.


1. shader-compiler: CompilationWarningLogger.warn

Why

SemanticAnalyzer.reportWarning wrote directly to console.warn. The verbose shader-compiler bundle is used by the editor viewport to surface diagnostics, but every PBR compile fires several warnings that are false positives in two shapes:

  1. Forward references inside #define value expressions

    #define FUNCTION_DIFFUSE_IBL evaluateDiffuseIBL
    // ... later in the translation unit ...
    vec3 evaluateDiffuseIBL(...) { ... }

    Macro RHS is expanded lazily at the call site, so symbols declared later are legitimate references.

  2. Runtime-injected macrosRENDERER_JOINTS_NUM, RENDERER_BLENDSHAPE_COUNT, MATERIAL_HAS_*. The engine prepends these #defines before compilation; they don't appear in the static source the compiler analyzes.

AST-only static analysis can't tell either shape apart from a real typo, and real typos get caught at codegen / GLSL-compile time. A single editing session in the editor generated hundreds of these warnings, drowning out genuine errors.

What changed

-    console.warn(new GSError(GSErrorName.CompilationWarn, ...).toString());
+    Logger.warn(new GSError(GSErrorName.CompilationWarn, ...).toString());

What didn't

  • reportError keeps writing to console.error directly — errors are always-on, not gated by Logger.
  • All warning emit sites are untouched; the diagnostic information is still produced, just gated.

2. loader: drop @builtin placeholder shader path from ShaderLoader

Why

ShaderLoader._getBuiltinShader parsed // @builtin <name> from a .shader file body and called Shader.find(name) instead of compiling. That indirection only mattered when the loader saw placeholder .shader files whose body was just a marker comment — a layout from the pre-ShaderLab era.

After #2961 all builtin shaders ship via _shaderMap and are resolved by Shader.find directly; no path in the engine emits a placeholder .shader for the loader to parse. Verified zero remaining callers: the only references to _builtinRegex / _getBuiltinShader were the loader's own internal use.

What changed

 class ShaderLoader extends Loader<Shader> {
-  private static _builtinRegex = /^\s*\/\/\s*@builtin\s+(\w+)/;
-
   load(item: LoadItem, resourceManager: ResourceManager): AssetPromise<Shader> {
     ...
     return resourceManager._request<string>(url, { ...item, type: "text" }).then((code: string) => {
-      const builtinShader = this._getBuiltinShader(code);
-      if (builtinShader) {
-        return Shader.find(builtinShader);
-      }
-
       return Shader.create(code, undefined, url);
     });
   }
-
-  private _getBuiltinShader(code: string) {
-    const match = code.match(ShaderLoader._builtinRegex);
-    if (match && match[1]) return match[1];
-  }
 }

Test plan

  • pnpm --filter @galacean/engine-shader-compiler build — release + verbose bundles produce.
  • pnpm --filter @galacean/engine-loader exec tsc --noEmit — typecheck clean.
  • In the editor (which uses @galacean/engine-shader-compiler/verbose): with default Logger state, no CompilationWarning flood; after Logger.enable(), warnings reappear.
  • Existing scenes / prefabs that reference builtin shaders by builtinShaderName continue to load (path now goes through Shader.find from the resolver, not through a placeholder .shader file).

`SemanticAnalyzer.reportWarning` called `console.warn` directly, so any
embedder of the verbose shader-compiler bundle gets noisy output regardless
of the engine's `Logger` toggle. In the editor (which uses
`@galacean/engine-shader-compiler/verbose` to surface diagnostics) a single
PBR shader compile fires several warnings — forward references to functions
declared later in the same translation unit (`#define FUNCTION_DIFFUSE_IBL
evaluateDiffuseIBL`), and runtime-injected macros (`RENDERER_JOINTS_NUM` /
`RENDERER_BLENDSHAPE_COUNT` etc. that the engine prepends before
compilation) — none of which AST-only static analysis can tell apart from
real typos. Hundreds of warnings during an editing session drown out real
errors.

Switch to `Logger.warn` so warnings stay disabled by default and shader
authors can opt in via `Logger.enable()` when actively debugging. Errors
(`reportError`) keep going through `console.error` — they're always-on.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 15, 2026

Walkthrough

Replaces direct console warning emission with Logger.warn in the shader compiler and removes built-in-shader detection in ShaderLoader, making .shader loads always create a new Shader from fetched text.

Changes

Shader Compiler Warning Logging

Layer / File(s) Summary
Logger integration for warning emission
packages/shader-compiler/src/parser/SemanticAnalyzer.ts
Logger import is added and reportWarning now calls Logger.warn(...) with the same GSError(...).toString() message instead of console.warn(...).

Shader Loader Simplification

Layer / File(s) Summary
Unconditional Shader.create from fetched source
packages/loader/src/ShaderLoader.ts
Removed built-in shader detection (regex and helper) and updated .shader load path to always pass fetched text into Shader.create(code, undefined, url) rather than conditionally returning built-ins.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • galacean/engine#3005: Related to shader compiler warning emission changes and prior fixes around macro/parameter handling.

Suggested labels

shader

Suggested reviewers

  • GuoLei1990

Poem

🐰 I hopped through code both crisp and small,
Replaced console calls with one Logger call,
I pruned the loader's built-in maze,
Now shaders spawn in simpler ways,
Hooray — fewer branches, hop and all!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title mentions 'silence verbose-mode noise' which directly relates to the Logger.warn routing change in SemanticAnalyzer, and 'drop ShaderLoader dead code' which relates to the removal of built-in shader detection logic. Both aspects are accurately represented and this is the main focus of the PR.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

GuoLei1990

This comment was marked as outdated.

`ShaderLoader._getBuiltinShader` parsed `// @Builtin <name>` from a `.shader`
file's source and called `Shader.find(name)` instead of compiling. That
indirection only mattered when the loader saw placeholder `.shader` files
whose body was just a marker comment — a layout from the pre-ShaderLab era.

Post `galacean#2961` (GLSL → ShaderLab migration) all builtin shaders ship via
`_shaderMap` and are resolved directly by `Shader.find`; nothing in the
engine emits a placeholder `.shader` for the loader to parse. Confirmed
zero remaining callers (the only reference to `_builtinRegex` /
`_getBuiltinShader` was the loader's own check).

Remove the regex, the helper, and the check. Net -14 lines.
@zhuxudong zhuxudong changed the title fix(shader-compiler): route CompilationWarning through Logger.warn fix(shader-compiler, loader): silence verbose-mode noise + drop ShaderLoader dead code May 15, 2026
GuoLei1990

This comment was marked as outdated.

Copy link
Copy Markdown
Member

@GuoLei1990 GuoLei1990 left a comment

Choose a reason for hiding this comment

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

总结

本轮为第三次审查。本 PR 自上次审查后无新变更(两个 commit 94e2800f + 145a5e8d 均已审过),代码状态未变。重新基于第一性原理审视后,方向与实现仍然正确。

已关闭问题(不再重提)

  • P2 循环依赖风险 — 已确认 engine-core 在运行时不导入 shader-compiler,Logger 自包含零依赖,module 构建中 engine-core 已正确 external。
  • P3 test plan 未勾选 — 上轮已确认。
  • ShaderLoader._getBuiltinShader 删除 — 已确认 packages/ 内无任何 .shader 文件或运行时路径产出 // @builtin <name> 占位文件,#2961 后该路径确为死代码。
  • bootstrap 构建 runtimeExternal = [] — 已知 CLI 场景 trade-off,非 bug。

第一性原理重审

Change 1 (console.warnLogger.warn) — 三个候选方向:

  1. 修根因(消除 forward ref / runtime macro 误报) — 需要 link-time 全局符号解析,超出 AST 静态分析能力,作者描述合理("real typos get caught at codegen / GLSL-compile time")
  2. 完全停止发出这些 warning — 损失 debug 价值
  3. 通过 Logger 门控(本 PR 选择) — 复用现有引擎基础设施,opt-in,与引擎其他 warning 行为一致

方向 3 是最小复杂度的本质解。

Change 2 (删除 _getBuiltinShader) — 纯死代码移除,无新抽象。直接简化。

性能微观察(不构成问题)

Logger.warn(new GSError(...).toString()) 即使 Logger 关闭也会先构造 GSError + .toString()。但 shader 编译是 load-time 一次性操作,不在稳态热路径,每次 PBR 编译多产生几次额外字符串构造无实际影响。如未来想做严格 zero-cost when disabled,可改为 if (Logger.isEnabled) Logger.warn(...) 或让 Logger.warn 接受 lazy message thunk —— 但当前完全可接受,无需修改。

无新问题,可以合并。

@codecov
Copy link
Copy Markdown

codecov Bot commented May 15, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 78.02%. Comparing base (9246f5e) to head (145a5e8).

Additional details and impacted files
@@             Coverage Diff             @@
##           dev/2.0    #3007      +/-   ##
===========================================
- Coverage    78.15%   78.02%   -0.13%     
===========================================
  Files          900      900              
  Lines        99524    99445      -79     
  Branches     10254    10270      +16     
===========================================
- Hits         77779    77592     -187     
- Misses       21571    21678     +107     
- Partials       174      175       +1     
Flag Coverage Δ
unittests 78.02% <100.00%> (-0.13%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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.

2 participants