Skip to content

Comments

fix: adapt ffd shader to fit max vertex uniform vectors#1355

Merged
yiiqii merged 2 commits intomainfrom
fix/ffd
Jan 5, 2026
Merged

fix: adapt ffd shader to fit max vertex uniform vectors#1355
yiiqii merged 2 commits intomainfrom
fix/ffd

Conversation

@ChengYi996
Copy link
Collaborator

@ChengYi996 ChengYi996 commented Jan 4, 2026

Summary by CodeRabbit

  • Bug Fixes
    • Added GPU capability detection so Free Form Deformation (FFD) automatically disables on devices with limited GPU resources, preventing performance and stability issues.
    • FFD shader work is now only applied when the feature is enabled, avoiding unnecessary GPU use on unsupported hardware.

✏️ Tip: You can customize this high-level summary in your review settings.

@ChengYi996 ChengYi996 requested a review from yiiqii January 4, 2026 12:33
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 4, 2026

📝 Walkthrough

Walkthrough

FFDComponent adds a private enableFFD flag (default true). During construction it checks GPU maxVertexUniforms and sets enableFFD = false if under 256. Shader creation and assignment to the current SpriteComponent are now performed only when enableFFD is true.

Changes

Cohort / File(s) Summary
FFD GPU Capability Guard
plugin-packages/ffd/src/ffd-component.ts
Added private enableFFD = true; constructor checks GPU maxVertexUniforms and disables FFD when < 256; shader creation/assignment guarded by enableFFD

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

A rabbit hops where shaders play,
Counts uniforms to light the way—
If numbers fall beneath the fix,
I tuck away those FFD tricks. 🐇✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adapting the FFD shader to work with devices that have limited vertex uniform vectors by adding a GPU capability check.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings

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.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
plugin-packages/ffd/src/ffd-component.ts (2)

22-22: Consider enhancing readability and observability.

While the GPU capability check logic is correct, consider these optional improvements:

  1. Format the conditional for better readability
  2. Extract the magic number 256 as a named constant with documentation
  3. Add logging when FFD is disabled to aid debugging
🔎 Proposed refactor
+  // Minimum vertex uniforms required for FFD shader (rowNum * colNum control points + other uniforms)
+  private static readonly MIN_VERTEX_UNIFORMS = 256;
+
   constructor (engine: Engine) {
     super(engine);
-    if (engine.gpuCapability.detail.maxVertexUniforms < 256) {this.enableFFD = false;}
+    if (engine.gpuCapability.detail.maxVertexUniforms < FFDComponent.MIN_VERTEX_UNIFORMS) {
+      this.enableFFD = false;
+      console.warn('FFD disabled: GPU supports only', engine.gpuCapability.detail.maxVertexUniforms, 'vertex uniforms, requires at least', FFDComponent.MIN_VERTEX_UNIFORMS);
+    }
   }

49-59: Good conditional shader creation, but consider guarding uniform updates.

The conditional shader assignment correctly prevents FFD shader usage on low-capability devices. However, when enableFFD is false, updateShaderUniform() (called from onUpdate and initData) will still attempt to set FFD-specific uniforms on the material, wasting CPU cycles on uniforms that don't exist in the default shader.

🔎 Suggested optimization

