claude-code-arcane 2.9.8 → 2.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +40 -38
  3. package/agents/business/business-ops-lead.md +1 -14
  4. package/agents/game/gameplay-programmer.md +3 -4
  5. package/agents/game/technical-artist.md +3 -4
  6. package/dist/cli.js +105 -39
  7. package/docs/USER-GUIDE.md +24 -22
  8. package/docs/coordination-rules.md +1 -1
  9. package/docs/directory-structure.md +93 -122
  10. package/package.json +1 -1
  11. package/profiles/ai.yaml +3 -0
  12. package/profiles/android-native.yaml +2 -0
  13. package/profiles/backend-go.yaml +1 -8
  14. package/profiles/backend-ts.yaml +2 -8
  15. package/profiles/backend-typescript.yaml +51 -0
  16. package/profiles/flutter.yaml +2 -0
  17. package/profiles/frontend-react-vite.yaml +39 -0
  18. package/profiles/frontend.yaml +2 -0
  19. package/profiles/integrations.yaml +6 -1
  20. package/profiles/ios-native.yaml +2 -0
  21. package/profiles/mobile-android-kotlin.yaml +36 -0
  22. package/profiles/mobile-flutter.yaml +37 -0
  23. package/profiles/mobile-ios-swift.yaml +37 -0
  24. package/profiles/mobile-react-native.yaml +39 -0
  25. package/profiles/mobile.yaml +2 -0
  26. package/rules/gamedev/engine-code.md +1 -1
  27. package/rules/gamedev/shader-code.md +1 -2
  28. package/rules/gamedev/vn-code.md +3 -2
  29. package/rules/implementation-workflow.md +1 -1
  30. package/rules/{ai-code.md → llm-code.md} +5 -5
  31. package/skills/agent-designer/README.md +2 -1
  32. package/skills/agent-designer/agent_evaluator.py +0 -5
  33. package/skills/ai-sdk-setup/SKILL.md +4 -4
  34. package/skills/arcane-add/SKILL.md +1 -1
  35. package/skills/arcane-list/SKILL.md +3 -3
  36. package/skills/arcane-status/SKILL.md +1 -1
  37. package/skills/architecture-decision/SKILL.md +3 -4
  38. package/skills/architecture-review/SKILL.md +1 -1
  39. package/skills/asset-audit/SKILL.md +0 -1
  40. package/skills/balance-check/SKILL.md +1 -1
  41. package/skills/brainstorm/SKILL.md +3 -3
  42. package/skills/brainstorm/references/next-steps-pipeline.md +8 -9
  43. package/skills/consistency-check/SKILL.md +2 -2
  44. package/skills/design-system/SKILL.md +1 -1
  45. package/skills/design-system/references/post-design-validation.md +2 -3
  46. package/skills/freelance-kickoff/SKILL.md +1 -1
  47. package/skills/frontend-dev/SKILL.md +27 -28
  48. package/skills/frontend-dev/references/asset-prompt-guide.md +1 -1
  49. package/skills/frontend-dev/references/motion-recipes.md +1 -1
  50. package/skills/help/SKILL.md +1 -2
  51. package/skills/hotfix/SKILL.md +2 -2
  52. package/skills/milestone-review/SKILL.md +1 -1
  53. package/skills/patch-notes/SKILL.md +1 -1
  54. package/skills/playtest-report/SKILL.md +2 -3
  55. package/skills/playwright-pro/CLAUDE.md +2 -2
  56. package/skills/playwright-pro/SKILL.md +13 -9
  57. package/skills/playwright-pro/agents/migration-planner.md +2 -2
  58. package/skills/playwright-pro/agents/test-architect.md +1 -2
  59. package/skills/playwright-pro/agents/test-debugger.md +1 -1
  60. package/skills/playwright-pro/hooks/detect-playwright.sh +1 -1
  61. package/skills/playwright-pro/skills/browserstack/SKILL.md +5 -5
  62. package/skills/playwright-pro/skills/migrate/SKILL.md +1 -1
  63. package/skills/playwright-pro/skills/report/SKILL.md +2 -2
  64. package/skills/playwright-pro/skills/testrail/SKILL.md +5 -5
  65. package/skills/playwright-pro/templates/README.md +2 -2
  66. package/skills/prototype/SKILL.md +1 -1
  67. package/skills/quick-design/SKILL.md +1 -1
  68. package/skills/release-checklist/SKILL.md +0 -1
  69. package/skills/security-audit/SKILL.md +1 -1
  70. package/skills/self-improving-agent/CLAUDE.md +12 -12
  71. package/skills/self-improving-agent/SKILL.md +16 -12
  72. package/skills/self-improving-agent/agents/memory-analyst.md +1 -1
  73. package/skills/self-improving-agent/hooks/error-capture.sh +2 -2
  74. package/skills/self-improving-agent/reference/memory-architecture.md +2 -2
  75. package/skills/self-improving-agent/reference/promotion-rules.md +3 -3
  76. package/skills/self-improving-agent/reference/rules-directory-patterns.md +1 -1
  77. package/skills/self-improving-agent/settings.json +5 -5
  78. package/skills/self-improving-agent/skills/extract/SKILL.md +7 -7
  79. package/skills/self-improving-agent/skills/promote/SKILL.md +5 -5
  80. package/skills/self-improving-agent/skills/remember/SKILL.md +9 -9
  81. package/skills/self-improving-agent/skills/review/SKILL.md +7 -7
  82. package/skills/self-improving-agent/skills/status/SKILL.md +8 -8
  83. package/skills/senior-ml-engineer/references/llm_integration_guide.md +14 -31
  84. package/skills/senior-prompt-engineer/SKILL.md +10 -10
  85. package/skills/senior-prompt-engineer/references/prompt_engineering_patterns.md +1 -1
  86. package/skills/senior-prompt-engineer/scripts/agent_orchestrator.py +43 -40
  87. package/skills/senior-prompt-engineer/scripts/prompt_optimizer.py +23 -66
  88. package/skills/shader-dev/reference/fluid-simulation.md +4 -4
  89. package/skills/shader-dev/reference/simulation-physics.md +6 -6
  90. package/skills/shader-dev/reference/voxel-rendering.md +1 -1
  91. package/skills/shader-dev/techniques/ambient-occlusion.md +1 -1
  92. package/skills/shader-dev/techniques/analytic-ray-tracing.md +2 -2
  93. package/skills/shader-dev/techniques/domain-warping.md +2 -2
  94. package/skills/shader-dev/techniques/fluid-simulation.md +45 -45
  95. package/skills/shader-dev/techniques/multipass-buffer.md +24 -24
  96. package/skills/shader-dev/techniques/normal-estimation.md +1 -1
  97. package/skills/shader-dev/techniques/particle-system.md +16 -16
  98. package/skills/shader-dev/techniques/polar-uv-manipulation.md +1 -1
  99. package/skills/shader-dev/techniques/post-processing.md +7 -7
  100. package/skills/shader-dev/techniques/sdf-3d.md +1 -1
  101. package/skills/shader-dev/techniques/simulation-physics.md +24 -24
  102. package/skills/shader-dev/techniques/sound-synthesis.md +2 -2
  103. package/skills/shader-dev/techniques/voronoi-cellular-noise.md +1 -1
  104. package/skills/shader-dev/techniques/voxel-rendering.md +60 -60
  105. package/skills/smoke-check/SKILL.md +1 -1
  106. package/skills/sprint-plan/SKILL.md +1 -2
  107. package/skills/start/SKILL.md +7 -7
  108. package/skills/story-done/SKILL.md +1 -1
  109. package/skills/test-helpers/SKILL.md +7 -2
  110. package/skills/test-setup/SKILL.md +1 -1
  111. package/skills/ue-actor-component-architecture/SKILL.md +0 -1
  112. package/skills/ue-ai-navigation/SKILL.md +0 -1
  113. package/skills/ue-animation-system/SKILL.md +0 -1
  114. package/skills/ue-async-threading/SKILL.md +0 -1
  115. package/skills/ue-audio-system/SKILL.md +0 -1
  116. package/skills/ue-blueprints/SKILL.md +0 -1
  117. package/skills/ue-character-movement/SKILL.md +0 -1
  118. package/skills/ue-cpp-foundations/SKILL.md +0 -1
  119. package/skills/ue-data-assets-tables/SKILL.md +0 -1
  120. package/skills/ue-editor-tools/SKILL.md +0 -1
  121. package/skills/ue-game-features/SKILL.md +0 -1
  122. package/skills/ue-gameplay-abilities/SKILL.md +0 -1
  123. package/skills/ue-gameplay-framework/SKILL.md +0 -1
  124. package/skills/ue-input-system/SKILL.md +0 -1
  125. package/skills/ue-mass-entity/SKILL.md +0 -1
  126. package/skills/ue-materials-rendering/SKILL.md +0 -1
  127. package/skills/ue-module-build-system/SKILL.md +0 -1
  128. package/skills/ue-naming-conventions/SKILL.md +0 -1
  129. package/skills/ue-networking-replication/SKILL.md +0 -1
  130. package/skills/ue-niagara-effects/SKILL.md +0 -1
  131. package/skills/ue-packaging/SKILL.md +0 -1
  132. package/skills/ue-physics-collision/SKILL.md +0 -1
  133. package/skills/ue-procedural-generation/SKILL.md +0 -1
  134. package/skills/ue-project-context/SKILL.md +0 -1
  135. package/skills/ue-sequencer-cinematics/SKILL.md +0 -1
  136. package/skills/ue-serialization-savegames/SKILL.md +0 -1
  137. package/skills/ue-state-trees/SKILL.md +0 -1
  138. package/skills/ue-testing-debugging/SKILL.md +0 -1
  139. package/skills/ue-ui-umg-slate/SKILL.md +0 -1
  140. package/skills/ue-world-level-streaming/SKILL.md +0 -1
  141. package/skills/ux-review/SKILL.md +1 -1
  142. package/docs/RELEASE-SETUP.md +0 -99
  143. package/docs/presentations/arcane-overview-12.pptx +0 -0
  144. package/docs/presentations/arcane-overview.pptx +0 -0
  145. package/docs/presentations/build_arcane_deck.py +0 -310
  146. package/docs/presentations/build_arcane_deck_12.py +0 -399
  147. package/docs/trusted-publishing-setup.md +0 -163
