@rosetears/aili-pi 0.1.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.
- package/LICENSE +21 -0
- package/README.md +109 -0
- package/THIRD_PARTY_NOTICES.md +64 -0
- package/extensions/index.ts +6 -0
- package/install.sh +5 -0
- package/manifests/adapter-evidence.json +45 -0
- package/manifests/capabilities.json +124 -0
- package/manifests/live-verification.json +26 -0
- package/manifests/provenance.json +71 -0
- package/manifests/roles.json +474 -0
- package/manifests/sbom.json +7797 -0
- package/manifests/skill-compatibility.json +8100 -0
- package/manifests/subagent-provenance.json +37 -0
- package/package.json +91 -0
- package/prompts/build.md +8 -0
- package/prompts/define.md +8 -0
- package/prompts/ideate.md +8 -0
- package/prompts/local-review.md +8 -0
- package/prompts/ship.md +8 -0
- package/roles/agent-evaluator.md +47 -0
- package/roles/ai-regression-scout.md +47 -0
- package/roles/browser-qa-runner.md +47 -0
- package/roles/code-reviewer.md +47 -0
- package/roles/code-scout.md +47 -0
- package/roles/convergence-reviewer.md +55 -0
- package/roles/doc-researcher.md +47 -0
- package/roles/e2e-artifact-runner.md +47 -0
- package/roles/implementer.md +47 -0
- package/roles/opensource-sanitizer.md +47 -0
- package/roles/plan-auditor.md +47 -0
- package/roles/pr-test-analyzer.md +47 -0
- package/roles/security-auditor.md +47 -0
- package/roles/silent-failure-reviewer.md +47 -0
- package/roles/spec-miner.md +47 -0
- package/roles/test-coverage-reviewer.md +47 -0
- package/roles/test-engineer.md +48 -0
- package/roles/web-performance-auditor.md +47 -0
- package/roles/web-researcher.md +47 -0
- package/scripts/apply-adapter-evidence.ts +73 -0
- package/scripts/bootstrap.sh +180 -0
- package/scripts/generate-provenance.ts +143 -0
- package/scripts/local-package-e2e.ts +51 -0
- package/scripts/sync-roles.ts +213 -0
- package/scripts/sync-skills.ts +356 -0
- package/scripts/validate-runtime.ts +11 -0
- package/skills/academic-paper-review/SKILL.md +81 -0
- package/skills/agents-md-initialization/SKILL.md +121 -0
- package/skills/agents-md-initialization/references/agents-template.md +83 -0
- package/skills/agents-md-initialization/references/agents_md.py +215 -0
- package/skills/ai-regression-scout/SKILL.md +24 -0
- package/skills/aili-delivery-flow/SKILL.md +125 -0
- package/skills/aili-delivery-flow/references/artifact-contracts.md +138 -0
- package/skills/aili-delivery-flow/references/backend-routing.md +40 -0
- package/skills/aili-delivery-flow/references/build-execution-loop.md +113 -0
- package/skills/aili-delivery-flow/references/build-goal-mode.md +3 -0
- package/skills/aili-delivery-flow/references/direct-vs-delegated-work.md +38 -0
- package/skills/aili-delivery-flow/references/implementation-packages.md +54 -0
- package/skills/aili-delivery-flow/references/lifecycle.md +127 -0
- package/skills/aili-delivery-flow/references/protocols/acceptance-test-plan.md +18 -0
- package/skills/aili-delivery-flow/references/protocols/alignment-questionnaire.md +10 -0
- package/skills/aili-delivery-flow/references/protocols/closeout-report.md +101 -0
- package/skills/aili-delivery-flow/references/protocols/compact-evidence-pack.md +46 -0
- package/skills/aili-delivery-flow/references/protocols/idea-brief.md +10 -0
- package/skills/aili-delivery-flow/references/protocols/implementation-package.md +53 -0
- package/skills/aili-delivery-flow/references/protocols/research-evidence-pack.md +19 -0
- package/skills/aili-delivery-flow/references/protocols/review-report.md +7 -0
- package/skills/aili-delivery-flow/references/protocols/spec-draft.md +12 -0
- package/skills/aili-delivery-flow/references/protocols/subagent-result.md +60 -0
- package/skills/aili-delivery-flow/references/protocols/subagent-task-packet.md +29 -0
- package/skills/aili-delivery-flow/references/protocols/worktree-context.md +109 -0
- package/skills/aili-delivery-flow/references/questionnaire-policy.md +62 -0
- package/skills/aili-delivery-flow/references/review-repair-loop.md +16 -0
- package/skills/aili-delivery-flow/references/test-document-policy.md +35 -0
- package/skills/android-native-dev/SKILL.md +722 -0
- package/skills/android-native-dev/references/accessibility.md +209 -0
- package/skills/android-native-dev/references/adaptive-screens.md +231 -0
- package/skills/android-native-dev/references/design-style-guide.md +365 -0
- package/skills/android-native-dev/references/functional-requirements.md +229 -0
- package/skills/android-native-dev/references/motion-system.md +203 -0
- package/skills/android-native-dev/references/performance-stability.md +223 -0
- package/skills/android-native-dev/references/privacy-security.md +244 -0
- package/skills/android-native-dev/references/testing.md +554 -0
- package/skills/android-native-dev/references/visual-design.md +246 -0
- package/skills/api-and-interface-design/SKILL.md +318 -0
- package/skills/browser-qa/SKILL.md +32 -0
- package/skills/browser-testing-with-devtools/SKILL.md +323 -0
- package/skills/build-failure-repair/SKILL.md +49 -0
- package/skills/chart-visualization/SKILL.md +73 -0
- package/skills/ci-cd-and-automation/SKILL.md +353 -0
- package/skills/code-review-and-quality/SKILL.md +375 -0
- package/skills/code-review-quality-gates/SKILL.md +132 -0
- package/skills/code-simplification/SKILL.md +371 -0
- package/skills/comment-accuracy-review/SKILL.md +37 -0
- package/skills/consulting-analysis/SKILL.md +69 -0
- package/skills/context-engineering/SKILL.md +375 -0
- package/skills/coverage-review/SKILL.md +24 -0
- package/skills/data-analysis/SKILL.md +74 -0
- package/skills/deprecation-and-migration/SKILL.md +222 -0
- package/skills/documentation-and-adrs/SKILL.md +330 -0
- package/skills/e2e-artifact-handling/SKILL.md +30 -0
- package/skills/evidence-scoped-retrospective/SKILL.md +156 -0
- package/skills/explain-by-allegory/SKILL.md +99 -0
- package/skills/flutter-dev/SKILL.md +162 -0
- package/skills/flutter-dev/references/animations.md +497 -0
- package/skills/flutter-dev/references/bloc-state.md +281 -0
- package/skills/flutter-dev/references/forms.md +656 -0
- package/skills/flutter-dev/references/gorouter-navigation.md +257 -0
- package/skills/flutter-dev/references/localization.md +510 -0
- package/skills/flutter-dev/references/networking.md +566 -0
- package/skills/flutter-dev/references/performance.md +305 -0
- package/skills/flutter-dev/references/platform-specific.md +417 -0
- package/skills/flutter-dev/references/project-structure.md +273 -0
- package/skills/flutter-dev/references/riverpod-state.md +232 -0
- package/skills/flutter-dev/references/testing.md +364 -0
- package/skills/flutter-dev/references/widget-patterns.md +233 -0
- package/skills/frontend-dev/SKILL.md +468 -0
- package/skills/frontend-dev/canvas-fonts/ArsenalSC-OFL.txt +93 -0
- package/skills/frontend-dev/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/BigShoulders-Bold.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/BigShoulders-OFL.txt +93 -0
- package/skills/frontend-dev/canvas-fonts/BigShoulders-Regular.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/Boldonse-OFL.txt +93 -0
- package/skills/frontend-dev/canvas-fonts/Boldonse-Regular.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/BricolageGrotesque-OFL.txt +93 -0
- package/skills/frontend-dev/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/CrimsonPro-OFL.txt +93 -0
- package/skills/frontend-dev/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/DMMono-OFL.txt +93 -0
- package/skills/frontend-dev/canvas-fonts/DMMono-Regular.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/EricaOne-OFL.txt +94 -0
- package/skills/frontend-dev/canvas-fonts/EricaOne-Regular.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/GeistMono-Bold.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/GeistMono-OFL.txt +93 -0
- package/skills/frontend-dev/canvas-fonts/GeistMono-Regular.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/Gloock-OFL.txt +93 -0
- package/skills/frontend-dev/canvas-fonts/Gloock-Regular.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/IBMPlexMono-OFL.txt +93 -0
- package/skills/frontend-dev/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/InstrumentSans-OFL.txt +93 -0
- package/skills/frontend-dev/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/Italiana-OFL.txt +93 -0
- package/skills/frontend-dev/canvas-fonts/Italiana-Regular.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/JetBrainsMono-OFL.txt +93 -0
- package/skills/frontend-dev/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/Jura-Light.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/Jura-Medium.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/Jura-OFL.txt +93 -0
- package/skills/frontend-dev/canvas-fonts/LibreBaskerville-OFL.txt +93 -0
- package/skills/frontend-dev/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/Lora-Bold.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/Lora-BoldItalic.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/Lora-Italic.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/Lora-OFL.txt +93 -0
- package/skills/frontend-dev/canvas-fonts/Lora-Regular.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/NationalPark-Bold.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/NationalPark-OFL.txt +93 -0
- package/skills/frontend-dev/canvas-fonts/NationalPark-Regular.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/NothingYouCouldDo-OFL.txt +93 -0
- package/skills/frontend-dev/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/Outfit-Bold.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/Outfit-OFL.txt +93 -0
- package/skills/frontend-dev/canvas-fonts/Outfit-Regular.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/PixelifySans-Medium.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/PixelifySans-OFL.txt +93 -0
- package/skills/frontend-dev/canvas-fonts/PoiretOne-OFL.txt +93 -0
- package/skills/frontend-dev/canvas-fonts/PoiretOne-Regular.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/RedHatMono-Bold.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/RedHatMono-OFL.txt +93 -0
- package/skills/frontend-dev/canvas-fonts/RedHatMono-Regular.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/Silkscreen-OFL.txt +93 -0
- package/skills/frontend-dev/canvas-fonts/Silkscreen-Regular.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/SmoochSans-Medium.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/SmoochSans-OFL.txt +93 -0
- package/skills/frontend-dev/canvas-fonts/Tektur-Medium.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/Tektur-OFL.txt +93 -0
- package/skills/frontend-dev/canvas-fonts/Tektur-Regular.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/WorkSans-Bold.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/WorkSans-Italic.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/WorkSans-OFL.txt +93 -0
- package/skills/frontend-dev/canvas-fonts/WorkSans-Regular.ttf +0 -0
- package/skills/frontend-dev/canvas-fonts/YoungSerif-OFL.txt +93 -0
- package/skills/frontend-dev/canvas-fonts/YoungSerif-Regular.ttf +0 -0
- package/skills/frontend-dev/references/asset-prompt-guide.md +43 -0
- package/skills/frontend-dev/references/env-setup.md +33 -0
- package/skills/frontend-dev/references/minimax-cli-reference.md +133 -0
- package/skills/frontend-dev/references/minimax-image-guide.md +65 -0
- package/skills/frontend-dev/references/minimax-music-guide.md +216 -0
- package/skills/frontend-dev/references/minimax-tts-guide.md +78 -0
- package/skills/frontend-dev/references/minimax-video-guide.md +82 -0
- package/skills/frontend-dev/references/minimax-voice-catalog.md +685 -0
- package/skills/frontend-dev/references/motion-recipes.md +407 -0
- package/skills/frontend-dev/references/troubleshooting.md +85 -0
- package/skills/frontend-dev/scripts/minimax_image.py +137 -0
- package/skills/frontend-dev/scripts/minimax_music.py +157 -0
- package/skills/frontend-dev/scripts/minimax_tts.py +127 -0
- package/skills/frontend-dev/scripts/minimax_video.py +187 -0
- package/skills/frontend-dev/templates/generator_template.js +223 -0
- package/skills/frontend-dev/templates/viewer.html +599 -0
- package/skills/frontend-ui-engineering/SKILL.md +367 -0
- package/skills/fullstack-dev/SKILL.md +819 -0
- package/skills/fullstack-dev/references/api-design.md +444 -0
- package/skills/fullstack-dev/references/auth-flow.md +165 -0
- package/skills/fullstack-dev/references/db-schema.md +706 -0
- package/skills/fullstack-dev/references/django-best-practices.md +466 -0
- package/skills/fullstack-dev/references/environment-management.md +78 -0
- package/skills/fullstack-dev/references/release-checklist.md +278 -0
- package/skills/fullstack-dev/references/technology-selection.md +254 -0
- package/skills/fullstack-dev/references/testing-strategy.md +404 -0
- package/skills/git-workflow-and-versioning/SKILL.md +446 -0
- package/skills/github-evidence-triage/SKILL.md +115 -0
- package/skills/harness-evolution/SKILL.md +59 -0
- package/skills/harness-evolution/references/activation-matrix.md +13 -0
- package/skills/harness-evolution/references/approval-policy.md +20 -0
- package/skills/harness-evolution/references/change-report-template.md +33 -0
- package/skills/harness-evolution/references/component-taxonomy.md +19 -0
- package/skills/harness-evolution/references/verdict-policy.md +13 -0
- package/skills/harness-issue-triage/SKILL.md +72 -0
- package/skills/harness-issue-triage/references/component-diagnosis.md +25 -0
- package/skills/harness-issue-triage/references/triage-report-template.md +34 -0
- package/skills/harness-optimization-audit/SKILL.md +125 -0
- package/skills/idea-refine/SKILL.md +191 -0
- package/skills/idea-refine/references/upstream/addyosmani-agent-skills/6bcfeb9dae52b11eaad23511acc165109746dbc3/LICENSE +21 -0
- package/skills/idea-refine/references/upstream/addyosmani-agent-skills/6bcfeb9dae52b11eaad23511acc165109746dbc3/NOTICE.md +9 -0
- package/skills/idea-refine/references/upstream/addyosmani-agent-skills/6bcfeb9dae52b11eaad23511acc165109746dbc3/idea-refine/SKILL.upstream.md +178 -0
- package/skills/idea-refine/references/upstream/addyosmani-agent-skills/6bcfeb9dae52b11eaad23511acc165109746dbc3/idea-refine/examples.md +238 -0
- package/skills/idea-refine/references/upstream/addyosmani-agent-skills/6bcfeb9dae52b11eaad23511acc165109746dbc3/idea-refine/frameworks.md +99 -0
- package/skills/idea-refine/references/upstream/addyosmani-agent-skills/6bcfeb9dae52b11eaad23511acc165109746dbc3/idea-refine/refinement-criteria.md +113 -0
- package/skills/idea-refine/references/upstream/addyosmani-agent-skills/6bcfeb9dae52b11eaad23511acc165109746dbc3/idea-refine/scripts/idea-refine.upstream.sh +15 -0
- package/skills/incremental-implementation/SKILL.md +252 -0
- package/skills/ios-application-dev/SKILL.md +212 -0
- package/skills/ios-application-dev/references/accessibility.md +259 -0
- package/skills/ios-application-dev/references/graphics-animation.md +350 -0
- package/skills/ios-application-dev/references/layout-system.md +199 -0
- package/skills/ios-application-dev/references/metal-shader.md +178 -0
- package/skills/ios-application-dev/references/navigation-patterns.md +175 -0
- package/skills/ios-application-dev/references/swift-coding-standards.md +757 -0
- package/skills/ios-application-dev/references/swiftui-design-guidelines.md +1167 -0
- package/skills/ios-application-dev/references/system-integration.md +401 -0
- package/skills/ios-application-dev/references/uikit-components.md +297 -0
- package/skills/local-review-gate/SKILL.md +207 -0
- package/skills/local-review-gate/references/addyosmani-code-review-rubric.md +33 -0
- package/skills/local-review-gate/references/codex-github-compatibility.md +26 -0
- package/skills/local-review-gate/references/ecc-code-review-adaptation.md +40 -0
- package/skills/local-review-gate/references/graphify-local-review.md +33 -0
- package/skills/local-review-gate/references/orchestration-adaptation.md +51 -0
- package/skills/local-review-gate/references/review-repair-lane-adaptation.md +46 -0
- package/skills/local-review-gate/references/upstream-provenance.md +61 -0
- package/skills/mature-project-pattern-research/SKILL.md +155 -0
- package/skills/mature-project-pattern-research/references/research-rubric.md +45 -0
- package/skills/minimax-docx/LICENSE +21 -0
- package/skills/minimax-docx/SKILL.md +273 -0
- package/skills/minimax-docx/assets/styles/academic_styles.xml +250 -0
- package/skills/minimax-docx/assets/styles/corporate_styles.xml +284 -0
- package/skills/minimax-docx/assets/styles/default_styles.xml +449 -0
- package/skills/minimax-docx/assets/xsd/aesthetic-rules.xsd +470 -0
- package/skills/minimax-docx/assets/xsd/business-rules.xsd +130 -0
- package/skills/minimax-docx/assets/xsd/common-types.xsd +159 -0
- package/skills/minimax-docx/assets/xsd/wml-subset.xsd +589 -0
- package/skills/minimax-docx/references/cjk_typography.md +357 -0
- package/skills/minimax-docx/references/cjk_university_template_guide.md +184 -0
- package/skills/minimax-docx/references/comments_guide.md +191 -0
- package/skills/minimax-docx/references/design_good_bad_examples.md +829 -0
- package/skills/minimax-docx/references/design_principles.md +819 -0
- package/skills/minimax-docx/references/openxml_element_order.md +308 -0
- package/skills/minimax-docx/references/openxml_encyclopedia_part1.md +4061 -0
- package/skills/minimax-docx/references/openxml_encyclopedia_part2.md +2820 -0
- package/skills/minimax-docx/references/openxml_encyclopedia_part3.md +3381 -0
- package/skills/minimax-docx/references/openxml_namespaces.md +82 -0
- package/skills/minimax-docx/references/openxml_units.md +72 -0
- package/skills/minimax-docx/references/scenario_a_create.md +284 -0
- package/skills/minimax-docx/references/scenario_b_edit_content.md +295 -0
- package/skills/minimax-docx/references/scenario_c_apply_template.md +456 -0
- package/skills/minimax-docx/references/track_changes_guide.md +200 -0
- package/skills/minimax-docx/references/troubleshooting.md +506 -0
- package/skills/minimax-docx/references/typography_guide.md +294 -0
- package/skills/minimax-docx/references/xsd_validation_guide.md +158 -0
- package/skills/minimax-docx/scripts/doc_to_docx.sh +40 -0
- package/skills/minimax-docx/scripts/docx_preview.sh +37 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Cli/MiniMaxAIDocx.Cli.csproj +19 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Cli/Program.cs +18 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/AnalyzeCommand.cs +147 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/ApplyTemplateCommand.cs +322 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/CreateCommand.cs +324 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/DiffCommand.cs +155 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/EditContentCommand.cs +487 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/FixOrderCommand.cs +108 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/MergeRunsCommand.cs +122 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Commands/ValidateCommand.cs +107 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/MiniMaxAIDocx.Core.csproj +15 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/CommentSynchronizer.cs +169 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/ElementOrder.cs +80 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/NamespaceConstants.cs +42 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/RunMerger.cs +81 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/StyleAnalyzer.cs +81 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/TrackChangesHelper.cs +99 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/OpenXml/UnitConverter.cs +23 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/AestheticRecipeSamples.cs +1832 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/AestheticRecipeSamples_Batch1.cs +910 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/AestheticRecipeSamples_Batch2.cs +999 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/AestheticRecipeSamples_Batch3.cs +1048 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/AestheticRecipeSamples_Batch4.cs +1038 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/CharacterFormattingSamples.cs +1020 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/DocumentCreationSamples.cs +1121 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/FieldAndTocSamples.cs +624 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/FootnoteAndCommentSamples.cs +675 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/HeaderFooterSamples.cs +838 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/ImageSamples.cs +917 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/ListAndNumberingSamples.cs +826 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/ParagraphFormattingSamples.cs +1199 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/StyleSystemSamples.cs +1487 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/TableSamples.cs +1163 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Samples/TrackChangesSamples.cs +595 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Typography/CjkHelper.cs +39 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Typography/FontDefaults.cs +24 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Typography/PageSizes.cs +20 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Validation/BusinessRuleValidator.cs +224 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Validation/GateCheckValidator.cs +148 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Validation/ValidationResult.cs +23 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.Core/Validation/XsdValidator.cs +69 -0
- package/skills/minimax-docx/scripts/dotnet/MiniMaxAIDocx.slnx +4 -0
- package/skills/minimax-docx/scripts/env_check.sh +196 -0
- package/skills/minimax-docx/scripts/setup.ps1 +274 -0
- package/skills/minimax-docx/scripts/setup.sh +504 -0
- package/skills/minimax-pdf/README.md +222 -0
- package/skills/minimax-pdf/SKILL.md +218 -0
- package/skills/minimax-pdf/design/design.md +381 -0
- package/skills/minimax-pdf/scripts/cover.py +1579 -0
- package/skills/minimax-pdf/scripts/fill_inspect.py +200 -0
- package/skills/minimax-pdf/scripts/fill_write.py +242 -0
- package/skills/minimax-pdf/scripts/make.sh +491 -0
- package/skills/minimax-pdf/scripts/merge.py +112 -0
- package/skills/minimax-pdf/scripts/palette.py +521 -0
- package/skills/minimax-pdf/scripts/reformat_parse.py +374 -0
- package/skills/minimax-pdf/scripts/render_body.py +1052 -0
- package/skills/minimax-pdf/scripts/render_cover.js +111 -0
- package/skills/minimax-xlsx/SKILL.md +156 -0
- package/skills/minimax-xlsx/references/create.md +691 -0
- package/skills/minimax-xlsx/references/edit.md +684 -0
- package/skills/minimax-xlsx/references/fix.md +37 -0
- package/skills/minimax-xlsx/references/format.md +768 -0
- package/skills/minimax-xlsx/references/ooxml-cheatsheet.md +231 -0
- package/skills/minimax-xlsx/references/read-analyze.md +97 -0
- package/skills/minimax-xlsx/references/validate.md +772 -0
- package/skills/minimax-xlsx/scripts/formula_check.py +422 -0
- package/skills/minimax-xlsx/scripts/libreoffice_recalc.py +248 -0
- package/skills/minimax-xlsx/scripts/shared_strings_builder.py +163 -0
- package/skills/minimax-xlsx/scripts/style_audit.py +575 -0
- package/skills/minimax-xlsx/scripts/xlsx_add_column.py +395 -0
- package/skills/minimax-xlsx/scripts/xlsx_insert_row.py +274 -0
- package/skills/minimax-xlsx/scripts/xlsx_pack.py +87 -0
- package/skills/minimax-xlsx/scripts/xlsx_reader.py +362 -0
- package/skills/minimax-xlsx/scripts/xlsx_shift_rows.py +396 -0
- package/skills/minimax-xlsx/scripts/xlsx_unpack.py +130 -0
- package/skills/minimax-xlsx/templates/minimal_xlsx/[Content_Types].xml +9 -0
- package/skills/minimax-xlsx/templates/minimal_xlsx/_rels/.rels +6 -0
- package/skills/minimax-xlsx/templates/minimal_xlsx/xl/_rels/workbook.xml.rels +19 -0
- package/skills/minimax-xlsx/templates/minimal_xlsx/xl/sharedStrings.xml +33 -0
- package/skills/minimax-xlsx/templates/minimal_xlsx/xl/styles.xml +160 -0
- package/skills/minimax-xlsx/templates/minimal_xlsx/xl/workbook.xml +30 -0
- package/skills/minimax-xlsx/templates/minimal_xlsx/xl/worksheets/sheet1.xml +70 -0
- package/skills/newsletter-generation/SKILL.md +71 -0
- package/skills/oss-release-readiness/SKILL.md +47 -0
- package/skills/parallel-subagent-dispatch/SKILL.md +58 -0
- package/skills/performance-optimization/SKILL.md +364 -0
- package/skills/planning-and-task-breakdown/SKILL.md +290 -0
- package/skills/pptx-generator/SKILL.md +275 -0
- package/skills/pptx-generator/references/design-system.md +392 -0
- package/skills/pptx-generator/references/editing.md +162 -0
- package/skills/pptx-generator/references/pitfalls.md +112 -0
- package/skills/pptx-generator/references/pptxgenjs.md +420 -0
- package/skills/pptx-generator/references/slide-types.md +413 -0
- package/skills/pr-test-analysis/SKILL.md +24 -0
- package/skills/react-native-dev/SKILL.md +180 -0
- package/skills/react-native-dev/references/animations.md +254 -0
- package/skills/react-native-dev/references/components.md +124 -0
- package/skills/react-native-dev/references/engineering.md +527 -0
- package/skills/react-native-dev/references/forms.md +300 -0
- package/skills/react-native-dev/references/native-capabilities.md +163 -0
- package/skills/react-native-dev/references/navigation.md +271 -0
- package/skills/react-native-dev/references/networking.md +346 -0
- package/skills/react-native-dev/references/performance.md +215 -0
- package/skills/react-native-dev/references/state-management.md +230 -0
- package/skills/react-native-dev/references/styling.md +117 -0
- package/skills/react-native-dev/references/testing.md +341 -0
- package/skills/requirements-grilling/SKILL.md +447 -0
- package/skills/requirements-grilling/references/ADR-FORMAT.md +46 -0
- package/skills/requirements-grilling/references/CONTEXT-FORMAT.md +41 -0
- package/skills/requirements-grilling/references/INTERVIEW-PACKET-FORMAT.md +62 -0
- package/skills/requirements-grilling/references/MIT-LICENSE-MATT-POCOCK.md +25 -0
- package/skills/requirements-grilling/references/upstream/addyosmani-agent-skills/6bcfeb9dae52b11eaad23511acc165109746dbc3/LICENSE +21 -0
- package/skills/requirements-grilling/references/upstream/addyosmani-agent-skills/6bcfeb9dae52b11eaad23511acc165109746dbc3/NOTICE.md +9 -0
- package/skills/requirements-grilling/references/upstream/addyosmani-agent-skills/6bcfeb9dae52b11eaad23511acc165109746dbc3/interview-me/SKILL.upstream.md +225 -0
- package/skills/requirements-grilling/references/upstream/mattpocock-skills/9603c1cc8118d08bc1b3bf34cf714f62178dea3b/LICENSE +21 -0
- package/skills/requirements-grilling/references/upstream/mattpocock-skills/9603c1cc8118d08bc1b3bf34cf714f62178dea3b/NOTICE.md +12 -0
- package/skills/requirements-grilling/references/upstream/mattpocock-skills/9603c1cc8118d08bc1b3bf34cf714f62178dea3b/batch-grill-me/SKILL.upstream.md +15 -0
- package/skills/requirements-grilling/references/upstream/mattpocock-skills/9603c1cc8118d08bc1b3bf34cf714f62178dea3b/grill-me/SKILL.upstream.md +7 -0
- package/skills/requirements-grilling/references/upstream/mattpocock-skills/9603c1cc8118d08bc1b3bf34cf714f62178dea3b/grilling/SKILL.upstream.md +12 -0
- package/skills/review-pipeline/SKILL.md +38 -0
- package/skills/rose-memory/SKILL.md +210 -0
- package/skills/rose-memory/references/README.md +48 -0
- package/skills/rose-memory/references/memory_cli.py +2384 -0
- package/skills/rose-memory/references/schema.sql +315 -0
- package/skills/security-and-hardening/SKILL.md +369 -0
- package/skills/session-handoff/SKILL.md +88 -0
- package/skills/session-handoff/references/upstream/mattpocock-skills/391a2701dd948f94f56a39f7533f8eea9a859c87/LICENSE +21 -0
- package/skills/session-handoff/references/upstream/mattpocock-skills/391a2701dd948f94f56a39f7533f8eea9a859c87/NOTICE.md +9 -0
- package/skills/session-handoff/references/upstream/mattpocock-skills/391a2701dd948f94f56a39f7533f8eea9a859c87/productivity/handoff/SKILL.upstream.md +16 -0
- package/skills/session-handoff/scripts/session_handoff.py +764 -0
- package/skills/shader-dev/SKILL.md +316 -0
- package/skills/shader-dev/reference/ambient-occlusion.md +382 -0
- package/skills/shader-dev/reference/analytic-ray-tracing.md +651 -0
- package/skills/shader-dev/reference/anti-aliasing.md +71 -0
- package/skills/shader-dev/reference/atmospheric-scattering.md +571 -0
- package/skills/shader-dev/reference/camera-effects.md +80 -0
- package/skills/shader-dev/reference/cellular-automata.md +635 -0
- package/skills/shader-dev/reference/color-palette.md +481 -0
- package/skills/shader-dev/reference/csg-boolean-operations.md +466 -0
- package/skills/shader-dev/reference/domain-repetition.md +436 -0
- package/skills/shader-dev/reference/domain-warping.md +419 -0
- package/skills/shader-dev/reference/fluid-simulation.md +425 -0
- package/skills/shader-dev/reference/fractal-rendering.md +525 -0
- package/skills/shader-dev/reference/lighting-model.md +639 -0
- package/skills/shader-dev/reference/matrix-transform.md +535 -0
- package/skills/shader-dev/reference/multipass-buffer.md +571 -0
- package/skills/shader-dev/reference/normal-estimation.md +418 -0
- package/skills/shader-dev/reference/particle-system.md +589 -0
- package/skills/shader-dev/reference/path-tracing-gi.md +602 -0
- package/skills/shader-dev/reference/polar-uv-manipulation.md +521 -0
- package/skills/shader-dev/reference/post-processing.md +375 -0
- package/skills/shader-dev/reference/procedural-2d-pattern.md +439 -0
- package/skills/shader-dev/reference/procedural-noise.md +551 -0
- package/skills/shader-dev/reference/ray-marching.md +396 -0
- package/skills/shader-dev/reference/sdf-2d.md +724 -0
- package/skills/shader-dev/reference/sdf-3d.md +805 -0
- package/skills/shader-dev/reference/sdf-tricks.md +63 -0
- package/skills/shader-dev/reference/shadow-techniques.md +476 -0
- package/skills/shader-dev/reference/simulation-physics.md +644 -0
- package/skills/shader-dev/reference/sound-synthesis.md +578 -0
- package/skills/shader-dev/reference/terrain-rendering.md +839 -0
- package/skills/shader-dev/reference/texture-mapping-advanced.md +87 -0
- package/skills/shader-dev/reference/texture-sampling.md +553 -0
- package/skills/shader-dev/reference/volumetric-rendering.md +608 -0
- package/skills/shader-dev/reference/voronoi-cellular-noise.md +486 -0
- package/skills/shader-dev/reference/voxel-rendering.md +701 -0
- package/skills/shader-dev/reference/water-ocean.md +445 -0
- package/skills/shader-dev/reference/webgl-pitfalls.md +41 -0
- package/skills/shader-dev/techniques/ambient-occlusion.md +364 -0
- package/skills/shader-dev/techniques/analytic-ray-tracing.md +542 -0
- package/skills/shader-dev/techniques/anti-aliasing.md +124 -0
- package/skills/shader-dev/techniques/atmospheric-scattering.md +522 -0
- package/skills/shader-dev/techniques/camera-effects.md +115 -0
- package/skills/shader-dev/techniques/cellular-automata.md +531 -0
- package/skills/shader-dev/techniques/color-palette.md +380 -0
- package/skills/shader-dev/techniques/csg-boolean-operations.md +491 -0
- package/skills/shader-dev/techniques/domain-repetition.md +333 -0
- package/skills/shader-dev/techniques/domain-warping.md +414 -0
- package/skills/shader-dev/techniques/fluid-simulation.md +1175 -0
- package/skills/shader-dev/techniques/fractal-rendering.md +436 -0
- package/skills/shader-dev/techniques/lighting-model.md +527 -0
- package/skills/shader-dev/techniques/matrix-transform.md +455 -0
- package/skills/shader-dev/techniques/multipass-buffer.md +922 -0
- package/skills/shader-dev/techniques/normal-estimation.md +318 -0
- package/skills/shader-dev/techniques/particle-system.md +1203 -0
- package/skills/shader-dev/techniques/path-tracing-gi.md +623 -0
- package/skills/shader-dev/techniques/polar-uv-manipulation.md +373 -0
- package/skills/shader-dev/techniques/post-processing.md +788 -0
- package/skills/shader-dev/techniques/procedural-2d-pattern.md +346 -0
- package/skills/shader-dev/techniques/procedural-noise.md +554 -0
- package/skills/shader-dev/techniques/ray-marching.md +467 -0
- package/skills/shader-dev/techniques/sdf-2d.md +631 -0
- package/skills/shader-dev/techniques/sdf-3d.md +589 -0
- package/skills/shader-dev/techniques/sdf-tricks.md +100 -0
- package/skills/shader-dev/techniques/shadow-techniques.md +776 -0
- package/skills/shader-dev/techniques/simulation-physics.md +1542 -0
- package/skills/shader-dev/techniques/sound-synthesis.md +490 -0
- package/skills/shader-dev/techniques/terrain-rendering.md +408 -0
- package/skills/shader-dev/techniques/texture-mapping-advanced.md +121 -0
- package/skills/shader-dev/techniques/texture-sampling.md +382 -0
- package/skills/shader-dev/techniques/volumetric-rendering.md +375 -0
- package/skills/shader-dev/techniques/voronoi-cellular-noise.md +458 -0
- package/skills/shader-dev/techniques/voxel-rendering.md +985 -0
- package/skills/shader-dev/techniques/water-ocean.md +490 -0
- package/skills/shader-dev/techniques/webgl-pitfalls.md +170 -0
- package/skills/shipping-and-launch/SKILL.md +334 -0
- package/skills/silent-failure-hunting/SKILL.md +24 -0
- package/skills/source-driven-development/SKILL.md +223 -0
- package/skills/spec-driven-development/SKILL.md +235 -0
- package/skills/spec-driven-development/references/upstream/addyosmani-agent-skills/6bcfeb9dae52b11eaad23511acc165109746dbc3/LICENSE +21 -0
- package/skills/spec-driven-development/references/upstream/addyosmani-agent-skills/6bcfeb9dae52b11eaad23511acc165109746dbc3/NOTICE.md +9 -0
- package/skills/spec-driven-development/references/upstream/addyosmani-agent-skills/6bcfeb9dae52b11eaad23511acc165109746dbc3/spec-driven-development/SKILL.upstream.md +206 -0
- package/skills/strategy-stress-test/SKILL.md +185 -0
- package/skills/systematic-literature-review/SKILL.md +77 -0
- package/skills/test-document-generator/SKILL.md +152 -0
- package/skills/test-document-generator/references/test-document-template.md +45 -0
- package/skills/test-driven-development/SKILL.md +399 -0
- package/skills/write-skills/GLOSSARY.md +113 -0
- package/skills/write-skills/SKILL.md +133 -0
- package/skills/write-skills/references/upstream/mattpocock-skills/391a2701dd948f94f56a39f7533f8eea9a859c87/LICENSE +21 -0
- package/skills/write-skills/references/upstream/mattpocock-skills/391a2701dd948f94f56a39f7533f8eea9a859c87/NOTICE.md +9 -0
- package/skills/write-skills/references/upstream/mattpocock-skills/391a2701dd948f94f56a39f7533f8eea9a859c87/productivity/writing-great-skills/GLOSSARY.md +201 -0
- package/skills/write-skills/references/upstream/mattpocock-skills/391a2701dd948f94f56a39f7533f8eea9a859c87/productivity/writing-great-skills/SKILL.upstream.md +83 -0
- package/src/runtime/child-guard.ts +70 -0
- package/src/runtime/conflicts.ts +25 -0
- package/src/runtime/contracts.ts +9 -0
- package/src/runtime/doctor.ts +134 -0
- package/src/runtime/global-resources.ts +152 -0
- package/src/runtime/index.ts +23 -0
- package/src/runtime/lifecycle.ts +19 -0
- package/src/runtime/native-integrations.ts +44 -0
- package/src/runtime/path-boundaries.ts +69 -0
- package/src/runtime/registry.ts +213 -0
- package/src/runtime/roles.ts +64 -0
- package/src/runtime/rose-context.ts +24 -0
- package/src/runtime/subagents.ts +426 -0
- package/templates/APPEND_SYSTEM.md +12 -0
- package/upstream/aili-workflows.lock.json +3226 -0
|
@@ -0,0 +1,922 @@
|
|
|
1
|
+
### Standalone HTML Complete Shader Template (Must Be Strictly Followed)
|
|
2
|
+
|
|
3
|
+
**IMPORTANT: The following template can be copied directly; every line must be strictly followed**:
|
|
4
|
+
|
|
5
|
+
**Vertex Shader** (common to all shaders):
|
|
6
|
+
```glsl
|
|
7
|
+
#version 300 es
|
|
8
|
+
in vec4 iPosition;
|
|
9
|
+
void main() {
|
|
10
|
+
gl_Position = iPosition;
|
|
11
|
+
}
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
**Fragment Shader Buffer A Example** (particle physics simulation):
|
|
15
|
+
```glsl
|
|
16
|
+
#version 300 es
|
|
17
|
+
precision highp float;
|
|
18
|
+
|
|
19
|
+
// IMPORTANT: Critical: uniforms must be declared; ShaderToy's iTime/iResolution etc. are global variables
|
|
20
|
+
uniform float iTime;
|
|
21
|
+
uniform vec2 iResolution;
|
|
22
|
+
uniform int iFrame;
|
|
23
|
+
uniform vec4 iMouse;
|
|
24
|
+
|
|
25
|
+
// IMPORTANT: Critical: mainImage parameters need manual extraction
|
|
26
|
+
// ShaderToy: void mainImage(out vec4 fragColor, in vec2 fragCoord)
|
|
27
|
+
// Adapted to:
|
|
28
|
+
out vec4 fragColor;
|
|
29
|
+
void main() {
|
|
30
|
+
vec2 fragCoord = gl_FragCoord.xy;
|
|
31
|
+
vec2 uv = fragCoord / iResolution;
|
|
32
|
+
|
|
33
|
+
// IMPORTANT: Critical: texture2D → texture
|
|
34
|
+
vec4 prev = texture(iChannel0, uv);
|
|
35
|
+
|
|
36
|
+
// ... particle physics logic ...
|
|
37
|
+
|
|
38
|
+
fragColor = vec4(pos, vel);
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**Fragment Shader Image Example**:
|
|
43
|
+
```glsl
|
|
44
|
+
#version 300 es
|
|
45
|
+
precision highp float;
|
|
46
|
+
|
|
47
|
+
uniform float iTime;
|
|
48
|
+
uniform vec2 iResolution;
|
|
49
|
+
uniform int iFrame;
|
|
50
|
+
uniform vec4 iMouse;
|
|
51
|
+
uniform sampler2D iChannel0;
|
|
52
|
+
|
|
53
|
+
out vec4 fragColor;
|
|
54
|
+
|
|
55
|
+
void main() {
|
|
56
|
+
vec2 fragCoord = gl_FragCoord.xy;
|
|
57
|
+
vec2 uv = fragCoord / iResolution;
|
|
58
|
+
|
|
59
|
+
// IMPORTANT: Critical: texture2D → texture, mainImage → standard main
|
|
60
|
+
vec4 col = texture(iChannel0, uv);
|
|
61
|
+
|
|
62
|
+
// Rendering logic
|
|
63
|
+
col = col / (1.0 + col); // Tone mapping
|
|
64
|
+
|
|
65
|
+
fragColor = col;
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**IMPORTANT: Common GLSL ES 3.00 Errors** (must be avoided):
|
|
70
|
+
1. **#version must be on the first line** - Any comments/blank lines will cause "version directive must occur on the first line" error
|
|
71
|
+
2. **in/out qualifiers** - WebGL1's attribute/varying must be changed to in/out in ES3
|
|
72
|
+
3. **texture function** - ES3 uses `texture(sampler, uv)`, not `texture2D(sampler, uv)`
|
|
73
|
+
4. **Type strictness** - `vec4 = float` is illegal, must use `vec4(v, v, v, v)` or `vec4(v)` or `vec4(vec3(v), 1.0)`
|
|
74
|
+
|
|
75
|
+
## Standalone HTML Multi-Channel Framebuffer Implementation
|
|
76
|
+
|
|
77
|
+
**IMPORTANT: Multi-Channel Rendering Pipeline Core Pitfalls**: ShaderToy code requires manual Framebuffer rendering pipeline implementation. The following template demonstrates the correct approach:
|
|
78
|
+
|
|
79
|
+
```javascript
|
|
80
|
+
// Correct multi-channel Framebuffer creation
|
|
81
|
+
const NUM_BUFFERS = 2; // Buffer A, Buffer B
|
|
82
|
+
const buffers = [];
|
|
83
|
+
const textures = [];
|
|
84
|
+
|
|
85
|
+
// Check float texture linear filtering extension
|
|
86
|
+
const ext = gl.getExtension('EXT_color_buffer_float');
|
|
87
|
+
const floatLinear = gl.getExtension('OES_texture_float_linear');
|
|
88
|
+
|
|
89
|
+
// Each Buffer needs an independent Framebuffer + texture
|
|
90
|
+
for (let i = 0; i < NUM_BUFFERS; i++) {
|
|
91
|
+
const texture = gl.createTexture();
|
|
92
|
+
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
93
|
+
|
|
94
|
+
// IMPORTANT: Critical: Must use UNSIGNED_BYTE format without EXT_color_buffer_float extension!
|
|
95
|
+
// RGBA16F/RGBA32F require the extension, otherwise GL_INVALID_OPERATION
|
|
96
|
+
// Float textures need EXT_color_buffer_float; RGBA16F supports HDR data
|
|
97
|
+
if (ext) {
|
|
98
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA16F, width, height, 0, gl.RGBA, gl.FLOAT, null);
|
|
99
|
+
} else {
|
|
100
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// IMPORTANT: Critical: Texture parameters must be set, otherwise GL_INVALID_FRAMEBUFFER
|
|
104
|
+
// IMPORTANT: Float textures use NEAREST, or require OES_texture_float_linear extension for LINEAR
|
|
105
|
+
// IMPORTANT: Critical: Float textures must use CLAMP_TO_EDGE wrap mode; REPEAT is not supported for float textures
|
|
106
|
+
// IMPORTANT: Critical: Must fall back to UNSIGNED_BYTE format without EXT_color_buffer_float extension
|
|
107
|
+
const filterMode = (ext && floatLinear) ? gl.LINEAR : gl.NEAREST;
|
|
108
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filterMode);
|
|
109
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filterMode);
|
|
110
|
+
// IMPORTANT: Must use CLAMP_TO_EDGE: float textures do not support REPEAT
|
|
111
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
112
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
113
|
+
|
|
114
|
+
const fbo = gl.createFramebuffer();
|
|
115
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
|
|
116
|
+
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
|
|
117
|
+
|
|
118
|
+
// IMPORTANT: Critical: Check Framebuffer completeness
|
|
119
|
+
const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
|
|
120
|
+
if (status !== gl.FRAMEBUFFER_COMPLETE) {
|
|
121
|
+
console.error("Framebuffer incomplete:", status);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
textures.push(texture);
|
|
125
|
+
buffers.push(fbo);
|
|
126
|
+
}
|
|
127
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
128
|
+
|
|
129
|
+
// Render loop: render to Buffer first, then render to screen
|
|
130
|
+
function render() {
|
|
131
|
+
// 1. Render to Buffer A (self-feedback reads previous Buffer)
|
|
132
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, buffers[0]);
|
|
133
|
+
gl.viewport(0, 0, width, height);
|
|
134
|
+
// Bind previous frame texture to iChannel0
|
|
135
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
136
|
+
gl.bindTexture(gl.TEXTURE_2D, textures[1]); // Read from other Buffer
|
|
137
|
+
// Set uniforms etc...
|
|
138
|
+
// Execute shader rendering
|
|
139
|
+
|
|
140
|
+
// 2. Swap Buffers (simulate self-feedback)
|
|
141
|
+
// IMPORTANT: Critical: Must swap textures for next frame reading; FBO handles remain unchanged
|
|
142
|
+
[textures[0], textures[1]] = [textures[1], textures[0]];
|
|
143
|
+
|
|
144
|
+
// 3. Render to screen
|
|
145
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
146
|
+
// Bind Buffer result to texture
|
|
147
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
148
|
+
gl.bindTexture(gl.TEXTURE_2D, textures[0]);
|
|
149
|
+
// Execute Image pass shader
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**IMPORTANT: Common Errors** (JavaScript/WebGL side):
|
|
154
|
+
1. **Missing texture parameters** - Must set `TEXTURE_MIN_FILTER`, `TEXTURE_MAG_FILTER`, `TEXTURE_WRAP_S/T`
|
|
155
|
+
2. **Missing Framebuffer completeness check** - `gl.checkFramebufferStatus()` must return `FRAMEBUFFER_COMPLETE` before use
|
|
156
|
+
3. **Float texture extension** - `gl.RGBA16F` requires `EXT_color_buffer_float` extension, otherwise fall back to `gl.UNSIGNED_BYTE`
|
|
157
|
+
4. **Buffer ping-pong error** - Self-feedback must use 2 independent FBOs alternating read/write; a single FBO + texture swap causes "Feedback loop" error
|
|
158
|
+
5. **Particle system empty texture initialization** - Textures are empty before the first frame; shaders reading default values cause render failure — must execute initPass() to pre-render
|
|
159
|
+
|
|
160
|
+
# Multi-Pass Buffer Techniques
|
|
161
|
+
|
|
162
|
+
## Use Cases
|
|
163
|
+
|
|
164
|
+
When single-frame computation cannot achieve the desired effect and cross-frame data persistence or multi-stage processing pipelines are needed, use multi-pass buffers:
|
|
165
|
+
|
|
166
|
+
- **Temporal accumulation**: Motion blur, TAA, progressive rendering
|
|
167
|
+
- **Physics simulation**: Fluids, reaction-diffusion, particle systems
|
|
168
|
+
- **Persistent state**: Game state, particle positions/velocities, interaction history
|
|
169
|
+
- **Deferred rendering**: G-Buffer → post-processing → compositing
|
|
170
|
+
- **Post-processing chains**: HDR Bloom (downsample → blur → composite)
|
|
171
|
+
- **Iterative solvers**: Poisson solver, vorticity confinement, multi-scale computation
|
|
172
|
+
|
|
173
|
+
## Core Principles
|
|
174
|
+
|
|
175
|
+
Multi-pass buffers split the rendering pipeline into multiple Buffers, each outputting a texture as input for the next stage.
|
|
176
|
+
|
|
177
|
+
### Self-Feedback
|
|
178
|
+
A Buffer reads its own previous frame output, achieving cross-frame state persistence: `x(n+1) = f(x(n))`
|
|
179
|
+
```
|
|
180
|
+
Buffer A (frame N) reads → Buffer A (frame N-1) output
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Pipeline Chaining
|
|
184
|
+
Multiple Buffers process in sequence:
|
|
185
|
+
```
|
|
186
|
+
Buffer A (geometry) → Buffer B (blur H) → Buffer C (blur V) → Image (compositing)
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Structured Data Storage
|
|
190
|
+
Specific pixels serve as data registers, read precisely via `texelFetch`:
|
|
191
|
+
```
|
|
192
|
+
texel (0,0) = ball position+velocity (vec4)
|
|
193
|
+
texel (1,0) = paddle position
|
|
194
|
+
texel (x,1)-(x,12) = brick grid state
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Key Mathematical Patterns
|
|
198
|
+
|
|
199
|
+
- **Fluid self-advection**: `newPos = texture(buf, uv - dt * velocity * texelSize)`
|
|
200
|
+
- **Gaussian blur**: `sum += texture(buf, uv + offset_i) * weight_i`
|
|
201
|
+
- **Temporal blending**: `result = mix(newFrame, prevFrame, blendWeight)`
|
|
202
|
+
- **Vorticity confinement**: `vortForce = curl × normalize(gradient(|curl|))`
|
|
203
|
+
|
|
204
|
+
## Implementation Steps
|
|
205
|
+
|
|
206
|
+
### Step 1: Minimal Self-Feedback Loop
|
|
207
|
+
|
|
208
|
+
Buffer A (iChannel0 → Buffer A self-feedback):
|
|
209
|
+
```glsl
|
|
210
|
+
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
|
|
211
|
+
vec2 uv = fragCoord / iResolution.xy;
|
|
212
|
+
|
|
213
|
+
vec4 prev = texture(iChannel0, uv);
|
|
214
|
+
|
|
215
|
+
// New content: procedural noise contour lines
|
|
216
|
+
float n = noise(vec3(uv * 8.0, 0.1 * iTime));
|
|
217
|
+
float v = sin(6.2832 * 10.0 * n);
|
|
218
|
+
v = smoothstep(1.0, 0.0, 0.5 * abs(v) / fwidth(v));
|
|
219
|
+
vec4 newContent = 0.5 + 0.5 * sin(12.0 * n + vec4(0, 2.1, -2.1, 0));
|
|
220
|
+
|
|
221
|
+
// Decay + offset blending
|
|
222
|
+
vec4 decayed = exp(-33.0 / iResolution.y) * texture(iChannel0, (fragCoord + vec2(1.0, sin(iTime))) / iResolution.xy);
|
|
223
|
+
fragColor = mix(decayed, newContent, v);
|
|
224
|
+
|
|
225
|
+
// Initialization guard
|
|
226
|
+
if (iFrame < 4) fragColor = vec4(0.5);
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
Image (iChannel0 → Buffer A):
|
|
231
|
+
```glsl
|
|
232
|
+
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
|
|
233
|
+
fragColor = texture(iChannel0, fragCoord / iResolution.xy);
|
|
234
|
+
}
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Step 2: Fluid Self-Advection
|
|
238
|
+
|
|
239
|
+
Buffer A (iChannel0 → Buffer A self-feedback):
|
|
240
|
+
```glsl
|
|
241
|
+
#define ROT_NUM 5
|
|
242
|
+
#define SCALE_NUM 20
|
|
243
|
+
|
|
244
|
+
const float ang = 6.2832 / float(ROT_NUM);
|
|
245
|
+
mat2 m = mat2(cos(ang), sin(ang), -sin(ang), cos(ang));
|
|
246
|
+
|
|
247
|
+
float getRot(vec2 pos, vec2 b) {
|
|
248
|
+
vec2 p = b;
|
|
249
|
+
float rot = 0.0;
|
|
250
|
+
for (int i = 0; i < ROT_NUM; i++) {
|
|
251
|
+
rot += dot(texture(iChannel0, fract((pos + p) / iResolution.xy)).xy - vec2(0.5),
|
|
252
|
+
p.yx * vec2(1, -1));
|
|
253
|
+
p = m * p;
|
|
254
|
+
}
|
|
255
|
+
return rot / float(ROT_NUM) / dot(b, b);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
|
|
259
|
+
vec2 pos = fragCoord;
|
|
260
|
+
float rnd = fract(sin(float(iFrame) * 12.9898) * 43758.5453);
|
|
261
|
+
vec2 b = vec2(cos(ang * rnd), sin(ang * rnd));
|
|
262
|
+
|
|
263
|
+
// Multi-scale rotation sampling
|
|
264
|
+
vec2 v = vec2(0);
|
|
265
|
+
float bbMax = 0.7 * iResolution.y;
|
|
266
|
+
bbMax *= bbMax;
|
|
267
|
+
for (int l = 0; l < SCALE_NUM; l++) {
|
|
268
|
+
if (dot(b, b) > bbMax) break;
|
|
269
|
+
vec2 p = b;
|
|
270
|
+
for (int i = 0; i < ROT_NUM; i++) {
|
|
271
|
+
v += p.yx * getRot(pos + p, b);
|
|
272
|
+
p = m * p;
|
|
273
|
+
}
|
|
274
|
+
b *= 2.0;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Self-advection
|
|
278
|
+
fragColor = texture(iChannel0, fract((pos + v * vec2(-1, 1) * 2.0) / iResolution.xy));
|
|
279
|
+
|
|
280
|
+
// Center driving force
|
|
281
|
+
vec2 scr = (fragCoord / iResolution.xy) * 2.0 - 1.0;
|
|
282
|
+
fragColor.xy += 0.01 * scr / (dot(scr, scr) / 0.1 + 0.3);
|
|
283
|
+
|
|
284
|
+
if (iFrame <= 4) fragColor = texture(iChannel1, fragCoord / iResolution.xy);
|
|
285
|
+
}
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### Step 3-4: Navier-Stokes Solver + Chained Acceleration
|
|
289
|
+
|
|
290
|
+
Buffer A / B / C use identical code (via Common tab's `solveFluid`):
|
|
291
|
+
```glsl
|
|
292
|
+
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
|
|
293
|
+
vec2 uv = fragCoord / iResolution.xy;
|
|
294
|
+
vec2 w = 1.0 / iResolution.xy;
|
|
295
|
+
|
|
296
|
+
vec4 lastMouse = texelFetch(iChannel0, ivec2(0, 0), 0);
|
|
297
|
+
vec4 data = solveFluid(iChannel0, uv, w, iTime, iMouse.xyz, lastMouse.xyz);
|
|
298
|
+
|
|
299
|
+
if (iFrame < 20) data = vec4(0.5, 0, 0, 0);
|
|
300
|
+
if (fragCoord.y < 1.0) data = iMouse; // Mouse state storage
|
|
301
|
+
|
|
302
|
+
fragColor = data;
|
|
303
|
+
}
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
iChannel bindings: A→C(prev frame), B→A, C→B — 3 iterations per frame.
|
|
307
|
+
|
|
308
|
+
### Step 5: Separable Gaussian Blur
|
|
309
|
+
|
|
310
|
+
Buffer B (horizontal, iChannel0 → source Buffer) — Buffer C vertical direction is analogous, using y-axis offset:
|
|
311
|
+
```glsl
|
|
312
|
+
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
|
|
313
|
+
vec2 pixelSize = 1.0 / iResolution.xy;
|
|
314
|
+
vec2 uv = fragCoord * pixelSize;
|
|
315
|
+
float h = pixelSize.x;
|
|
316
|
+
vec4 sum = vec4(0.0);
|
|
317
|
+
// 9-tap Gaussian (sigma ≈ 2.0)
|
|
318
|
+
sum += texture(iChannel0, fract(vec2(uv.x - 4.0*h, uv.y))) * 0.05;
|
|
319
|
+
sum += texture(iChannel0, fract(vec2(uv.x - 3.0*h, uv.y))) * 0.09;
|
|
320
|
+
sum += texture(iChannel0, fract(vec2(uv.x - 2.0*h, uv.y))) * 0.12;
|
|
321
|
+
sum += texture(iChannel0, fract(vec2(uv.x - 1.0*h, uv.y))) * 0.15;
|
|
322
|
+
sum += texture(iChannel0, fract(vec2(uv.x, uv.y))) * 0.16;
|
|
323
|
+
sum += texture(iChannel0, fract(vec2(uv.x + 1.0*h, uv.y))) * 0.15;
|
|
324
|
+
sum += texture(iChannel0, fract(vec2(uv.x + 2.0*h, uv.y))) * 0.12;
|
|
325
|
+
sum += texture(iChannel0, fract(vec2(uv.x + 3.0*h, uv.y))) * 0.09;
|
|
326
|
+
sum += texture(iChannel0, fract(vec2(uv.x + 4.0*h, uv.y))) * 0.05;
|
|
327
|
+
fragColor = vec4(sum.xyz / 0.98, 1.0);
|
|
328
|
+
}
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### Step 6: Structured State Storage
|
|
332
|
+
|
|
333
|
+
```glsl
|
|
334
|
+
// Register address definitions
|
|
335
|
+
const ivec2 txBallPosVel = ivec2(0, 0);
|
|
336
|
+
const ivec2 txPaddlePos = ivec2(1, 0);
|
|
337
|
+
const ivec2 txPoints = ivec2(2, 0);
|
|
338
|
+
const ivec2 txState = ivec2(3, 0);
|
|
339
|
+
const ivec4 txBricks = ivec4(0, 1, 13, 12);
|
|
340
|
+
|
|
341
|
+
vec4 loadValue(ivec2 addr) {
|
|
342
|
+
return texelFetch(iChannel0, addr, 0);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
void storeValue(ivec2 addr, vec4 val, inout vec4 fragColor, ivec2 currentPixel) {
|
|
346
|
+
fragColor = (currentPixel == addr) ? val : fragColor;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
void storeValue(ivec4 rect, vec4 val, inout vec4 fragColor, ivec2 currentPixel) {
|
|
350
|
+
fragColor = (currentPixel.x >= rect.x && currentPixel.y >= rect.y &&
|
|
351
|
+
currentPixel.x <= rect.z && currentPixel.y <= rect.w) ? val : fragColor;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
|
|
355
|
+
ivec2 px = ivec2(fragCoord - 0.5);
|
|
356
|
+
if (fragCoord.x > 14.0 || fragCoord.y > 14.0) discard;
|
|
357
|
+
|
|
358
|
+
vec4 ballPosVel = loadValue(txBallPosVel);
|
|
359
|
+
float paddlePos = loadValue(txPaddlePos).x;
|
|
360
|
+
float points = loadValue(txPoints).x;
|
|
361
|
+
|
|
362
|
+
if (iFrame == 0) {
|
|
363
|
+
ballPosVel = vec4(0.0, -0.8, 0.6, 1.0);
|
|
364
|
+
paddlePos = 0.0;
|
|
365
|
+
points = 0.0;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// ... game logic update ...
|
|
369
|
+
|
|
370
|
+
fragColor = loadValue(px);
|
|
371
|
+
storeValue(txBallPosVel, ballPosVel, fragColor, px);
|
|
372
|
+
storeValue(txPaddlePos, vec4(paddlePos, 0, 0, 0), fragColor, px);
|
|
373
|
+
storeValue(txPoints, vec4(points, 0, 0, 0), fragColor, px);
|
|
374
|
+
}
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
### Step 7: Mouse State Inter-Frame Tracking
|
|
378
|
+
|
|
379
|
+
```glsl
|
|
380
|
+
// Method 1: First-row pixel storage
|
|
381
|
+
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
|
|
382
|
+
vec2 uv = fragCoord / iResolution.xy;
|
|
383
|
+
vec2 w = 1.0 / iResolution.xy;
|
|
384
|
+
vec4 lastMouse = texelFetch(iChannel0, ivec2(0, 0), 0);
|
|
385
|
+
// ... simulation logic ...
|
|
386
|
+
if (fragCoord.y < 1.0) fragColor = iMouse;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// Method 2: Fixed UV region storage
|
|
390
|
+
vec2 mouseDelta() {
|
|
391
|
+
vec2 pixelSize = 1.0 / iResolution.xy;
|
|
392
|
+
float eighth = 1.0 / 8.0;
|
|
393
|
+
vec4 oldMouse = texture(iChannel2, vec2(7.5 * eighth, 2.5 * eighth));
|
|
394
|
+
vec4 nowMouse = vec4(iMouse.xy / iResolution.xy, iMouse.zw / iResolution.xy);
|
|
395
|
+
if (oldMouse.z > pixelSize.x && oldMouse.w > pixelSize.y &&
|
|
396
|
+
nowMouse.z > pixelSize.x && nowMouse.w > pixelSize.y) {
|
|
397
|
+
return nowMouse.xy - oldMouse.xy;
|
|
398
|
+
}
|
|
399
|
+
return vec2(0.0);
|
|
400
|
+
}
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
## Complete Code Template
|
|
404
|
+
|
|
405
|
+
A fully runnable fluid simulation shader (self-feedback + vorticity confinement + mouse interaction + color advection).
|
|
406
|
+
|
|
407
|
+
### Common tab
|
|
408
|
+
|
|
409
|
+
```glsl
|
|
410
|
+
#define DT 0.15
|
|
411
|
+
#define VORTICITY_AMOUNT 0.11
|
|
412
|
+
#define VISCOSITY 0.55
|
|
413
|
+
#define PRESSURE_K 0.2
|
|
414
|
+
#define FORCE_RADIUS 0.001
|
|
415
|
+
#define FORCE_STRENGTH 0.001
|
|
416
|
+
#define VELOCITY_DECAY 1e-4
|
|
417
|
+
|
|
418
|
+
float mag2(vec2 p) { return dot(p, p); }
|
|
419
|
+
|
|
420
|
+
vec2 emitter1(float t) { t *= 0.62; return vec2(0.12, 0.5 + sin(t) * 0.2); }
|
|
421
|
+
vec2 emitter2(float t) { t *= 0.62; return vec2(0.88, 0.5 + cos(t + 1.5708) * 0.2); }
|
|
422
|
+
|
|
423
|
+
vec4 solveFluid(sampler2D smp, vec2 uv, vec2 w, float time, vec3 mouse, vec3 lastMouse) {
|
|
424
|
+
vec4 data = textureLod(smp, uv, 0.0);
|
|
425
|
+
vec4 tr = textureLod(smp, uv + vec2(w.x, 0), 0.0);
|
|
426
|
+
vec4 tl = textureLod(smp, uv - vec2(w.x, 0), 0.0);
|
|
427
|
+
vec4 tu = textureLod(smp, uv + vec2(0, w.y), 0.0);
|
|
428
|
+
vec4 td = textureLod(smp, uv - vec2(0, w.y), 0.0);
|
|
429
|
+
|
|
430
|
+
vec3 dx = (tr.xyz - tl.xyz) * 0.5;
|
|
431
|
+
vec3 dy = (tu.xyz - td.xyz) * 0.5;
|
|
432
|
+
vec2 densDif = vec2(dx.z, dy.z);
|
|
433
|
+
|
|
434
|
+
data.z -= DT * dot(vec3(densDif, dx.x + dy.y), data.xyz);
|
|
435
|
+
|
|
436
|
+
vec2 laplacian = tu.xy + td.xy + tr.xy + tl.xy - 4.0 * data.xy;
|
|
437
|
+
vec2 viscForce = vec2(VISCOSITY) * laplacian;
|
|
438
|
+
|
|
439
|
+
data.xyw = textureLod(smp, uv - DT * data.xy * w, 0.0).xyw;
|
|
440
|
+
|
|
441
|
+
vec2 newForce = vec2(0);
|
|
442
|
+
newForce += 0.75 * vec2(0.0003, 0.00015) / (mag2(uv - emitter1(time)) + 0.0001);
|
|
443
|
+
newForce -= 0.75 * vec2(0.0003, 0.00015) / (mag2(uv - emitter2(time)) + 0.0001);
|
|
444
|
+
|
|
445
|
+
if (mouse.z > 1.0 && lastMouse.z > 1.0) {
|
|
446
|
+
vec2 vv = clamp((mouse.xy * w - lastMouse.xy * w) * 400.0, -6.0, 6.0);
|
|
447
|
+
newForce += FORCE_STRENGTH / (mag2(uv - mouse.xy * w) + FORCE_RADIUS) * vv;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
data.xy += DT * (viscForce - PRESSURE_K / DT * densDif + newForce);
|
|
451
|
+
data.xy = max(vec2(0), abs(data.xy) - VELOCITY_DECAY) * sign(data.xy);
|
|
452
|
+
|
|
453
|
+
data.w = (tr.y - tl.y - tu.x + td.x);
|
|
454
|
+
vec2 vort = vec2(abs(tu.w) - abs(td.w), abs(tl.w) - abs(tr.w));
|
|
455
|
+
vort *= VORTICITY_AMOUNT / length(vort + 1e-9) * data.w;
|
|
456
|
+
data.xy += vort;
|
|
457
|
+
|
|
458
|
+
data.y *= smoothstep(0.5, 0.48, abs(uv.y - 0.5));
|
|
459
|
+
data = clamp(data, vec4(vec2(-10), 0.5, -10.0), vec4(vec2(10), 3.0, 10.0));
|
|
460
|
+
|
|
461
|
+
return data;
|
|
462
|
+
}
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
### Buffer A / B / C (Fluid Sub-Steps 1/2/3)
|
|
466
|
+
|
|
467
|
+
iChannel bindings: A←C(prev frame), B←A, C←B
|
|
468
|
+
|
|
469
|
+
```glsl
|
|
470
|
+
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
|
|
471
|
+
vec2 uv = fragCoord / iResolution.xy;
|
|
472
|
+
vec2 w = 1.0 / iResolution.xy;
|
|
473
|
+
vec4 lastMouse = texelFetch(iChannel0, ivec2(0, 0), 0);
|
|
474
|
+
vec4 data = solveFluid(iChannel0, uv, w, iTime, iMouse.xyz, lastMouse.xyz);
|
|
475
|
+
if (iFrame < 20) data = vec4(0.5, 0, 0, 0);
|
|
476
|
+
if (fragCoord.y < 1.0) data = iMouse;
|
|
477
|
+
fragColor = data;
|
|
478
|
+
}
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
### Buffer D (Color Advection, iChannel0 → Buffer C, iChannel1 → Buffer D self-feedback)
|
|
482
|
+
|
|
483
|
+
```glsl
|
|
484
|
+
#define COLOR_DECAY 0.004
|
|
485
|
+
#define COLOR_ADVECT_SCALE 3.0
|
|
486
|
+
|
|
487
|
+
vec3 getPalette(float x, vec3 c1, vec3 c2, vec3 p1, vec3 p2) {
|
|
488
|
+
float x2 = fract(x / 2.0);
|
|
489
|
+
x = fract(x);
|
|
490
|
+
mat3 m = mat3(c1, p1, c2);
|
|
491
|
+
mat3 m2 = mat3(c2, p2, c1);
|
|
492
|
+
float omx = 1.0 - x;
|
|
493
|
+
vec3 pws = vec3(omx * omx, 2.0 * omx * x, x * x);
|
|
494
|
+
return clamp(mix(m * pws, m2 * pws, step(x2, 0.5)), 0.0, 1.0);
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
vec4 palette1(float x) {
|
|
498
|
+
return vec4(getPalette(-x, vec3(0.2, 0.5, 0.7), vec3(0.9, 0.4, 0.1),
|
|
499
|
+
vec3(1.0, 1.2, 0.5), vec3(1.0, -0.4, 0.0)), 1.0);
|
|
500
|
+
}
|
|
501
|
+
vec4 palette2(float x) {
|
|
502
|
+
return vec4(getPalette(-x, vec3(0.4, 0.3, 0.5), vec3(0.9, 0.75, 0.4),
|
|
503
|
+
vec3(0.1, 0.8, 1.3), vec3(1.25, -0.1, 0.1)), 1.0);
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
|
|
507
|
+
vec2 uv = fragCoord / iResolution.xy;
|
|
508
|
+
vec2 w = 1.0 / iResolution.xy;
|
|
509
|
+
|
|
510
|
+
vec2 velo = textureLod(iChannel0, uv, 0.0).xy;
|
|
511
|
+
vec4 col = textureLod(iChannel1, uv - DT * velo * w * COLOR_ADVECT_SCALE, 0.0);
|
|
512
|
+
|
|
513
|
+
vec2 mo = iMouse.xy / iResolution.xy;
|
|
514
|
+
vec4 lastMouse = texelFetch(iChannel1, ivec2(0, 0), 0);
|
|
515
|
+
if (iMouse.z > 1.0 && lastMouse.z > 1.0) {
|
|
516
|
+
float str = smoothstep(-0.5, 1.0, length(mo - lastMouse.xy / iResolution.xy));
|
|
517
|
+
col += str * 0.0009 / (pow(length(uv - mo), 1.7) + 0.002) * palette2(-iTime * 0.7);
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
col += 0.0025 / (0.0005 + pow(length(uv - emitter1(iTime)), 1.75)) * DT * 0.12 * palette1(iTime * 0.05);
|
|
521
|
+
col += 0.0025 / (0.0005 + pow(length(uv - emitter2(iTime)), 1.75)) * DT * 0.12 * palette2(iTime * 0.05 + 0.675);
|
|
522
|
+
|
|
523
|
+
if (iFrame < 20) col = vec4(0.0);
|
|
524
|
+
col = clamp(col, 0.0, 5.0);
|
|
525
|
+
col = max(col - (0.0001 + col * COLOR_DECAY) * 0.5, 0.0);
|
|
526
|
+
|
|
527
|
+
if (fragCoord.y < 1.0 && fragCoord.x < 1.0) col = iMouse;
|
|
528
|
+
fragColor = col;
|
|
529
|
+
}
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
### Image (iChannel0 → Buffer D)
|
|
533
|
+
|
|
534
|
+
```glsl
|
|
535
|
+
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
|
|
536
|
+
vec4 col = textureLod(iChannel0, fragCoord / iResolution.xy, 0.0);
|
|
537
|
+
if (fragCoord.y < 1.0 || fragCoord.y >= iResolution.y - 1.0) col = vec4(0);
|
|
538
|
+
fragColor = col;
|
|
539
|
+
}
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
## Common Variants
|
|
543
|
+
|
|
544
|
+
### Variant 1: TAA Temporal Accumulation Anti-Aliasing
|
|
545
|
+
|
|
546
|
+
```glsl
|
|
547
|
+
// Buffer A: Sub-pixel jittered rendering
|
|
548
|
+
vec2 jitter = vec2(rand(uv + sin(iTime)), rand(uv + 1.0 + sin(iTime))) / iResolution.xy;
|
|
549
|
+
vec3 eyevec = normalize(vec3(((uv + jitter) * 2.0 - 1.0) * vec2(aspect, 1.0), fov));
|
|
550
|
+
float blendWeight = 0.9;
|
|
551
|
+
color = mix(color, texture(iChannel_self, uv).rgb, blendWeight);
|
|
552
|
+
|
|
553
|
+
// Buffer C (TAA): YCoCg neighborhood clamping to prevent ghosting
|
|
554
|
+
vec3 newYCC = RGBToYCoCg(newFrame);
|
|
555
|
+
vec3 histYCC = RGBToYCoCg(history);
|
|
556
|
+
vec3 colorAvg = ...; vec3 colorVar = ...;
|
|
557
|
+
vec3 sigma = sqrt(max(vec3(0), colorVar - colorAvg * colorAvg));
|
|
558
|
+
histYCC = clamp(histYCC, colorAvg - 0.75 * sigma, colorAvg + 0.75 * sigma);
|
|
559
|
+
result = YCoCgToRGB(mix(newYCC, histYCC, 0.95));
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
### Variant 2: Deferred Rendering G-Buffer
|
|
563
|
+
|
|
564
|
+
```glsl
|
|
565
|
+
// Buffer A: G-Buffer output
|
|
566
|
+
col.xy = (normal * camMat * 0.5 + 0.5).xy; // Normal
|
|
567
|
+
col.z = 1.0 - abs((t * rd) * camMat).z / DMAX; // Depth
|
|
568
|
+
col.w = dot(lightDir, nor) * 0.5 + 0.5; // Diffuse
|
|
569
|
+
|
|
570
|
+
// Buffer B: Edge detection
|
|
571
|
+
float checkSame(vec4 center, vec4 sample) {
|
|
572
|
+
vec2 diffNormal = abs(center.xy - sample.xy) * Sensitivity.x;
|
|
573
|
+
float diffDepth = abs(center.z - sample.z) * Sensitivity.y;
|
|
574
|
+
return (diffNormal.x + diffNormal.y < 0.1 && diffDepth < 0.1) ? 1.0 : 0.0;
|
|
575
|
+
}
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
### Variant 3: HDR Bloom
|
|
579
|
+
|
|
580
|
+
```glsl
|
|
581
|
+
// Buffer B: MIP pyramid (multi-level downsampling packed into one texture)
|
|
582
|
+
vec2 CalcOffset(float octave) {
|
|
583
|
+
vec2 offset = vec2(0);
|
|
584
|
+
vec2 padding = vec2(10.0) / iResolution.xy;
|
|
585
|
+
offset.x = -min(1.0, floor(octave / 3.0)) * (0.25 + padding.x);
|
|
586
|
+
offset.y = -(1.0 - 1.0 / exp2(octave)) - padding.y * octave;
|
|
587
|
+
offset.y += min(1.0, floor(octave / 3.0)) * 0.35;
|
|
588
|
+
return offset;
|
|
589
|
+
}
|
|
590
|
+
// Image: Accumulate multi-level bloom + Reinhard tone mapping
|
|
591
|
+
bloom += Grab(coord, 1.0, CalcOffset(0.0)) * 1.0;
|
|
592
|
+
bloom += Grab(coord, 2.0, CalcOffset(1.0)) * 1.5;
|
|
593
|
+
color = pow(color, vec3(1.5));
|
|
594
|
+
color = color / (1.0 + color);
|
|
595
|
+
```
|
|
596
|
+
|
|
597
|
+
### Variant 4: Reaction-Diffusion System
|
|
598
|
+
|
|
599
|
+
```glsl
|
|
600
|
+
// Buffer A: Gray-Scott reaction-diffusion
|
|
601
|
+
vec2 uv_red = uv + vec2(dx.x, dy.x) * pixelSize * 8.0;
|
|
602
|
+
float new_val = texture(iChannel0, fract(uv_red)).x;
|
|
603
|
+
new_val += (noise.x - 0.5) * 0.0025 - 0.002;
|
|
604
|
+
new_val -= (texture(iChannel_blur, fract(uv_red)).x -
|
|
605
|
+
texture(iChannel_self, fract(uv_red)).x) * 0.047;
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
### Variant 5: Multi-Scale MIP Fluid
|
|
609
|
+
|
|
610
|
+
```glsl
|
|
611
|
+
for (int i = 0; i < NUM_SCALES; i++) {
|
|
612
|
+
float mip = float(i);
|
|
613
|
+
float stride = float(1 << i);
|
|
614
|
+
vec4 t = stride * vec4(texel, -texel.y, 0);
|
|
615
|
+
vec2 d = textureLod(sampler, fract(uv + t.ww), mip).xy;
|
|
616
|
+
float w = WEIGHT_FUNCTION;
|
|
617
|
+
result += w * computation(neighbors);
|
|
618
|
+
}
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
### Variant 6: Particle System (Position-Velocity Storage)
|
|
622
|
+
|
|
623
|
+
**IMPORTANT: Particle System Implementation Key**: Particle state is stored in texture pixels, one particle per pixel. Rendering must iterate over the particle texture for sampling.
|
|
624
|
+
|
|
625
|
+
**Buffer A (Particle Physics Simulation)**:
|
|
626
|
+
```glsl
|
|
627
|
+
// Each texture pixel stores one particle: xy=position, zw=velocity
|
|
628
|
+
|
|
629
|
+
// IMPORTANT: Critical: hash function must return vec2! Returning float causes type mismatch errors
|
|
630
|
+
vec2 hash2(vec2 p) {
|
|
631
|
+
return fract(sin(mat2(127.1, 311.7, 269.5, 183.3) * p) * 43758.5453);
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
|
|
635
|
+
vec2 uv = fragCoord / iResolution.xy;
|
|
636
|
+
vec4 prev = texture(iChannel0, uv);
|
|
637
|
+
|
|
638
|
+
vec2 pos = prev.xy;
|
|
639
|
+
vec2 vel = prev.zw;
|
|
640
|
+
|
|
641
|
+
// IMPORTANT: Initialization guard: use integer comparison + pixel-coordinate-based random (avoids particle overlap when time is too small)
|
|
642
|
+
if (iFrame < 3) {
|
|
643
|
+
// Use fragCoord (pixel coordinates) to ensure each particle has a unique position, independent of time
|
|
644
|
+
// IMPORTANT: Critical: hash2 returns vec2, assign directly to pos/vel
|
|
645
|
+
pos = hash2(fragCoord * 0.01 + vec2(1.7, 9.3));
|
|
646
|
+
vel = (hash2(fragCoord * 0.01 + vec2(5.3, 2.8)) - 0.5) * 0.02;
|
|
647
|
+
fragColor = vec4(pos, vel);
|
|
648
|
+
return;
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
// Physics update
|
|
652
|
+
vel *= 0.98; // Damping
|
|
653
|
+
|
|
654
|
+
// Mouse interaction
|
|
655
|
+
vec2 mouse = iMouse.xy / iResolution.xy;
|
|
656
|
+
if (iMouse.z > 0.0) {
|
|
657
|
+
vec2 toMouse = mouse - pos;
|
|
658
|
+
vel += normalize(toMouse + 0.001) * 0.0005 / (length(toMouse) + 0.1);
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
// Motion
|
|
662
|
+
pos += vel * 60.0 * 0.016;
|
|
663
|
+
pos = fract(pos); // Boundary wrapping
|
|
664
|
+
|
|
665
|
+
fragColor = vec4(pos, vel);
|
|
666
|
+
}
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
**Image (Render Particles)**:
|
|
670
|
+
```glsl
|
|
671
|
+
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
|
|
672
|
+
vec2 uv = fragCoord / iResolution.xy;
|
|
673
|
+
vec2 w = 1.0 / iResolution.xy;
|
|
674
|
+
|
|
675
|
+
vec3 color = vec3(0.02, 0.02, 0.05); // Dark background
|
|
676
|
+
|
|
677
|
+
// Iterate over particle texture for sampling (performance-sensitive, balance sample count)
|
|
678
|
+
float glow = 0.0;
|
|
679
|
+
for (float y = 0.0; y < 1.0; y += 0.02) { // IMPORTANT: Step size determines sampling density
|
|
680
|
+
for (float x = 0.0; x < 1.0; x += 0.02) {
|
|
681
|
+
vec4 particle = texture(iChannel0, vec2(x, y));
|
|
682
|
+
vec2 pPos = particle.xy;
|
|
683
|
+
float dist = length(uv - pPos);
|
|
684
|
+
float size = 0.01 + length(particle.zw) * 0.3;
|
|
685
|
+
glow += exp(-dist * dist / (size * size)) * 0.15;
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
// Particle glow
|
|
690
|
+
color += vec3(0.3, 0.6, 1.0) * glow;
|
|
691
|
+
|
|
692
|
+
// Vignette
|
|
693
|
+
color *= 1.0 - length(uv - 0.5) * 0.8;
|
|
694
|
+
|
|
695
|
+
// Tone mapping
|
|
696
|
+
color = color / (1.0 + color);
|
|
697
|
+
|
|
698
|
+
fragColor = vec4(color, 1.0);
|
|
699
|
+
}
|
|
700
|
+
```
|
|
701
|
+
|
|
702
|
+
**Key Points**:
|
|
703
|
+
- Buffer A self-feedback: iChannel0 → Buffer A
|
|
704
|
+
- Image reads: iChannel0 → Buffer A (particle state)
|
|
705
|
+
- Step size 0.02 produces 2500 samples; adjust based on performance
|
|
706
|
+
- Particle size varies with velocity: `size = 0.01 + length(vel) * 0.3`
|
|
707
|
+
|
|
708
|
+
**Complete JavaScript Rendering Pipeline (Particle System 3-Pass)**:
|
|
709
|
+
```javascript
|
|
710
|
+
// Particle system needs 4 Framebuffers (2 each for Buffer A and Buffer B ping-pong) + screen output
|
|
711
|
+
// Buffer A: Particle physics (self-feedback) - uses FBO 0/1 ping-pong
|
|
712
|
+
// Buffer B: Density accumulation (reads Buffer A) - uses FBO 2/3 ping-pong
|
|
713
|
+
// Image: Final rendering (reads Buffer A + Buffer B)
|
|
714
|
+
|
|
715
|
+
// IMPORTANT: Critical: Must use 2 FBOs for ping-pong! Single FBO + texture swap causes
|
|
716
|
+
// "Feedback loop formed between Framebuffer and active Texture" error
|
|
717
|
+
const buffers = [null, null, null, null]; // [A_FBO0, A_FBO1, B_FBO0, B_FBO1]
|
|
718
|
+
const textures = [null, null, null, null]; // [A_tex0, A_tex1, B_tex0, B_tex1]
|
|
719
|
+
|
|
720
|
+
function createBuffers() {
|
|
721
|
+
// Buffer A: 2 FBOs for ping-pong
|
|
722
|
+
for (let i = 0; i < 2; i++) {
|
|
723
|
+
const tex = createTexture();
|
|
724
|
+
textures[i] = tex;
|
|
725
|
+
|
|
726
|
+
const fbo = gl.createFramebuffer();
|
|
727
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
|
|
728
|
+
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
|
|
729
|
+
buffers[i] = fbo;
|
|
730
|
+
}
|
|
731
|
+
// Buffer B: 2 FBOs for ping-pong
|
|
732
|
+
for (let i = 0; i < 2; i++) {
|
|
733
|
+
const tex = createTexture();
|
|
734
|
+
textures[2 + i] = tex;
|
|
735
|
+
|
|
736
|
+
const fbo = gl.createFramebuffer();
|
|
737
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
|
|
738
|
+
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
|
|
739
|
+
buffers[2 + i] = fbo;
|
|
740
|
+
}
|
|
741
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
// IMPORTANT: Critical: Initialization pre-rendering - must execute before the first frame!
|
|
745
|
+
// Empty textures cause particle initialization failure (reading 0,0,0,0 makes all particles overlap)
|
|
746
|
+
let aReadIdx = 0; // Current read FBO index (0 or 1)
|
|
747
|
+
let bReadIdx = 0; // Buffer B current read FBO index (0 or 1)
|
|
748
|
+
|
|
749
|
+
function initPass() {
|
|
750
|
+
// ===== Buffer A Initialization =====
|
|
751
|
+
// Render first frame using FBO 0
|
|
752
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, buffers[0]);
|
|
753
|
+
gl.viewport(0, 0, width, height);
|
|
754
|
+
gl.useProgram(programBufferA);
|
|
755
|
+
setupAttribute(programBufferA);
|
|
756
|
+
// Bind FBO 1's texture as input (not yet rendered, but avoids binding errors)
|
|
757
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
758
|
+
gl.bindTexture(gl.TEXTURE_2D, textures[1]);
|
|
759
|
+
gl.uniform1i(gl.getUniformLocation(programBufferA, 'iChannel0'), 0);
|
|
760
|
+
gl.uniform2f(gl.getUniformLocation(programBufferA, 'iResolution'), width, height);
|
|
761
|
+
gl.uniform1f(gl.getUniformLocation(programBufferA, 'iTime'), 0);
|
|
762
|
+
gl.uniform1i(gl.getUniformLocation(programBufferA, 'iFrame'), 0);
|
|
763
|
+
gl.uniform4f(gl.getUniformLocation(programBufferA, 'iMouse'), 0, 0, 0, 0);
|
|
764
|
+
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
|
765
|
+
|
|
766
|
+
// Render second frame using FBO 1 (iFrame=1)
|
|
767
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, buffers[1]);
|
|
768
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
769
|
+
gl.bindTexture(gl.TEXTURE_2D, textures[0]); // Read FBO 0's result
|
|
770
|
+
gl.uniform1i(gl.getUniformLocation(programBufferA, 'iFrame'), 1);
|
|
771
|
+
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
|
772
|
+
|
|
773
|
+
// Render one more frame to ensure initialization is complete
|
|
774
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, buffers[0]);
|
|
775
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
776
|
+
gl.bindTexture(gl.TEXTURE_2D, textures[1]);
|
|
777
|
+
gl.uniform1i(gl.getUniformLocation(programBufferA, 'iFrame'), 2);
|
|
778
|
+
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
|
779
|
+
|
|
780
|
+
// ===== Buffer B Initialization =====
|
|
781
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, buffers[2]); // B_FBO0
|
|
782
|
+
gl.viewport(0, 0, width, height);
|
|
783
|
+
gl.useProgram(programBufferB);
|
|
784
|
+
setupAttribute(programBufferB);
|
|
785
|
+
|
|
786
|
+
// Bind latest Buffer A result (FBO 0's result)
|
|
787
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
788
|
+
gl.bindTexture(gl.TEXTURE_2D, textures[0]);
|
|
789
|
+
gl.uniform1i(gl.getUniformLocation(programBufferB, 'iChannel0'), 0);
|
|
790
|
+
|
|
791
|
+
// Bind Buffer B previous frame (FBO 3's texture, not yet rendered)
|
|
792
|
+
gl.activeTexture(gl.TEXTURE1);
|
|
793
|
+
gl.bindTexture(gl.TEXTURE_2D, textures[3]);
|
|
794
|
+
gl.uniform1i(gl.getUniformLocation(programBufferB, 'iChannel1'), 1);
|
|
795
|
+
|
|
796
|
+
gl.uniform2f(gl.getUniformLocation(programBufferB, 'iResolution'), width, height);
|
|
797
|
+
gl.uniform1f(gl.getUniformLocation(programBufferB, 'iTime'), 0);
|
|
798
|
+
gl.uniform1i(gl.getUniformLocation(programBufferB, 'iFrame'), 0);
|
|
799
|
+
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
|
800
|
+
|
|
801
|
+
// Buffer B second frame
|
|
802
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, buffers[3]); // B_FBO1
|
|
803
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
804
|
+
gl.bindTexture(gl.TEXTURE_2D, textures[1]); // Buffer A latest
|
|
805
|
+
gl.activeTexture(gl.TEXTURE1);
|
|
806
|
+
gl.bindTexture(gl.TEXTURE_2D, textures[2]); // Buffer B FBO0 result
|
|
807
|
+
gl.uniform1i(gl.getUniformLocation(programBufferB, 'iFrame'), 1);
|
|
808
|
+
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
|
809
|
+
|
|
810
|
+
// Initialize ping-pong indices
|
|
811
|
+
aReadIdx = 0; // Next frame reads FBO 0
|
|
812
|
+
bReadIdx = 0; // Next frame reads FBO 2
|
|
813
|
+
|
|
814
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
function render() {
|
|
818
|
+
// ===== Pass 1: Buffer A (Particle Physics Self-Feedback) =====
|
|
819
|
+
// aReadIdx = 0: read FBO 0, write FBO 1
|
|
820
|
+
// aReadIdx = 1: read FBO 1, write FBO 0
|
|
821
|
+
const aWriteIdx = 1 - aReadIdx;
|
|
822
|
+
|
|
823
|
+
// Write to target FBO (not the current read FBO)
|
|
824
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, buffers[aWriteIdx]);
|
|
825
|
+
gl.viewport(0, 0, width, height);
|
|
826
|
+
|
|
827
|
+
// Read previous frame Buffer A texture (from current read FBO's texture)
|
|
828
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
829
|
+
gl.bindTexture(gl.TEXTURE_2D, textures[aReadIdx]);
|
|
830
|
+
gl.uniform1i(uniformsBufferA.iChannel0, 0);
|
|
831
|
+
|
|
832
|
+
gl.uniform2f(uniformsBufferA.iResolution, width, height);
|
|
833
|
+
gl.uniform1f(uniformsBufferA.iTime, time);
|
|
834
|
+
gl.uniform1i(uniformsBufferA.iFrame, frameCount);
|
|
835
|
+
gl.uniform4f(uniformsBufferA.iMouse, mouse.x, mouse.y, mouse.z, mouse.w);
|
|
836
|
+
|
|
837
|
+
// Render particle physics
|
|
838
|
+
gl.useProgram(programBufferA);
|
|
839
|
+
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
|
840
|
+
|
|
841
|
+
// Switch read index
|
|
842
|
+
aReadIdx = aWriteIdx;
|
|
843
|
+
|
|
844
|
+
// ===== Pass 2: Buffer B (Density Field) =====
|
|
845
|
+
const bWriteIdx = 1 - bReadIdx;
|
|
846
|
+
|
|
847
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, buffers[2 + bWriteIdx]); // B_FBO0 or B_FBO1
|
|
848
|
+
gl.viewport(0, 0, width, height);
|
|
849
|
+
|
|
850
|
+
// Bind current Buffer A particle state (use latest Buffer A result)
|
|
851
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
852
|
+
gl.bindTexture(gl.TEXTURE_2D, textures[aReadIdx]); // A latest result
|
|
853
|
+
gl.uniform1i(uniformsBufferB.iChannel0, 0);
|
|
854
|
+
|
|
855
|
+
// Bind previous frame Buffer B density (for accumulation)
|
|
856
|
+
gl.activeTexture(gl.TEXTURE1);
|
|
857
|
+
gl.bindTexture(gl.TEXTURE_2D, textures[2 + bReadIdx]); // B_read
|
|
858
|
+
gl.uniform1i(uniformsBufferB.iChannel1, 1);
|
|
859
|
+
|
|
860
|
+
gl.uniform2f(uniformsBufferB.iResolution, width, height);
|
|
861
|
+
gl.uniform1f(uniformsBufferB.iTime, time);
|
|
862
|
+
gl.uniform1i(uniformsBufferB.iFrame, frameCount);
|
|
863
|
+
|
|
864
|
+
// Render density accumulation
|
|
865
|
+
gl.useProgram(programBufferB);
|
|
866
|
+
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
|
867
|
+
|
|
868
|
+
// Switch Buffer B read index
|
|
869
|
+
bReadIdx = bWriteIdx;
|
|
870
|
+
|
|
871
|
+
// ===== Pass 3: Image (Final Rendering to Screen) =====
|
|
872
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
873
|
+
gl.viewport(0, 0, width, height);
|
|
874
|
+
|
|
875
|
+
// Bind Buffer A particles (use latest Buffer A result)
|
|
876
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
877
|
+
gl.bindTexture(gl.TEXTURE_2D, textures[aReadIdx]);
|
|
878
|
+
gl.uniform1i(uniformsImage.iChannel0, 0);
|
|
879
|
+
|
|
880
|
+
// Bind Buffer B density (use latest Buffer B result)
|
|
881
|
+
gl.activeTexture(gl.TEXTURE1);
|
|
882
|
+
gl.bindTexture(gl.TEXTURE_2D, textures[2 + bReadIdx]);
|
|
883
|
+
gl.uniform1i(uniformsImage.iChannel1, 1);
|
|
884
|
+
|
|
885
|
+
gl.uniform2f(uniformsImage.iResolution, width, height);
|
|
886
|
+
gl.uniform1f(uniformsImage.iTime, time);
|
|
887
|
+
gl.uniform1i(uniformsImage.iFrame, frameCount);
|
|
888
|
+
gl.uniform4f(uniformsImage.iMouse, mouse.x, mouse.y, mouse.z, mouse.w);
|
|
889
|
+
|
|
890
|
+
// Render to screen
|
|
891
|
+
gl.useProgram(programImage);
|
|
892
|
+
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
|
893
|
+
}
|
|
894
|
+
```
|
|
895
|
+
|
|
896
|
+
**IMPORTANT: Key Points**:
|
|
897
|
+
- **Must use 2 FBOs for ping-pong**: Each Buffer needs two independent FBOs (read FBO + write FBO); a single FBO + texture swap causes "Feedback loop" error
|
|
898
|
+
- Use FBO index switching (not texture swapping): bind target FBO when writing, bind source texture when reading
|
|
899
|
+
- Image pass binds the latest Buffer results (obtained via read index)
|
|
900
|
+
|
|
901
|
+
## Performance & Composition
|
|
902
|
+
|
|
903
|
+
**Performance Optimization**:
|
|
904
|
+
- Separable blur: N² → 2N samples
|
|
905
|
+
- Bilinear tap trick: 5 samples replace 9-tap Gaussian
|
|
906
|
+
- MIP sampling replaces large kernels: `textureLod` at high MIP levels ≈ large-range average
|
|
907
|
+
- `discard` outside data regions to skip unnecessary computation
|
|
908
|
+
- RGBA channel packing: velocity(xy) + density(z) + curl(w) in one vec4
|
|
909
|
+
- Chained sub-steps: A→B→C same code for 3x simulation speed
|
|
910
|
+
- `if (dot(b,b) > bbMax) break;` adaptive early exit
|
|
911
|
+
- `iFrame < 20` progressive initialization to prevent explosion
|
|
912
|
+
|
|
913
|
+
**Typical Composition Patterns**:
|
|
914
|
+
- **Fluid + Lighting**: Fluid buffer → Image computes gradient normals → diffuse + specular
|
|
915
|
+
- **Fluid + Color Advection**: Separate Buffer tracks color field, advected by velocity field
|
|
916
|
+
- **Scene + Bloom + TAA**: 4-Buffer pipeline (render → downsample → blur → composite tone mapping)
|
|
917
|
+
- **G-Buffer + Screen-Space Effects**: 2-Buffer without temporal feedback (geometry → edge/SSAO/SSR → stylized compositing)
|
|
918
|
+
- **State Storage + Visualization Separation**: Buffer A pure logic + Image pure rendering (`texelFetch` reads state + distance field drawing)
|
|
919
|
+
|
|
920
|
+
## Further Reading
|
|
921
|
+
|
|
922
|
+
For complete step-by-step tutorials, mathematical derivations, and advanced usage, see [reference](../reference/multipass-buffer.md)
|