Add an early return in updateShaderUniform() method:

   private updateShaderUniform (): void {
+    // Skip uniform updates when FFD is disabled
+    if (!this.enableFFD) {
+      return;
+    }
+
     // 确保当前的 SpriteComponent 存在
     if (!this.currentSpriteComponent) {
       return;
     }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 78da679 and 09accb4.

⛔ Files ignored due to path filters (1)
  • plugin-packages/ffd/src/shader/vertex.glsl is excluded by !**/*.glsl
📒 Files selected for processing (1)
  • plugin-packages/ffd/src/ffd-component.ts
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: ChengYi996
Repo: galacean/effects-runtime PR: 1118
File: packages/effects-core/src/components/ffd-component.ts:135-219
Timestamp: 2025-08-05T07:50:26.317Z
Learning: In packages/effects-core/src/components/ffd-component.ts, the mesh subdivision logic (lines 147-219) within the collectSpriteComponents method is temporary debug code that will be properly implemented later, as confirmed by ChengYi996.
📚 Learning: 2025-08-05T07:50:26.317Z
Learnt from: ChengYi996
Repo: galacean/effects-runtime PR: 1118
File: packages/effects-core/src/components/ffd-component.ts:135-219
Timestamp: 2025-08-05T07:50:26.317Z
Learning: In packages/effects-core/src/components/ffd-component.ts, the mesh subdivision logic (lines 147-219) within the collectSpriteComponents method is temporary debug code that will be properly implemented later, as confirmed by ChengYi996.

Applied to files:

  • plugin-packages/ffd/src/ffd-component.ts
📚 Learning: 2025-08-05T07:51:18.728Z
Learnt from: ChengYi996
Repo: galacean/effects-runtime PR: 1118
File: packages/effects-core/src/components/ffd-component.ts:162-164
Timestamp: 2025-08-05T07:51:18.728Z
Learning: In packages/effects-core/src/components/ffd-component.ts, the //ts-expect-error usage for accessing siblingComponent.splits (around lines 162-164) is temporary debugging code that will be properly implemented later, as confirmed by ChengYi996.

Applied to files:

  • plugin-packages/ffd/src/ffd-component.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (1)
plugin-packages/ffd/src/ffd-component.ts (1)

10-10: LGTM!

The enableFFD flag provides a clean mechanism to conditionally disable FFD functionality based on GPU capabilities.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
plugin-packages/ffd/src/ffd-component.ts (1)

23-25: Add logging when FFD is disabled.

The threshold of 256 vertex uniforms is appropriate for the shader's actual requirements (the FFD control points array uses ~169 uniform vec3 slots plus ~25 additional uniforms, totaling ~195 vectors). However, consider adding a warning log when FFD is disabled due to GPU limitations to help with debugging and render discrepancies.

💡 Suggested improvement: Add logging
 constructor (engine: Engine) {
   super(engine);

   if (engine.gpuCapability.detail.maxVertexUniforms < 256) {
     this.enableFFD = false;
+    console.warn('FFD disabled: GPU maxVertexUniforms (%d) is below required threshold (256)', 
+                 engine.gpuCapability.detail.maxVertexUniforms);
   }
 }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 09accb4 and 645ee4a.

📒 Files selected for processing (1)
  • plugin-packages/ffd/src/ffd-component.ts
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: ChengYi996
Repo: galacean/effects-runtime PR: 1118
File: packages/effects-core/src/components/ffd-component.ts:135-219
Timestamp: 2025-08-05T07:50:26.317Z
Learning: In packages/effects-core/src/components/ffd-component.ts, the mesh subdivision logic (lines 147-219) within the collectSpriteComponents method is temporary debug code that will be properly implemented later, as confirmed by ChengYi996.
Learnt from: ChengYi996
Repo: galacean/effects-runtime PR: 1118
File: packages/effects-core/src/components/ffd-component.ts:162-164
Timestamp: 2025-08-05T07:51:18.728Z
Learning: In packages/effects-core/src/components/ffd-component.ts, the //ts-expect-error usage for accessing siblingComponent.splits (around lines 162-164) is temporary debugging code that will be properly implemented later, as confirmed by ChengYi996.
📚 Learning: 2025-08-05T07:50:26.317Z
Learnt from: ChengYi996
Repo: galacean/effects-runtime PR: 1118
File: packages/effects-core/src/components/ffd-component.ts:135-219
Timestamp: 2025-08-05T07:50:26.317Z
Learning: In packages/effects-core/src/components/ffd-component.ts, the mesh subdivision logic (lines 147-219) within the collectSpriteComponents method is temporary debug code that will be properly implemented later, as confirmed by ChengYi996.

Applied to files:

  • plugin-packages/ffd/src/ffd-component.ts
📚 Learning: 2025-08-05T07:51:18.728Z
Learnt from: ChengYi996
Repo: galacean/effects-runtime PR: 1118
File: packages/effects-core/src/components/ffd-component.ts:162-164
Timestamp: 2025-08-05T07:51:18.728Z
Learning: In packages/effects-core/src/components/ffd-component.ts, the //ts-expect-error usage for accessing siblingComponent.splits (around lines 162-164) is temporary debugging code that will be properly implemented later, as confirmed by ChengYi996.

Applied to files:

  • plugin-packages/ffd/src/ffd-component.ts
🧬 Code graph analysis (1)
plugin-packages/ffd/src/ffd-component.ts (1)
packages/effects-core/src/utils/index.ts (1)
  • generateGUID (145-147)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (1)
plugin-packages/ffd/src/ffd-component.ts (1)

10-10: LGTM: Feature flag added for GPU capability handling.

The enableFFD flag provides a clean way to disable FFD on devices with limited GPU capabilities while maintaining backward compatibility.

Comment on lines +52 to +62
if (this.enableFFD) {
const shader = new Shader(this.engine);

shader.fromData({
vertex: vs,
fragment: fs,
id: generateGUID(),
dataType: spec.DataType.Shader,
});
currentComponent.material.shader = shader;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Critical: updateShaderUniform doesn't respect the enableFFD flag.

While shader creation is correctly guarded by enableFFD, the updateShaderUniform method (lines 105-130) will still attempt to set uniforms even when FFD is disabled. This means it will try to set FFD-specific uniforms (_BoundMin, _BoundMax, _ControlPoints[], etc.) on the default shader, which likely doesn't have these uniforms.

🔎 Proposed fix

Add an early return in updateShaderUniform when FFD is disabled:

 private updateShaderUniform (): void {
+  // Skip uniform updates when FFD is disabled
+  if (!this.enableFFD) {
+    return;
+  }
+
   // 确保当前的 SpriteComponent 存在
   if (!this.currentSpriteComponent) {
     return;
   }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In plugin-packages/ffd/src/ffd-component.ts (around lines 52-62 and 105-130),
updateShaderUniform currently runs even when this.enableFFD is false; add an
early return at the top of updateShaderUniform that checks if (!this.enableFFD)
return so the function exits before accessing/setting any FFD-specific uniforms
or touching the material.shader on non-FFD builds, preventing attempts to set
_BoundMin/_BoundMax/_ControlPoints[] on the default shader.

@yiiqii yiiqii merged commit 3a981bc into main Jan 5, 2026
2 checks passed
@yiiqii yiiqii deleted the fix/ffd branch January 5, 2026 01:38
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