@@ -1,14 +1,14 @@
1
1
  # Particle System
2
2
 
3
- **IMPORTANT: GLSL ES 3.0 return values**: All code paths in non-void functions must return a value. Every branch of an if statement must have a return.
3
+ **GLSL ES 3.0 return values**: All code paths in non-void functions must return a value. Every branch of an if statement must have a return.
4
4
 
5
- **IMPORTANT: Particle system time cycling**: Must use `mod(time - offset, period)` for cycle computation. **Never use `floor(time / period) * period`**! The latter causes all particles to have negative time initially, resulting in startup delay or blank rendering.
5
+ **Particle system time cycling**: Must use `mod(time - offset, period)` for cycle computation. **Never use `floor(time / period) * period`**! The latter causes all particles to have negative time initially, resulting in startup delay or blank rendering.
6
6
 
7
- **IMPORTANT: Brightness budget (most common failure cause!)**: Each particle's `numerator / (dist² + epsilon)` peak = `numerator / epsilon`. **Total peak = N_particles x (numerator / epsilon) must be < 5.0** (single pass). Exceeding this budget causes washout even with Reinhard. See specific reference values in the comments of each template below. Multi-pass ping-pong systems have a stricter budget, see below.
7
+ **Brightness budget (most common failure cause!)**: Each particle's `numerator / (dist² + epsilon)` peak = `numerator / epsilon`. **Total peak = N_particles x (numerator / epsilon) must be < 5.0** (single pass). Exceeding this budget causes washout even with Reinhard. See specific reference values in the comments of each template below. Multi-pass ping-pong systems have a stricter budget, see below.
8
8
 
