SuperAPI AI 工具集

shader-fills

设计与创作

查看项目

更新于 10-16 15:57

技能介绍

用途

Shader Fills 用于在设计产物中实现代码驱动的着色器填充与特效。其核心理念是:着色器是代码,而非不透明的资源。每个着色器由 GLSL 片段源码与 JSON uniforms 清单组成,直接持久化在页面 HTML 中,并由内嵌于同一 HTML 的自包含 WebGL 运行时实时渲染。因此着色器在编辑器、分享链接以及导出的独立文件中均可工作。用户可在代码面板中查看和编辑 GLSL,uniform 旋钮会自动出现在检查器中(填充 → Shader 绘制类型,以及 特效 → Shader)。

主要能力

持久化格式(v1)

每个着色器对应一个定义块,放置在 </body> 之前,使用 <script type="application/x-agent-native-shader"> 标签,携带 data-shader-id、data-shader-name、data-shader-mode 属性。源码以 /*! an-shader v1 开头,后接 JSON uniforms 清单,再跟 GLSL 代码。

元素引用支持两种方式,且可在同一元素上共存(类似 Figma):

  • 填充:data-an-shader-fill,canvas 渲染在元素内容之后,使用负 z-index 并处于隔离的层叠上下文中,位于元素自身背景之上。应保留静态回退背景色,以便在无 JS/WebGL 时仍能渲染。
  • 特效:data-an-shader-effect,透明叠加 canvas 位于内容之上,pointer-events: none。每个元素的覆盖值存放在单独属性 data-an-shader-effect-uniforms 中。

运行时必须以 <script data-agent-native-shader-runtime data-runtime-version="1"> 的形式在每份文档中嵌入一次,由 ensureShaderRuntime() / applyShaderToHtml() 负责处理。

应用着色器(推荐路径)

使用纯辅助函数加源码编辑操作。在 templates/design/ 中:

// script: apply-shader.ts — run with: pnpm exec tsx apply-shader.ts
import { applyShaderToHtml, newShaderId } from "./shared/shader-fills";
import { getGlslShaderPreset } from "./shared/shader-presets";

const preset = getGlslShaderPreset("water-caustics")!;
const result = applyShaderToHtml(currentHtml /* from read-source-file */, {
  nodeId: "hero", // the element's data-agent-native-node-id
  def: {
    id: newShaderId(),
    name: preset.label,
    mode: preset.mode, // "fill" | "effect"
    glsl: preset.glsl,
    uniforms: preset.uniforms,
  },
  fallbackColor: "#06283d", // fills only — static no-JS fallback
});
if (result.errors.length) throw new Error(result.errors.join("; "));
// result.html → write back via apply-source-edit (full-replace) with the
// versionHash you got from read-source-file.

操作流程:read-source-file → 变换 → apply-source-edit(edit: { kind: "full-replace", content }),并传入 expectedVersionHash。若只是小幅手改(例如调整清单中某个 uniform 值),也可用 edit-design 对该块原文做精确搜索替换。

移除使用 removeShaderFromNode(html, nodeId, mode?) — 清除注解并垃圾回收未被引用的定义块。

从选择器发起「Create a custom shader fill.」

填充选择器中的 Create new (AI) 磁贴会用隐藏上下文行(designId、fileId、目标 nodeId、mode)预填此提示。随后:

  1. 仅当用户完全没给描述时,才询问想要的外观。
  2. 为该请求编写原创 GLSL(不要只是重新套用预设),暴露 2–5 个精心选择的 uniform 作为旋钮。按用户描述控件的方式命名旋钮。
  3. 通过上述辅助流程应用,目标是提供的 nodeId。
  4. 汇报着色器名称、其旋钮,以及 GLSL 可在代码面板中编辑。

GLSL 规则(WebGL1 / GLSL ES 1.00)

  • 以 precision highp float; 开头,写入 gl_FragColor。
  • 使用到时声明 uniform vec2 u_resolution; 和 uniform float u_time; — 运行时自动驱动它们(u_time 以秒为单位;在 prefers-reduced-motion 下保持为 0)。切勿把内置变量放进清单。
  • 清单中的每个 uniform 都必须在 GLSL 中按映射类型声明:float → uniform float,vec2 → uniform vec2,color → uniform vec3(颜色以归一化 0–1 RGB 传入)。校验会拒绝未使用的旋钮。
  • uniform 名称匹配 u_[A-Za-z0-9_]+;不超过 16 个 uniform;float 旋钮需要 min/max/step;颜色值为 #rrggbb 十六进制。
  • 循环边界必须是编译期常量(for (int i = 0; i < 5; i++))。
  • 特效叠加在内容之上:不进行输出预乘,因此 gl_FragColor = vec4(color, alpha) 且 alpha < 1 时可干净地叠加。
  • 切勿在 GLSL、名称或标签中包含 </script、<script 或会破坏 */ 的序列 — validateShaderDef() 会强制检查;写入前请运行它(或运行会调用它的 applyShaderToHtml)。

预设库

shared/shader-presets.ts 中的 GLSL_SHADER_PRESETS 附带 12 个精选预设 — 填充类:mesh-gradient、glowing-wave、water-caustics、fractal-noise、clouds、nebula、moire、concentric-rings、pattern-grid;特效类:film-grain、halftone、scanlines。应用预设会把一份新副本(新 id)盖入设计;此后即为用户可编辑的代码。

填充与特效对比

项目 填充(data-an-shader-fill) 特效(data-an-shader-effect)
Canvas 位置 内容之后(隔离层叠上下文中的负 z-index,位于元素自身背景之上) 内容之上的叠加层,pointer-events: none
输出 不透明像素(一种材质) 透明叠加层(alpha 合成)
回退 元素保留静态背景色 退化为无叠加
覆盖属性 data-an-shader-uniforms data-an-shader-effect-uniforms

限制

失败情形(无 WebGL、编译错误、每屏挂载超过 8 个)会移除 canvas,并把原因记录在元素的 data-an-shader-error 属性上 — 当着色器「不显示」时检查该属性。