Initial commit

This commit is contained in:
Z User
2026-06-06 05:21:10 +00:00
Unverified
commit 6664758a6d
493 changed files with 135653 additions and 0 deletions

View File

@@ -0,0 +1,190 @@
# shaders.com 提取工作流
shaders.com 是一个 shader 设计工具,使用 Nuxt.js + Three.js r183 TSL + Supabase。
## 识别特征
- URL: `shaders.com/collection/{slug}/{presetId}``shaders.com/preset/{id}`
- Canvas: `data-renderer="shaders"` + `data-engine="three.js r183"`
- Nuxt.js (`_nuxt/` 路径)
- Clerk 认证
- Supabase 存储 (`data.shaders.com/storage/v1/`)
## 关键架构差异
与 Unicorn Studio 完全不同:
- **不使用 GLSL** — 使用 Three.js TSL (Three Shader Language) 节点系统
- **87 种组件类型** — 每种有自己的 TSL `fragmentNode` 函数
- **定义数据是 XOR + base64 编码的**
- **组件可嵌套** — 树形结构Glass 的 children 是其内部效果)
## 数据获取
### API 端点
```bash
# 集合变体(含编码定义)— 公开,无需认证
curl -s "https://shaders.com/api/collections/{slug}/{variantId}"
# 预览 API含编码定义 + 水印注入)
curl -s "https://shaders.com/api/preview/preset/{presetId}"
# Nuxt payload只含元数据不含 shader 定义)
curl -s "https://shaders.com/collection/{slug}/{id}/_payload.json"
```
### 定义解码
定义使用 XOR + base64 编码,有两套密钥:
1. **网站 API**`/api/collections/`
- 混淆密钥: `a5e7244ad0973f07e10285bfa75ddbe4`(来自 Nuxt runtime config
- 组件/属性名用短代码(`C52`=Plasma, `p06`=angle, 等)
- 解码: `JSON.parse(XOR(base64decode(encoded), keyBytes))`
- 然后需要 code→name 映射表还原可读名称
2. **预览 API**`/api/preview/`
- 密钥: `shaders-preview-key`
- 使用人类可读属性名(无需映射)
- 注意:会注入水印 `ImageTexture` 组件
### 代码映射表
87 种组件按字母排序编号 `C00-C86`233 种属性按字母排序编号 `p00-p232`
映射表可从 JS bundle 中提取。
## 已知陷阱
### Y 轴翻转(反复出现!)
**SDF 纹理和 UV 坐标系统性 Y 翻转** — 已在多次提取中确认:
shaders.com 的 SDF 二进制(`.bin`)使用**图像坐标系**Y=0 在顶部),
而 WebGL 纹理坐标 Y=0 在底部。直接加载会导致形状上下翻转。
```glsl
// 错误:直接用 shapeUV 采样
float sdf = texture(tSDF, shapeUV).r;
// 正确:翻转 Y
vec2 sdfUV = vec2(shapeUV.x, 1.0 - shapeUV.y);
float sdf = texture(tSDF, sdfUV).r;
// 注意:梯度的 Y 分量也需要取反
float dSdy = -(texture(tSDF, sdfUV - vec2(0, eps)).r - sdf) / eps;
```
同样,组件定义中的 `center.y` 使用 DOM 坐标Y=0 在顶部),
在 Glass shader 中需要翻转:`center.y = 1.0 - center.y`
### SDF 二进制格式
- 格式512×512 Float32 单通道1,048,576 bytes = 512² × 4
- 值域:有符号距离,负值=内部,正值=外部(如 [-0.065, 0.486]
- **不需要重映射**(不要做 `*2-1`),直接使用原始值
- 需要 `OES_texture_float_linear` 扩展做线性过滤
- WebGL2 加载:`gl.texImage2D(gl.TEXTURE_2D, 0, gl.R32F, 512, 512, 0, gl.RED, gl.FLOAT, data)`
## 组件类型速查
| 类别 | 组件 | 复杂度 |
|------|------|--------|
| 纹理 | Plasma, Godrays, SimplexNoise, LinearGradient, RadialGradient | 中 |
| 形状 | Glass, Blob, Circle, Ring, Star, RoundedRect, Polygon | 高Glass 最复杂) |
| 畸变 | WaveDistortion, ChromaticAberration, Liquify, Twirl, Bulge | 低-中 |
| 风格化 | FilmGrain, Halftone, Ascii, Dither, Glow, Bloom | 低-中 |
| 后处理 | Blur, ProgressiveBlur, BrightnessContrast, HueShift | 低 |
## 渲染管线
```
Three.js r183 TSL 渲染器
├─ 优先尝试 WebGPU降级到 WebGL
├─ 正交相机 + 单个全屏四边形
├─ 组件树从底到顶合成
├─ 有 children 的组件用 RTT (render-to-texture) 捕获子内容
├─ blend mode 用自定义混合函数
└─ Glass 组件最复杂SDF 评估 → 梯度法线 → 折射 → 色差 → 模糊 → 着色 → 高光 → 菲涅尔 → 合成
```
## 移植策略
1. **TSL 不能直接复制** — 需要翻译为 GLSL
2. **从 JS bundle 提取 TSL `fragmentNode`** → 反混淆 → 翻译为 GLSL
3. **组件树 → multi-pass FBO 管线**
4. **SDF 纹理需要 Y-flip**(见上方陷阱)
5. **Glass 组件参数多**20+),需要精确匹配每个值
## 颜色空间处理(关键)
shaders.com 的 Three.js 渲染器全程在 **linear 空间** 工作:
- 组件定义中的 hex 颜色(如 `#2c2c42`)是 **sRGB**
- TSL 的 `color()` 函数自动将 sRGB→linear
- 所有中间 FBO 均存储 linear 值
- 最终由渲染器做 linear→sRGB 输出编码
移植时:
```glsl
// 1. 颜色定义时sRGB hex → linear
vec3 colorA = pow(vec3(0.173, 0.173, 0.259), vec3(2.2)); // #2c2c42
// 2. 中间 pass全部在 linear 空间计算,不做 gamma
// 3. 最终输出 pass仅一次linear → sRGB
fragColor = vec4(pow(color.rgb, vec3(1.0/2.2)), color.a);
```
**常见错误**:在中间 pass 做 gamma 校正,导致后续 pass 在错误空间累加高光/菲涅尔。
## 参数精确对齐原则
**绝对禁止手动调参**。所有参数必须严格匹配 TSL 翻译中的公式和乘数:
```
TSL 原始乘数 → GLSL 必须使用的值
aberration * 0.06 → 不能改为 0.12
fresnelSoftness * 0.06 → 不能改为 0.12
fresnel (0.17) → 不能改为 0.4
SDF gradient eps = 0.01 → 不能改为 0.005
```
如果视觉效果不匹配,应检查:
1. 颜色空间是否正确sRGB/linear 混乱是最常见原因)
2. 噪声函数实现差异Perlin 实现 vs `mx_noise_float`
3. 时间基准是否正确
4. FBO 管线顺序是否与组件树匹配
**不要**通过修改乘数来"补偿"视觉差异 — 这会在其他参数配置下崩溃。
## TSL 时间约定
`timerLocal(speed)` = 每秒递增 `speed` 单位。移植时:`uTime = seconds * speed`
然后 shader 内部再乘自己的系数:
| 组件 | speed 参数 | shader 内部乘数 | 实际速率/秒 |
|------|-----------|----------------|------------|
| Plasma | 2 | × 0.125 | 0.25 |
| Godrays | 0.7 | × 0.2 | 0.14 |
| WaveDistortion | 0.8 | × 0.5 | 0.4 |
| FilmGrain | — | 无时间(静态) | 0 |
## TSL→GLSL 标识符映射SPCVwBqR.js
常用映射(随构建版本变化,需动态提取):
| 本地名 | TSL 函数 | GLSL |
|--------|---------|------|
| C / z | vec4() | vec4 |
| x / D | vec2() | vec2 |
| q / N | vec3() | vec3 |
| P / J | resolution | u_resolution |
| A / $ | uv | vUv |
| se / Oe | sin() | sin() |
| W / I | cos() | cos() |
| ne | mix() | mix() |
| D | smoothstep() | smoothstep() |
| fe | clamp() | clamp() |
| ar | mx_noise_float() | perlinNoise3D() |
| dr / Gt | timerLocal() | u_time × speed |
| Me / wt | rtt() | FBO pass |
| Ce | renderOutput() | fragColor |