9
- **IMPORTANT: Particle color vs background contrast**: When particle color is close to the background (sand dust/snow/fog), visibility must be enhanced through at least one method: (1) brightness significantly higher than background (2) different hue (3) visible motion trail.
9
+ **Particle color vs background contrast**: When particle color is close to the background (sand dust/snow/fog), visibility must be enhanced through at least one method: (1) brightness significantly higher than background (2) different hue (3) visible motion trail.
10
10
 
11
- **IMPORTANT: Elongated glow (meteor/trail lines)**: Do not use `1/(distPerp² + tiny_epsilon)` for line glow — too-small epsilon makes the line center extremely bright. Correct approach: use `smoothstep` or `exp(-dist)` for lines, see meteor template below.
11
+ **Elongated glow (meteor/trail lines)**: Do not use `1/(distPerp² + tiny_epsilon)` for line glow — too-small epsilon makes the line center extremely bright. Correct approach: use `smoothstep` or `exp(-dist)` for lines, see meteor template below.
12
12
 
13
13
  ### Correct Pattern
14
14
  ```glsl
@@ -133,7 +133,7 @@ void main() {
133
133
  float fade = smoothstep(1.0, 0.0, burstPhase);
134
134
  fade *= fade;
135
135
 
136
- // IMPORTANT: Brightness budget: peak = 0.015/0.03 = 0.5, x 40 particles x fade ≈ total peak < 5.0
136
+ // Brightness budget: peak = 0.015/0.03 = 0.5, x 40 particles x fade ≈ total peak < 5.0
137
137
  float intensity = fade * 0.015 / (dist * dist + 0.03);
138
138
 
139
139
  float hueOffset = (hash11(pId * 3.7 + fwId * 11.0) - 0.5) * 0.15;
@@ -330,7 +330,7 @@ requestAnimationFrame(render);
330
330
 
331
331
  ### Star Field Function Template (For Meteors, Fireworks, and Other Night Sky Scenes)
332
332
 
333
- **IMPORTANT: Star visibility**: Stars must be clearly visible in screenshots as individual light points. Use `exp(-dist*dist*k)` for sharp Gaussian dots rather than `1/(dist²+eps)` broad glow. Each star's peak brightness should be at least 0.3 to be visible against a dark background.
333
+ **Star visibility**: Stars must be clearly visible in screenshots as individual light points. Use `exp(-dist*dist*k)` for sharp Gaussian dots rather than `1/(dist²+eps)` broad glow. Each star's peak brightness should be at least 0.3 to be visible against a dark background.
334
334
 
335
335
  ```glsl
336
336
  #define NUM_STARS 200
@@ -484,7 +484,7 @@ vec2 particlePosition(int id, float time) {
484
484
  ### Step 4: Buffer-Stored Particle State (Stateful System)
485
485
  ```glsl
486
486
  // === Buffer A: Particle Physics Update ===
487
- // IMPORTANT: Multi-pass system warning: each fragment shader is compiled independently, helper functions must be redefined in each shader!
487
+ // Multi-pass system warning: each fragment shader is compiled independently, helper functions must be redefined in each shader!
488
488
  #define NUM_PARTICLES 40
489
489
  #define MAX_VEL 0.5
490
490
  #define MAX_ACC 3.0
@@ -547,7 +547,7 @@ void mainImage(out vec4 fragColor, in vec2 fragCoord) {
547
547
  ```
548
548
 
549
549
  ### Step 5: Particle Rendering — Metaball Style
550
- // IMPORTANT: Multi-pass system warning: Image shader must define all the following helper functions (compiled independently)!
550
+ // Multi-pass system warning: Image shader must define all the following helper functions (compiled independently)!
551
551
  ```glsl
552
552
  #define BRIGHTNESS 0.002
553
553
  #define COLOR_START vec3(0.0, 0.64, 0.2)
@@ -595,7 +595,7 @@ vec3 renderParticles(vec2 uv) {
595
595
 
596
596
  ### Step 6: Frame Feedback Motion Blur
597
597
  ```glsl
598
- // IMPORTANT: Ping-pong brightness budget (most common washout cause!):
598
+ // Ping-pong brightness budget (most common washout cause!):
599
599
  // Steady-state brightness = singleFrameContribution / (1 - TRAIL_DECAY)
600
600
  // decay=0.88 → 8.3x amplification, decay=0.95 → 20x amplification
601
601
  // Budget formula: N_particles x (numerator/epsilon) x 1/(1-decay) < 10.0
@@ -834,8 +834,8 @@ if (particle.z > particle.a) {
834
834
  Uses stateless single pass. Key: spiral trajectory + high-visibility particles + vortex eye dark zone + separated background fog layer.
835
835
 
836
836
  ```glsl
837
- // IMPORTANT: Particle color must be 2-3x brighter than background to be visible (sand-colored particles on sand-colored background easily disappear)
838
- // IMPORTANT: Brightness budget: 150 particles x peak(0.005/0.003=1.67) x fade(avg~0.3) ≈ 75, overexposed!
837
+ // Particle color must be 2-3x brighter than background to be visible (sand-colored particles on sand-colored background easily disappear)
838
+ // Brightness budget: 150 particles x peak(0.005/0.003=1.67) x fade(avg~0.3) ≈ 75, overexposed!
839
839
  // Must increase epsilon or decrease numerator. Safe values: numerator=0.002, epsilon=0.008 → peak=0.25, total=11 → OK after Reinhard
840
840
  #define NUM_DUST 150
841
841
  #define VORTEX_CENTER vec2(0.0)
@@ -886,7 +886,7 @@ void main() {
886
886
 
887
887
  Meteors, magic projectiles, etc. need elongated glow (stretched luminous lines). **Do not use `1/(distPerp² + tiny_epsilon)` for lines** — too-small epsilon makes line centers extremely bright and washed out. Use `exp(-dist)` or `smoothstep` for safe line glow.
888
888
 
889
- **IMPORTANT: Common meteor failures**: (1) Star background too dark to see — must call `starField()` above and ensure stars use Gaussian dots `exp(-dist²*k)` for rendering (2) Meteor trail too faint — `core` multiplier should be at least 0.15, each step after dividing by `NUM_TRAIL_STEPS` still needs >= 0.005 contribution
889
+ **Common meteor failures**: (1) Star background too dark to see — must call `starField()` above and ensure stars use Gaussian dots `exp(-dist²*k)` for rendering (2) Meteor trail too faint — `core` multiplier should be at least 0.15, each step after dividing by `NUM_TRAIL_STEPS` still needs >= 0.005 contribution
890
890
 
891
891
  ```glsl
892
892
  #define NUM_METEORS 6
@@ -959,7 +959,7 @@ void main() {
959
959
 
960
960
  Water/sparks jetting upward from a point, parabolic descent. Key: **Particles must be sharp, individually visible points** (small epsilon), not just a diffuse glow blob. Must include: (1) main water column particles (upward jet + parabola) (2) splash particles (spread sideways after hitting water) (3) water surface/pool visuals.
961
961
 
962
- **IMPORTANT: Most common fountain failure**: Only produces blurry glow without visible individual water droplet trajectories! Must use small epsilon (<=0.002) so each particle is clearly visible as an individual light point. Numerator must also be proportionally reduced to control total brightness.
962
+ **Most common fountain failure**: Only produces blurry glow without visible individual water droplet trajectories! Must use small epsilon (<=0.002) so each particle is clearly visible as an individual light point. Numerator must also be proportionally reduced to control total brightness.
963
963
 
964
964
  ```glsl
965
965
  #define NUM_WATER 60
@@ -1042,7 +1042,7 @@ void main() {
1042
1042
 
1043
1043
  Flame effects must include **two layers**: (1) smooth flame body at the base (noise-driven cone gradient) (2) many **discrete ember/spark particles** above, drifting upward and gradually extinguishing. Using only a smooth gradient will be judged as "no particle system."
1044
1044
 
1045
- **IMPORTANT: Most common flame failure**: Only draws a smooth gradient without discrete particles! Must have NUM_SPARKS individual point-like particles drifting out from the flame top.
1045
+ **Most common flame failure**: Only draws a smooth gradient without discrete particles! Must have NUM_SPARKS individual point-like particles drifting out from the flame top.
1046
1046
 
1047
1047
  ```glsl
1048
1048
  #define NUM_SPARKS 60
@@ -1112,7 +1112,7 @@ void main() {
1112
1112
 
1113
1113
  Magic effects, spiral ascent, magic circles, etc. require particles arranged in **geometric arrays** with **iridescent shimmer**. Key: particles must be individually visible glowing points (not a blurry glow blob), and the spiral structure must be clearly discernible.
1114
1114
 
1115
- **IMPORTANT: Most common magic failure**: Only produces a blob of blurry light (diffuse glow blob) without visible individual particles or geometric structure! Ensure each particle is an independently visible small light point, and the overall arrangement forms spiral/ring/other geometric shapes. Reduce epsilon to make each particle sharper (small light dot) rather than a large blurry halo.
1115
+ **Most common magic failure**: Only produces a blob of blurry light (diffuse glow blob) without visible individual particles or geometric structure! Ensure each particle is an independently visible small light point, and the overall arrangement forms spiral/ring/other geometric shapes. Reduce epsilon to make each particle sharper (small light dot) rather than a large blurry halo.
1116
1116
 
1117
1117
  ```glsl
1118
1118
  #define NUM_SPIRAL 80
@@ -9,7 +9,7 @@ Code templates in this document use ShaderToy GLSL style. When generating standa
9
9
  - Fragment shader: `varying` → `in`, `gl_FragColor` → custom `out vec4 fragColor`, `texture2D()` → `texture()`
10
10
  - ShaderToy's `void mainImage(out vec4 fragColor, in vec2 fragCoord)` must be adapted to standard `void main()` entry
11
11
 
12
- **IMPORTANT: GLSL Type Strictness Warning**:
12
+ **GLSL Type Strictness Warning**:
13
13
  - `vec2 = float` is illegal: types must match exactly, e.g., `float r = length(uv)` not `vec2 r = length(uv)`
14
14
  - Function return types must match: commonly used `fbm()` / `noise()` return `float`, cannot be assigned to `vec2`
15
15
  - If you need a vec2 type, use `vec2(fbm(...), fbm(...))` or `vec2(value)` constructor
@@ -1,11 +1,11 @@
1
1
  ## WebGL2 Adaptation Requirements
2
2
 
3
- **IMPORTANT: Critical Warning for Standalone HTML Deployment**: Post-processing effects require an input texture to work. When generating standalone HTML, you must:
3
+ **Critical Warning for Standalone HTML Deployment**: Post-processing effects require an input texture to work. When generating standalone HTML, you must:
4
4
  1. Set `#define USE_DEMO_SCENE 1` to use the built-in demo scene (recommended), or
5
5
  2. Pass a valid input texture to the `iChannel0` channel, otherwise the screen will be completely black
6
6
  3. **Critical**: When USE_DEMO_SCENE=1, ensure the #else branch code does not reference non-existent uniforms (e.g., iChannel0)
7
7
 
8
- **IMPORTANT: GLSL Type Strictness Rules**:
8
+ **GLSL Type Strictness Rules**:
9
9
  - `vec2 = float` is illegal — must use `vec2(x, x)` or `vec2(x)`
10
10
  - Function parameters must be defined before use; using a variable name in its own initializer is forbidden (e.g., `float w = filmicCurve(w, w)` is an error)
11
11
  - Variables must be declared before use
@@ -203,7 +203,7 @@ const progPost = createProgram(vsSource, fsPost);
203
203
  function createFBO(w, h) {
204
204
  const tex = gl.createTexture();
205
205
  gl.bindTexture(gl.TEXTURE_2D, tex);
206
- // IMPORTANT: Critical: Check for float texture extension, fall back to RGBA8 if unsupported
206
+ // Check for float texture extension, fall back to RGBA8 if unsupported
207
207
  const fmt = ext ? gl.RGBA16F : gl.RGBA;
208
208
  const typ = ext ? gl.FLOAT : gl.UNSIGNED_BYTE;
209
209
  gl.texImage2D(gl.TEXTURE_2D, 0, fmt, w, h, 0, gl.RGBA, typ, null);
@@ -293,7 +293,7 @@ The essence of post-processing is **per-pixel transformation of an already-rende
293
293
  vec3 reinhard(vec3 color) { return color / (1.0 + color); }
294
294
 
295
295
  // Filmic Reinhard (W=white point, T2=shoulder parameter)
296
- // IMPORTANT: GLSL critical rule: function parameters must be defined before use; using a variable name in its own initializer is forbidden
296
+ // GLSL critical rule: function parameters must be defined before use; using a variable name in its own initializer is forbidden
297
297
  const float W = 1.2, T2 = 7.5; // adjustable
298
298
  float filmic_reinhard_curve(float x) {
299
299
  float q = (T2 * T2 + 1.0) * x * x;
@@ -440,7 +440,7 @@ color += (orderedDither(fragCoord) - 0.5) * 4.0 / 255.0;
440
440
 
441
441
  ### Step 10: Demo Scene (Required for Standalone HTML!)
442
442
 
443
- **IMPORTANT: Critical Warning**: Standalone HTML deployment must provide an input texture, otherwise post-processing effects will output solid black.
443
+ **Critical Warning**: Standalone HTML deployment must provide an input texture, otherwise post-processing effects will output solid black.
444
444
 
445
445
  ```glsl
446
446
  // Demo scene fallback: used when no valid input texture is available
@@ -541,7 +541,7 @@ vec3 fxaa(sampler2D tex, vec2 fragCoord, vec2 resolution) {
541
541
 
542
542
  Can be run directly in ShaderToy. `iChannel0` is the scene texture.
543
543
 
544
- **IMPORTANT: Important Warning**: For standalone HTML deployment, you must:
544
+ **Important Warning**: For standalone HTML deployment, you must:
545
545
  1. Pass a valid input texture to iChannel0 (or uChannel0)
546
546
  2. Or set `#define USE_DEMO_SCENE 1` to use the built-in demo scene
547
547
 
@@ -589,7 +589,7 @@ vec3 demoScene(vec2 uv, float time) {
589
589
  }
590
590
 
591
591
  vec3 tonemapReinhard(vec3 c) { return c / (1.0 + c); }
592
- // IMPORTANT: Critical: filmicCurve takes only one parameter x; w is computed externally via WHITE_POINT
592
+ // filmicCurve takes only one parameter x; w is computed externally via WHITE_POINT
593
593
  float filmicCurve(float x) {
594
594
  float q = (SHOULDER*SHOULDER+1.0)*x*x; return q/(q+x+SHOULDER*SHOULDER);
595
595
  }
@@ -36,7 +36,7 @@ Key math:
36
36
 
37
37
  Runs directly in ShaderToy. Includes multi-primitive scene, smooth blending, soft shadows, AO, and material system.
38
38
 
39
- **IMPORTANT:** When using the `vec2(distance, materialID)` material system, `smin` needs to handle `vec2` types. The template includes a `vec2 smin(vec2 a, vec2 b, float k)` overload that ensures the material ID is correctly passed through during smooth blending (taking the material of the closer distance).
39
+ **** When using the `vec2(distance, materialID)` material system, `smin` needs to handle `vec2` types. The template includes a `vec2 smin(vec2 a, vec2 b, float k)` overload that ensures the material ID is correctly passed through during smooth blending (taking the material of the closer distance).
40
40
 
41
41
  ```glsl
42
42
  // 3D SDF Full Rendering Pipeline Template - Runs in ShaderToy
@@ -4,7 +4,7 @@
4
4
 
5
5
  Below is a complete standalone HTML template demonstrating how to set up WebGL2 double buffering (ping-pong) for physics simulation:
6
6
 
7
- **IMPORTANT: WebGL2 ping-pong core rule: The texture bound to the write-target framebuffer must never simultaneously serve as input for any iChannel.** Violating this rule causes undefined behavior (typically all-black/all-zero output).
7
+ **WebGL2 ping-pong core rule: The texture bound to the write-target framebuffer must never simultaneously serve as input for any iChannel.** Violating this rule causes undefined behavior (typically all-black/all-zero output).
8
8
 
9
9
  For simulations requiring "current frame" and "previous frame" two time steps (such as the wave equation), use **dual-channel encoding**: R channel stores current height, G channel stores previous frame height. This way only one buffer is read from (iChannel0 = currentBuf), writing to another buffer (nextBuf), avoiding read-write conflicts.
10
10
 
@@ -62,9 +62,9 @@ void main() {
62
62
  }`;
63
63
 
64
64
  // === Buffer Pass Shader (physics simulation) ===
65
- // IMPORTANT: Only uses iChannel0 (reads currentBuf), writes to nextBuf
65
+ // Only uses iChannel0 (reads currentBuf), writes to nextBuf
66
66
  // R channel = current height, G channel = previous frame height (dual-channel encoding avoids read-write conflict)
67
- // IMPORTANT: RGBA8 compatible: use encode/decode to map signed values to [0,1], ensuring SwiftShader/no-float-texture environments work correctly
67
+ // RGBA8 compatible: use encode/decode to map signed values to [0,1], ensuring SwiftShader/no-float-texture environments work correctly
68
68
  const fsBuffer = `#version 300 es
69
69
  precision highp float;
70
70
  uniform sampler2D iChannel0;
@@ -161,7 +161,7 @@ gl.enableVertexAttribArray(posLoc);
161
161
  gl.vertexAttribPointer(posLoc, 2, gl.FLOAT, false, 0, 0);
162
162
 
163
163
  // === Render loop ===
164
- // IMPORTANT: Key: currentBuf (read-only) and nextBuf (write-only) must be different buffers
164
+ // currentBuf (read-only) and nextBuf (write-only) must be different buffers
165
165
  let frame = 0;
166
166
  function render(time) {
167
167
  time *= 0.001;
@@ -207,7 +207,7 @@ requestAnimationFrame(render);
207
207
  </script></body></html>
208
208
  ```
209
209
 
210
- **IMPORTANT: Common errors**:
210
+ **Common errors**:
211
211
  1. **RGBA8 signed value truncation (fatal)**: Environments like SwiftShader that don't support `EXT_color_buffer_float` fall back to RGBA8 where values are clamped to [0,1]. Simulations requiring negative values (like the wave equation) will all zero out and produce a static image. **Must** use encode/decode functions: store as `v * 0.5 + 0.5`, read as `v * 2.0 - 1.0`, switching at runtime via `uniform int useFloatTex`. See the `encode()`/`decode()` functions in the template above
212
212
  2. **Ping-pong read-write conflict (fatal)**: When rendering to a framebuffer, the texture bound to that framebuffer cannot simultaneously serve as input. The wave equation uses dual-channel encoding (R=current, G=previous) requiring only one input buffer; cloth/particle systems read getpos/getvel both from iChannel0
213
213
  3. **Cloth rendering must use world coordinate projection (fatal)**: The cloth Image Pass cannot use `uv * vec2(SIZX, SIZY)` to map screen UV directly to grid ID. It must iterate over mesh faces, project vertex world coordinates to screen space via `worldToScreen()`, and perform triangle rasterization
@@ -253,14 +253,14 @@ Vorticity confinement: curl = ∂v_x/∂y - ∂v_y/∂x
253
253
 
254
254
  ### Step 1: Ping-Pong Double Buffering (Correct WebGL2 Implementation)
255
255
 
256
- **IMPORTANT: Key difference between ShaderToy and WebGL2**: In ShaderToy, Buffer A/B are two independent passes with separate write targets, so `iChannel0=self, iChannel1=other` doesn't conflict. But in WebGL2 with a single shader program doing ping-pong, the write-target texture cannot be read simultaneously.
256
+ **Key difference between ShaderToy and WebGL2**: In ShaderToy, Buffer A/B are two independent passes with separate write targets, so `iChannel0=self, iChannel1=other` doesn't conflict. But in WebGL2 with a single shader program doing ping-pong, the write-target texture cannot be read simultaneously.
257
257
 
258
258
  **Solution: Dual-channel encoding** — R channel stores current height, G channel stores previous frame height, requiring only one input buffer:
259
259
 
260
260
  ```glsl
261
261
  // WebGL2 Wave Equation Buffer Pass
262
- // IMPORTANT: Only iChannel0 (reads currentBuf), writes to nextBuf (must be different!)
263
- // IMPORTANT: encode/decode ensures signed values aren't truncated under RGBA8 (no float textures)
262
+ // Only iChannel0 (reads currentBuf), writes to nextBuf (must be different!)
263
+ // encode/decode ensures signed values aren't truncated under RGBA8 (no float textures)
264
264
 
265
265
  uniform int useFloatTex;
266
266
  float decode(float v) { return useFloatTex == 1 ? v : v * 2.0 - 1.0; }
@@ -298,7 +298,7 @@ gl.activeTexture(gl.TEXTURE0);
298
298
  gl.bindTexture(gl.TEXTURE_2D, currentBuf.tex); // read from currentBuf
299
299
  gl.uniform1i(gl.getUniformLocation(progBuffer, 'iChannel0'), 0);
300
300
  gl.uniform1i(gl.getUniformLocation(progBuffer, 'useFloatTex'), useFloat ? 1 : 0);
301
- // IMPORTANT: Do NOT bind iChannel1 to nextBuf/otherBuf!
301
+ // Do NOT bind iChannel1 to nextBuf/otherBuf!
302
302
  ```
303
303
 
304
304
  ### Step 2: Interaction-Driven (External Force Injection)
@@ -328,7 +328,7 @@ next += force;
328
328
  ### Step 3: Height Field Rendering (Image Pass)
329
329
 
330
330
  ```glsl
331
- // IMPORTANT: Image Pass also needs decode
331
+ // Image Pass also needs decode
332
332
  uniform int useFloatTex;
333
333
  float decode(float v) { return useFloatTex == 1 ? v : v * 2.0 - 1.0; }
334
334
 
@@ -429,9 +429,9 @@ Texture regions are partitioned to store different attributes:
429
429
  #define SIZX 128.0
430
430
  #define SIZY 64.0
431
431
 
432
- // IMPORTANT: Cloth/particle systems: getpos/getvel both read from iChannel0 (not iChannel1)
432
+ // Cloth/particle systems: getpos/getvel both read from iChannel0 (not iChannel1)
433
433
  // Because iChannel0 = currentBuf (read-only), write target is nextBuf (separate buffer)
434
- // IMPORTANT: Use +0.5 to sample texel centers (not +0.01)
434
+ // Use +0.5 to sample texel centers (not +0.01)
435
435
  vec3 getpos(vec2 id) {
436
436
  return texture(iChannel0, (id + 0.5) / iResolution.xy).xyz;
437
437
  }
@@ -566,8 +566,8 @@ void mainImage(out vec4 fragColor, in vec2 fragCoord)
566
566
 
567
567
  ```glsl
568
568
  // === Buffer Pass (Wave Equation) ===
569
- // IMPORTANT: Only uses iChannel0 = currentBuf (read-only), writes to nextBuf
570
- // IMPORTANT: encode/decode ensures signed values aren't truncated under RGBA8 (SwiftShader compatible)
569
+ // Only uses iChannel0 = currentBuf (read-only), writes to nextBuf
570
+ // encode/decode ensures signed values aren't truncated under RGBA8 (SwiftShader compatible)
571
571
 
572
572
  uniform int useFloatTex;
573
573
  float decode(float v) { return useFloatTex == 1 ? v : v * 2.0 - 1.0; }
@@ -611,7 +611,7 @@ void mainImage(out vec4 fragColor, in vec2 fragCoord)
611
611
 
612
612
  ```glsl
613
613
  // === Image Pass ===
614
- // IMPORTANT: Also needs decode to correctly read signed height values
614
+ // Also needs decode to correctly read signed height values
615
615
 
616
616
  uniform int useFloatTex;
617
617
  float decode(float v) { return useFloatTex == 1 ? v : v * 2.0 - 1.0; }
@@ -744,7 +744,7 @@ void main() {
744
744
  ```glsl
745
745
  // === Image Pass (Smoke Rendering) ===
746
746
  // Reads density (z channel) and velocity (xy channels) from buffer, renders dense layered smoke + light scattering
747
- // IMPORTANT: Smoke brightness key: absorption coefficient must be large enough (>=3.0), background not too dark, lightTransmit must not over-attenuate
747
+ // Smoke brightness key: absorption coefficient must be large enough (>=3.0), background not too dark, lightTransmit must not over-attenuate
748
748
 
749
749
  void main() {
750
750
  vec2 uv = vUv;
@@ -812,7 +812,7 @@ Cloth simulation requires 2 buffers for ping-pong alternating read/write, with a
812
812
 
813
813
  ```glsl
814
814
  // WebGL2-adapted cloth simulation Buffer Pass
815
- // IMPORTANT: getpos/getvel both read from iChannel0! iChannel0 = currentBuf (read-only), writes to nextBuf
815
+ // getpos/getvel both read from iChannel0! iChannel0 = currentBuf (read-only), writes to nextBuf
816
816
 
817
817
  #define SIZX 128.0
818
818
  #define SIZY 64.0
@@ -889,12 +889,12 @@ void mainImage(out vec4 fragColor, in vec2 fragCoord) {
889
889
 
890
890
  #### Cloth Rendering Pass (Image Pass) Complete Template
891
891
 
892
- **IMPORTANT: Cloth rendering core principle**: After physics simulation, cloth particle world positions (pos.xy) will deviate from their initial grid positions (due to gravity, collisions, etc.). The Image Pass must render based on particles' **actual world positions** projected to the screen — you cannot use `uv * vec2(SIZX, SIZY)` to directly map screen UV to grid ID (that would produce scattered dots/fragments rather than a continuous cloth surface).
892
+ **Cloth rendering core principle**: After physics simulation, cloth particle world positions (pos.xy) will deviate from their initial grid positions (due to gravity, collisions, etc.). The Image Pass must render based on particles' **actual world positions** projected to the screen — you cannot use `uv * vec2(SIZX, SIZY)` to directly map screen UV to grid ID (that would produce scattered dots/fragments rather than a continuous cloth surface).
893
893
 
894
894
  Correct approach: iterate over all cloth mesh cells, project each cell's 4 vertex world coordinates to screen space, determine if the current pixel falls within that quad, then interpolate shading.
895
895
 
896
896
  ```glsl
897
- // IMPORTANT: Key: must pass additional uniform vec2 iSimResolution (simulation resolution)
897
+ // must pass additional uniform vec2 iSimResolution (simulation resolution)
898
898
  // getpos/getvel use iSimResolution, not iResolution
899
899
  // Rendering method: iterate cloth mesh, project world coordinates to screen coordinates
900
900
 
@@ -1035,11 +1035,11 @@ void main() {
1035
1035
  }
1036
1036
  ```
1037
1037
 
1038
- **IMPORTANT: Cloth rendering performance note**: The above template uses a double loop to iterate all mesh faces for triangle rasterization. For a 128x64 mesh this is about 8000 quads per frame. If GPU performance is insufficient, reduce mesh resolution (e.g., SIZX=64, SIZY=32) or use `texelFetch` instead of `texture` for speed. Another approach is to partition the cloth into blocks (e.g., 4x4), each with an independent bounding box for early culling.
1038
+ **Cloth rendering performance note**: The above template uses a double loop to iterate all mesh faces for triangle rasterization. For a 128x64 mesh this is about 8000 quads per frame. If GPU performance is insufficient, reduce mesh resolution (e.g., SIZX=64, SIZY=32) or use `texelFetch` instead of `texture` for speed. Another approach is to partition the cloth into blocks (e.g., 4x4), each with an independent bounding box for early culling.
1039
1039
 
1040
1040
  #### Cloth Simulation Complete HTML Template (Multi-Substep Iteration)
1041
1041
 
1042
- **IMPORTANT: Key notes (must-read for cloth template)**:
1042
+ **Key notes (must-read for cloth template)**:
1043
1043
  1. **No read-write conflict**: In the Buffer Pass, iChannel0 is bound to currentBuf (read-only), the write target is nextBuf (separate buffer). getpos/getvel both read from iChannel0
1044
1044
  2. **iSimResolution uniform**: Image Pass must have `uniform vec2 iSimResolution` passing `(SIM_W, SIM_H)`, and `getpos`/`getvel` internally use `iSimResolution` for UV calculation
1045
1045
  3. **iFrame value passing**: In substep loops, iFrame should pass `frame * SUBSTEPS + substep`, ensuring the initialization condition `iFrame < SUBSTEPS` only triggers on the first frame
@@ -1130,7 +1130,7 @@ float getBallRadius() { return 0.12; }
1130
1130
  vec3 pos, vel, ovel;
1131
1131
  vec2 c;
1132
1132
 
1133
- // IMPORTANT: Both read from iChannel0 (currentBuf), not iChannel1
1133
+ // Both read from iChannel0 (currentBuf), not iChannel1
1134
1134
  vec3 getpos(vec2 id) {
1135
1135
  return texture(iChannel0, (id + 0.5) / iResolution.xy).xyz;
1136
1136
  }
@@ -1414,7 +1414,7 @@ function render(time) {
1414
1414
  time *= 0.001;
1415
1415
 
1416
1416
  for (let substep = 0; substep < SUBSTEPS; substep++) {
1417
- // IMPORTANT: ping-pong: read from currentBuf (iChannel0), write to nextBuf
1417
+ // ping-pong: read from currentBuf (iChannel0), write to nextBuf
1418
1418
  let currentBuf = (globalStep % 2 === 0) ? bufA : bufB;
1419
1419
  let nextBuf = (globalStep % 2 === 0) ? bufB : bufA;
1420
1420
 
@@ -1422,7 +1422,7 @@ function render(time) {
1422
1422
  gl.viewport(0, 0, SIM_W, SIM_H);
1423
1423
  gl.useProgram(progBuffer);
1424
1424
 
1425
- // IMPORTANT: Only bind iChannel0 = currentBuf (read-only)
1425
+ // Only bind iChannel0 = currentBuf (read-only)
1426
1426
  gl.activeTexture(gl.TEXTURE0);
1427
1427
  gl.bindTexture(gl.TEXTURE_2D, currentBuf.tex);
1428
1428
  gl.uniform1i(gl.getUniformLocation(progBuffer, 'iChannel0'), 0);
@@ -157,7 +157,7 @@ const float NOTES[16] = float[16](
157
157
 
158
158
  float melody_array(float time, float bpm) {
159
159
  float beat = time * bpm / 60.0;
160
- int idx = int(mod(beat, 16.0)); // IMPORTANT: Must use int() conversion
160
+ int idx = int(mod(beat, 16.0)); // Must use int() conversion
161
161
  float noteTime = fract(beat);
162
162
  float freq = noteFreq(NOTES[idx]);
163
163
  return instrument_additive(freq, noteTime * 60.0 / bpm);
@@ -241,7 +241,7 @@ vec2 mainSound(int samp, float time) {
241
241
  // Arrangement: smoothstep controls intro/outro
242
242
  audio *= smoothstep(0.0, 4.0, bar); // Fade in over first 4 bars
243
243
  audio *= 0.35 * smoothstep(0.0, 0.5, time);
244
- // IMPORTANT: Array indices must be int type
244
+ // Array indices must be int type
245
245
  // float idx = mod(beat, 16.0); // WRONG: float cannot be used as index
246
246
  int idx = int(mod(beat, 16.0)); // CORRECT: int(mod(...)) conversion
247
247
  return clamp(audio, -1.0, 1.0);
@@ -1,4 +1,4 @@
1
- - **IMPORTANT:** All declared `uniform` variables must be used in the shader code, otherwise the compiler will optimize them away. After optimization, `gl.getUniformLocation()` returns `null`, and setting that uniform triggers a WebGL `INVALID_OPERATION` error, which may cause rendering failure. Ensure uniforms like `iTime` are actually used in `main()` (e.g., `float t = iTime * 1.0;`)
1
+ - **** All declared `uniform` variables must be used in the shader code, otherwise the compiler will optimize them away. After optimization, `gl.getUniformLocation()` returns `null`, and setting that uniform triggers a WebGL `INVALID_OPERATION` error, which may cause rendering failure. Ensure uniforms like `iTime` are actually used in `main()` (e.g., `float t = iTime * 1.0;`)
2
2
 
3
3
  # Voronoi & Cellular Noise
4
4