# @basementstudio/shader-lab 中文文档

规范地址：https://npmcn.com/package/%40basementstudio/shader-lab/

版本：3\.1\.0
npm 元数据更新时间：2026-10-13T22:59:25.250Z
中文译文更新时间：2026-11-07T19:59:33.957Z
软件包许可：未声明

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40basementstudio/shader-lab
原文对照：https://npmcn.com/package/%40basementstudio/shader-lab/?lang=original
项目主页：https://eng.basement.studio/tools/shader-lab
源码仓库：https://github.com/basementstudio/shader-lab

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：1.3 MB，303 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- 运行依赖：1 个
- peer 依赖：react ^19\.0\.0，three ^0\.185\.0，react-dom ^19\.0\.0
- 首次发布：2026-03-27T20:01:05.477Z
- 最新版本发布：2026-10-13T22:59:24.923Z
- 近 30 天下载量：2828（2026-10-08 至 2026-11-06，npm 官方下载统计）
- 已发布版本数：30（近 12 个月 30 个）

## 中文简介

用于Shader Lab出口的可移植回放运行时间.

## 安装

```sh
npm install @basementstudio/shader-lab
```

也可以使用：`pnpm add @basementstudio/shader-lab`、`yarn add @basementstudio/shader-lab`、`bun add @basementstudio/shader-lab`

## README

# @basementstudio/shader-lab (英语)

[![basement.studio logo](https://img.shields.io/badge/MADE%20BY%20basement.studio-000000.svg?style=for-the-badge&labelColor=000)](https://basement.studio/) [![NPM version](https://img.shields.io/npm/v/%40basementstudio%2Fshader-lab.svg?style=for-the-badge&labelColor=000000)](https://www.npmjs.com/package/@basementstudio/shader-lab) [![Website](https://img.shields.io/badge/WEBSITE-basement.studio-a6d600.svg?style=for-the-badge&labelColor=000000)](https://basement.studio/)

`@basementstudio/shader-lab` 是一个从编辑器导出 Shader Lab 组件的可移植反应运行时间.

它支持三个主要使用案例:

-   在 React 中直接渲染成份
-   在您自己的场景中使用配体作为纹理
-   使用 Shader 实验室效果层作为您自己的场景的后处理

## 安装

```bash
npm install @basementstudio/shader-lab three
```

```bash
bun add @basementstudio/shader-lab three
```

## 同伴依赖关系

-   `react`
-   `react-dom`
-   `three`

## 所需资源

-   运行时间需要浏览器中的 WebGPU 支持
-   `ShaderLabComposition` 此套件中的钩子是客户端 API
-   媒体层期望在 `layer.asset.src`
-   组成纹理输出为画布后置,可以被 WebGL 或 WebGPU 主机场景所消耗
-   后处理必须运行在同一程序上 `WebGPURenderer` 当你经过的场景纹理

所支持的效果层包括ASCII,blob跟踪,CRT,方向模糊,分色,半通,墨子,粒子网格,图案,像素排序,后缀,切片,边缘检测,移位图,和色调偏差.

Blob跟踪层检测出下方内容的移动(或亮度)区域,并用闭路电视风格的形状,标签,连接线条和出轨来设定. 一种内在效应可以在检测到的形状内通过 `params.innerEffectType` (任何过后效应类型)和 `params.innerEffectParams` (该效应参数的JSON字符串覆盖;参见 `ShaderLabBlobInnerEffect` 类型)。 设定 `params.outputMode` 改为 `"mask"` 以释放白黑相接的填充器使用 `compositeMode: "mask"`。 。 。 .

## 隔离群体

导出配置可以包含层 `kind: "group"`, (中文(简体) ), `type: "group"`,以及 `params: {}`儿童通过 `parentId`. 平面阵列使用最先,最后深度顺序:先是组,再是其所有后人,再是下个兄弟姐妹. 失踪或无效 `parentId` 在场景根上放置一层. ID必须是独一无二的,巢穴仅限于8个组.

例如,顺序 `[title, portraitGroup, halftone, photo, background]` 与 `halftone.parentId` 财务报告和审定财务报表 `photo.parentId` 设置为 `portraitGroup.id` 将半音限制在相片上。 每个组开始透明,处理内容,然后对结果应用自己的不透明与混合模式. 隐藏一个团体隐藏整个子树而不改变孩子的能见度. 组不透明/可视性可以使用普通的地层时间轨.

组使用 `compositeMode: "filter"`, (中文(简体) ), `hue: 0`,以及 `saturation: 1`; 覆盖口罩和组色调整在此迭代中没有被曝光. 团体目标目前每组花费约32米B,为1080p. 现有的平面配置继续工作,没有任何新领域.

## 字体

ASCII 和文本层在运行时通过读取 CSS 解析字体家族 自定义属性( e)`--geist-mono`, (中文(简体) ), `--bsmnt-grotesque`, (中文(简体) ), `--adhesion`从 文档根。 每个变量的值用作 CSS `font-family` glyph 光栅化; 当变量未被设定时, 层 返回到系统字体.

包船 三个公开许可的家庭 - Geist Sans, Geist Mono,和BSMNT Grotesque——带有一个样式表,宣布 `@font-face` 规则和设置变量:

```ts
import "@basementstudio/shader-lab/fonts.css"
```

在Shader Lab编辑室(Adhesion, Blob, 包克克克克克尼切克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克克 有商业执照。 它们在主机Shader Lab应用程序中使用,但 故意不与这个包一起分发。 使用它们(或 在主机应用程序中装入字体并设置匹配的 CSS 变量 其姓氏,例如:. `:root { --adhesion: "Adhesion" }`。 。 。 .

## API 概览

### 高级API

-   `ShaderLabComposition`
-   `useShaderLab`

### 高级 API

-   `useShaderLabCanvasSource`
-   `useShaderLabPostProcessingSource`
-   `useShaderLabTextureSource`
-   `ShaderLabCanvasSource`
-   `ShaderLabPostProcessingSource`
-   `ShaderLabTextureSource`

使用 `useShaderLab` 除非您特别需要手动计时或生命周期控制.

## 1\. 组成

```tsx
"use client"

import {
  ShaderLabComposition,
  type ShaderLabConfig,
} from "@basementstudio/shader-lab"

const config: ShaderLabConfig = {
  layers: [],
  timeline: {
    duration: 6,
    loop: true,
    tracks: [],
  },
}

export default function Example() {
  return (
    <div style={{ width: "100%", maxWidth: 1200 }}>
      <ShaderLabComposition config={config} />
    </div>
  )
}
```

处理运行时间错误 :

```tsx
<ShaderLabComposition
  config={config}
  onRuntimeError={(message) => {
    if (message) {
      console.error(message)
    } else {
      console.info("Shader Lab runtime error resolved.")
    }
  }}
/>
```

`onRuntimeError` 当运行时间出错时使用字符串消息调用 (启动失败, 阴影编译错误, 缺失 WebGPU) 支持)。 报告出错后,称为一次 `null` 何时 错误被解决后, UIs 可以恢复错误 。 它从来没有叫 `null` 在报告出错之前.

## 2\. 使用构成作为纹理

`useShaderLab` 能够管理运行时间并返回即时使用 `THREE.CanvasTexture`。 。 。 .

```tsx
"use client"

import {
  useShaderLab,
  type ShaderLabConfig,
} from "@basementstudio/shader-lab"
import { OrbitControls, PerspectiveCamera } from "@react-three/drei"
import { Canvas, useFrame } from "@react-three/fiber"
import { useMemo, useRef } from "react"
import * as THREE from "three"
import { WebGPURenderer } from "three/webgpu"

function Scene({ config }: { config: ShaderLabConfig }) {
  const { texture } = useShaderLab(config, {
    width: 1024,
    height: 1024,
  })

  const material = useMemo(
    () => new THREE.MeshBasicMaterial({ color: 0xffffff }),
    []
  )
  const meshRef = useRef<THREE.Mesh | null>(null)

  useFrame((_, delta) => {
    if (meshRef.current) {
      meshRef.current.rotation.y += delta * 0.3
    }

    if (texture) {
      texture.needsUpdate = true
      material.map = texture
      material.needsUpdate = true
    }
  })

  return (
    <>
      <color attach="background" args={["#0a0a0a"]} />
      <PerspectiveCamera makeDefault fov={50} position={[0, 0, 4]} />
      <mesh ref={meshRef} material={material}>
        <sphereGeometry args={[1, 64, 64]} />
      </mesh>
      <OrbitControls enableDamping />
    </>
  )
}

export function TexturedExample({ config }: { config: ShaderLabConfig }) {
  return (
    <Canvas
      gl={async (props) => {
        const renderer = new WebGPURenderer(
          props as ConstructorParameters<typeof WebGPURenderer>[0]
        )
        await renderer.init()
        return renderer
      }}
    >
      <Scene config={config} />
    </Canvas>
  )
}
```

### 纹理说明

-   `texture` 由软件包的内部输出画布支持
-   `canvas` 也可从下列网址获得: `useShaderLab` 如果您想要在原始画布级别整合
-   运行时间在内部更新您的组成
-   此纹理路径可移植到WebGL和WebGPU主机场景中, 因为软件包输出有画布支持

## 3\. 使用Shader Lab作为后处理

后处理, `useShaderLab` 暴露一个 `postprocessing` 手柄.

你把场景变成纹理 然后把纹理交给沙德实验室.

```tsx
"use client"

import {
  useShaderLab,
  type ShaderLabConfig,
} from "@basementstudio/shader-lab"
import { Canvas, useFrame, useThree } from "@react-three/fiber"
import { PerspectiveCamera } from "@react-three/drei"
import { createPortal } from "@react-three/fiber"
import { useEffect, useMemo, useRef } from "react"
import * as THREE from "three"
import { float, texture as tslTexture, uv, vec2 } from "three/tsl"
import { MeshBasicNodeMaterial, WebGPURenderer } from "three/webgpu"

function PostProcessedScene({ config }: { config: ShaderLabConfig }) {
  const { gl, scene, size } = useThree()
  const renderer = gl as unknown as WebGPURenderer
  const cameraRef = useRef<THREE.PerspectiveCamera | null>(null)
  const sceneTargetRef = useRef<THREE.WebGLRenderTarget | null>(null)

  const { postprocessing } = useShaderLab(config, {
    renderer,
    width: size.width,
    height: size.height,
  })

  const presentScene = useMemo(() => new THREE.Scene(), [])
  const presentCamera = useMemo(
    () => new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1),
    []
  )
  const presentTextureNode = useMemo(() => {
    const sampleUv = vec2(uv().x, float(1).sub(uv().y))
    return tslTexture(new THREE.Texture(), sampleUv)
  }, [])
  const presentMaterial = useMemo(() => {
    const material = new MeshBasicNodeMaterial()
    material.colorNode = presentTextureNode.rgb
    return material
  }, [presentTextureNode])

  useEffect(() => {
    const target = new THREE.WebGLRenderTarget(size.width, size.height)
    sceneTargetRef.current = target

    return () => {
      sceneTargetRef.current = null
      target.dispose()
    }
  }, [size.height, size.width])

  useEffect(() => {
    sceneTargetRef.current?.setSize(size.width, size.height)
    postprocessing.resize(size.width, size.height)
  }, [postprocessing, size.height, size.width])

  useFrame((state, delta) => {
    const target = sceneTargetRef.current
    const camera = cameraRef.current
    if (!(target && camera && postprocessing.ready)) return

    renderer.setRenderTarget(target)
    renderer.render(scene, camera)

    const output = postprocessing.render(
      target.texture,
      state.clock.elapsedTime,
      delta
    )

    if (output) {
      presentTextureNode.value = output
    }

    renderer.setRenderTarget(null)
    renderer.render(presentScene, presentCamera)
  }, 1)

  return (
    <>
      <PerspectiveCamera ref={cameraRef} makeDefault position={[0, 2, 5]} />

      <mesh position={[-1.2, 0, 0]}>
        <boxGeometry args={[1.4, 1.4, 1.4]} />
        <meshStandardMaterial color="#e74c3c" />
      </mesh>

      <mesh position={[1.2, 0, 0]}>
        <sphereGeometry args={[0.8, 32, 32]} />
        <meshStandardMaterial color="#3498db" />
      </mesh>

      {createPortal(
        <mesh frustumCulled={false}>
          <planeGeometry args={[2, 2]} />
          <primitive attach="material" object={presentMaterial} />
        </mesh>,
        presentScene
      )}
    </>
  )
}

export function PostProcessingExample({
  config,
}: {
  config: ShaderLabConfig
}) {
  return (
    <Canvas
      gl={async (props) => {
        const renderer = new WebGPURenderer(
          props as ConstructorParameters<typeof WebGPURenderer>[0]
        )
        await renderer.init()
        return renderer
      }}
    >
      <PostProcessedScene config={config} />
    </Canvas>
  )
}
```

### 后处理说明

-   后处理仅为同级
-   从同一处传出你的场景纹理 `WebGPURenderer` 你给了 `useShaderLab`
-   WebGL 主机渲染器不支持后处理
-   只有效果的 沙德 实验室配置 最自然适合这里
-   保留后处理 `width`编号 :`height` 财务报告和审定财务报表 `postprocessing.resize(...)` 与输入同步渲染目标大小,特别是用于屏幕-空间效果,如去色、像素和ASCII
-   `postprocessing.texture` 总是指向最近的输出纹理

外部输入纹理和输出纹理使用正( 非多倍化) RGB 还有阿尔法 纹理路径通过效果传递来保持输入覆盖; 效果输出α控制效果强度. 源层使用源层 组成。 在传递前将多倍输入转换为正α. 遗留面具层仍然使用他们现有的 RGB- darken 行为,以及 画布构成背景仍然不透明.

## `useShaderLab`

```ts
const { canvas, ready, texture, postprocessing } = useShaderLab(config, options)
```

### 选项

| 选项 | 说明 |
| --- | --- |
| `width` | 内部运行时间输出宽度 |
| `height` | 内部运行时间输出高度 |
| `pixelRatio` | 可选像素比覆盖 |
| `canvas` | 可选的现有画布,使组成 |
| `renderer` | 可选共享 `WebGPURenderer` 用于后处理 |

### 返回值

| 外地 | 说明 |
| --- | --- |
| `canvas` | 内部输出画布 |
| `ready` | `true` 当管理过的纹理路径初始化时 |
| `texture` | 管理 `THREE.CanvasTexture` 由运行时显示布支持 |
| `postprocessing` | 处理同级接线员后处理 |

### `postprocessing`

| 外地 | 说明 |
| --- | --- |
| `ready` | `true` 后处理源初始化时 |
| `texture` | 最近处理的产出纹理 |
| `resize(width, height, pixelRatio?)` | 调整运行时间目标大小 |
| `render(inputTexture, time, delta)` | 向输出纹理中渲染 |

## 高级 API

这些API是当您想要更直接地控制时间,调整行为大小,或对象生命周期时提供的.

用于:

-   您已经拥有了自己的渲染回路, 想要手动驱动更新
-   您想要原始输出画布而不是管理 `CanvasTexture`
-   你想自己拥有完整的后处理管道
-   您需要使用 React 以外的运行时间( 但仍在浏览器/ 客户端运行时间)

### 钩子

-   `useShaderLabCanvasSource`
-   `useShaderLabPostProcessingSource`
-   `useShaderLabTextureSource`
-   `useShaderLabTexture`

#### `useShaderLabCanvasSource`

需要原始画布和人工计时时时使用此功能.

```tsx
const { canvas, ready, resize, update } = useShaderLabCanvasSource(config, {
  width: 1024,
  height: 1024,
})

useFrame((state, delta) => {
  if (!ready) return
  update(state.clock.elapsedTime, delta)
})
```

这在下列情况下是有用的:

-   你想创造你自己 `THREE.CanvasTexture`
-   你想把帆布喂进别的管道
-   您想要确切决定何时更新组成

#### `useShaderLabPostProcessingSource`

想要控制整个场景到文字到屏幕的流量时使用这个.

```tsx
const { ready, error, resize, texture, update } =
  useShaderLabPostProcessingSource(effectConfig, {
    renderer,
    width: size.width,
    height: size.height,
  })

useFrame((state, delta) => {
  if (!(ready && sceneTarget)) return

  renderer.setRenderTarget(sceneTarget)
  renderer.render(scene, camera)

  const output = update(
    sceneTarget.texture,
    state.clock.elapsedTime,
    delta
  )

  renderer.setRenderTarget(null)
  // present(output)
})
```

确保当场景改变目标大小时, Shader Lab 后处理源会调整大小 。 屏幕-空间效应使用这个尺寸来确定它们的采样网格.

这在下列情况下是有用的:

-   你已经有你自己的目标了
-   您要决定最终输出是如何呈现的
-   您需要低于 `useShaderLab().postprocessing`

#### `useShaderLabTextureSource`

这暴露出下层的内部纹理来源.

只有在您特别想要内部纹理路径并理解渲染器的制约时才使用. 在大多数情况下, `useShaderLab` 或者说 `useShaderLabCanvasSource` 是更好的选择.

### 类

-   `ShaderLabCanvasSource`
-   `ShaderLabPostProcessingSource`
-   `ShaderLabTextureSource`

类API是钩子的非反应等同物.

典型流量 :

```ts
const source = new ShaderLabCanvasSource(config, {
  width: 1024,
  height: 1024,
})

await source.initialize()
source.update(time, delta)
source.resize(width, height)
source.dispose()
```

当 :

-   你在外面反应
-   你想要全手工控制生命周期
-   您正在将 Shader Lab 整合到自定义运行时间或框架中

## 自定义阴影层

自定义阴影层允许您使用 GPU 阴影层写入 [Three.js TSL( 三分语言)](https://github.com/mrdoob/three.js/wiki/Three.js-Shading-Language)您的草图完全运行在 GPU 作为节点图 —— 没有 GLSL 或 WGSL 可写入 .

### 如何运作

您的代码必须导出一个被包裹的函数 `Fn()` 返回 TSL 节点( vec3 或 vec4) 。 编辑器会编译您的 TypeScript, 条形导入, 并评价结果为带有前置范围的沙盒. 一切从 `three/tsl` 而Shader Lab 通用图书馆作为全球图书馆可供使用——不需要进口.

```ts
export const sketch = Fn(() => {
  const color = vec3(uv().x, uv().y, sin(time).mul(0.5).add(0.5))
  return color
})
```

点击 **应用** (或作再作活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活活 导出项名默认为 `sketch` 但可以在条目导出字段中更改.

### 源模式 vs 效果模式

自定义阴影层有一个 **效果模式** 切换 :

-   **源模式** (默认)——地层从头产生像素,像梯度或图像. 您的草图输出每个像素的颜色 。 输出为线性( sRGB → 线性通过) `pow(2.2)`)与堆肥管道相匹配.
    
-   **效果模式** ——地层发挥后处理作用. 它通过它接收下方所有层的复合结果 `inputTexture` 并改变它。 由于输入已经处于线性空间,因此没有应用γ转换.
    

### 注射范围

这些变量被注入到您的草图中,并作为全局数据提供:

| 变量 | 类型 | 说明 |
| --- | --- | --- |
| `time` | `float` | 以秒计耗时, 不断更新 |
| `inputTexture` | `TextureNode` | 下面的复合层(效果模式). 在源模式下, 这是空白的纹理 。 直接用于默认- UV 颜色, 或调用 `.sample(customUV)` 以自定义坐标重采样 |

### TSL 全球

全部从 `three/tsl` 已提供。 关键:

| 函数 | 说明 |
| --- | --- |
| `Fn(() => { ... })` | 定义延后的阴影函数( 需要的包装) |
| `float`, (中文(简体) ), `vec2`, (中文(简体) ), `vec3`, (中文(简体) ), `vec4` | 平面和向量类型的构造器 |
| `uv()` | 碎片紫外线坐标 (0-1) |
| `screenSize` | 将传送分辨率视为 vec2 |
| `sin`, (中文(简体) ), `cos`, (中文(简体) ), `abs`, (中文(简体) ), `floor`, (中文(简体) ), `round`, (中文(简体) ), `pow`, (中文(简体) ), `mix`, (中文(简体) ), `clamp`, (中文(简体) ), `smoothstep`, (中文(简体) ), `dot`, (中文(简体) ), `min`, (中文(简体) ), `max` | 标准数学 |
| `texture(tex, uv)` | 给定紫外线上的纹理样本 |
| `uniform(value)` | 创建统一节点 |
| `select(cond, a, b)` | 初选 |
| `If(cond, () => { ... }).Else(...)` | 有条件分支 `.toVar()` 任务 |

节点用方法链: `a.add(b)`, (中文(简体) ), `a.mul(b)`, (中文(简体) ), `a.sub(b)`, (中文(简体) ), `a.div(b)`, (中文(简体) ), `a.negate()`, (中文(简体) ), `a.toVar()` (使可变), `a.assign(b)` (将 a 移动到 Var 节点).

### 沙德实验室设施

这些是与 TSL 一起注入的额外助手 :

#### 噪声

| 函数 | 签署 | 说明 |
| --- | --- | --- |
| `simplexNoise3d` | `(vec3) → float` | 3D 简单音响 |
| `simplexNoise4d` | `(vec4) → float` | 4D 简单音响( 使用) `.w` (时间) |
| `perlinNoise3d` | `(vec3) → float` | 3D 佩林噪声 |
| `valueNoise3d` | `(vec3) → float` | 三维值噪声 |
| `voronoiNoise3d` | `(vec3) → vec2` | 3D 沃罗诺伊`.x` =细胞分解, `.y` =边角) |
| `fbm` | `(vec3) → float` | 分形布朗运动(2-octave simplex) |
| `curlNoise3d` | `(vec3) → vec3` | 3D 卷曲噪声 |
| `curlNoise4d` | `(vec4) → vec3` | 4D 卷曲噪声 |
| `ridgeNoise` | `(vec3) → float` | 山脊噪声 |
| `turbulence` | `(vec3) → float` | 骚动的噪音 |

#### 记事

| 函数 | 签署 | 说明 |
| --- | --- | --- |
| `reinhardTonemap` | `(vec3) → vec3` | 莱因哈德语调图 |
| `acesTonemap` | `(vec3) → vec3` | ACES 电影音调图 |
| `technicolorTonemap` | `(vec3) → vec3` | 温暖的科技色彩外观 |
| `cinematicTonemap` | `(vec3) → vec3` | 有线的电影S曲线 |
| `bleachBypassTonemap` | `(vec3) → vec3` | 脱饱和高孔 |
| `crossProcessTonemap` | `(vec3) → vec3` | 跨进程颜色变化 |
| `totosTonemap` | `(vec3) → vec3` | Basement 的自定义胶片色调图 |

#### SDF 原始人

| 函数 | 签署 | 说明 |
| --- | --- | --- |
| `sdBox2d` | `(vec2, float) → float` | 2D 框签名距离 |
| `sdSphere` | `(vec3, float) → float` | 3D 球体签名距离 |
| `sdDiamond` | `(vec2, float) → float` | 2D 钻石签名距离 |
| `sdRhombus` | `(vec2, vec2) → float` | 2D Rhombus 签名距离 |

#### 数学空间( S)

| 函数 | 签署 | 说明 |
| --- | --- | --- |
| `screenAspectUV` | `(screenSize, range?) → vec2` | 以原产地为中心、被视线校正的紫外线 |
| `rotate` | `(vec2, float) → vec2` | 2D 按角度旋转(弧度) |
| `smin` | `(float, float, float) → float` | 最小平滑 |
| `smax` | `(float, float, float) → float` | 最大滑动度 |
| `atan2` | `(float, float) → float` | 两相弧度 |
| `tanh` | `(float) → float` | 双曲正切 |
| `sinh` | `(float) → float` | 双曲正弦 |
| `cosh` | `(float) → float` | 双曲余弦 |
| `cosinePalette` | `(t, a, b, c, d, e?) → vec3` | 基于余弦的调色板生成器 |

#### 复杂的数学

所有复杂业务的使用 `vec2` 地点 `.x` 真实的, `.y` = 虚构:

`complexMul`, (中文(简体) ), `complexDiv`, (中文(简体) ), `complexPow`, (中文(简体) ), `complexSqrt`, (中文(简体) ), `complexSin`, (中文(简体) ), `complexCos`, (中文(简体) ), `complexTan`, (中文(简体) ), `complexLog`, (中文(简体) ), `complexConj`, (中文(简体) ), `complexToPolar`, (中文(简体) ), `complexMobius`

#### 模式

| 函数 | 签署 | 说明 |
| --- | --- | --- |
| `bloom` | `(float) → float` | 软发光曲线 |
| `bloomEdgePattern` | `(float, float, float) → float` | 边缘意识开花 |
| `canvasWeavePattern` | `(vec2, float) → float` | 织布纹理 |
| `grainTexturePattern` | `(vec2) → float` | 胶片粒纹理 |
| `repeatingPattern` | `(vec2, float) → vec2` | 倾斜紫外线帮助器 |

### 实例

出处模式 — 有色调的动画梯度 :

```ts
export const sketch = Fn(() => {
  const uv0 = screenAspectUV(screenSize)
  const color = vec3(
    uv0.x.add(0.5),
    uv0.y.add(0.5),
    sin(time).mul(0.5).add(0.5)
  ).toVar()
  color.assign(technicolorTonemap(color))
  return color
})
```

效果模式——自定义紫外线的样本输入有扭曲:

```ts
export const sketch = Fn(() => {
  const warp = sin(uv().y.mul(20).add(time.mul(2))).mul(0.02)
  const warped = vec2(uv().x.add(warp), uv().y)
  return inputTexture.sample(warped)
})
```

效果模式——简单的色彩操作 :

```ts
export const sketch = Fn(() => {
  const color = inputTexture.toVar()
  const luma = dot(color.rgb, vec3(0.299, 0.587, 0.114))
  return vec4(vec3(luma), color.a)
})
```

## 包含运行时间支持

包含模式支持中的图像和视频层 `params.transparentBounds: true` 以揭示其空地边界下的内容。 关闭设置或使用 `false` 以保留黑色边界。 此选项不影响封面模式或制作 组成背景透明.

-   渐变
-   文本
-   自定义阴影( 来源和效果模式)
-   图像和视频来源
-   实时相机输入
-   ASC 二届理事会
-   图案
-   墨迹
-   半圆
-   抖动
-   CRT 网络
-   粒子网格
-   像素排序

## 工具出口

-   `createRuntimeClock`
-   `advanceRuntimeClock`
-   `buildRuntimeFrame`
-   `evaluateTimelineForLayers`
-   `resolveEvaluatedLayers`
-   运行时间配置和时间轴类型

## 页:1

-   `ShaderLabComposition` 仅在 `config.composition` ,否则将填充由您布局定义的大小
-   `useShaderLab` 是大多数应用程序集成推荐的切入点
-   如果您只需要在 DOM 中直接渲染成分, 请使用 `ShaderLabComposition`
-   如果需要全手工控制,请使用下级源 API
-   纹理输出是可移植的,因为它由管理的画布支撑
-   后处理目前需要共享 `THREE.WebGPURenderer`
-   如果您使用三发式反射 `three@0.183.x`你可能会看到 `THREE.Clock` 从 `@react-three/fiber`; 警告是上游的, 不是由此套件发出的

## 链接

-   网站: [地下室. studio (英语)](https://basement.studio/)
-   无 : [@basementstudio/shader-lab (英语)](https://www.npmjs.com/package/@basementstudio/shader-lab)

## 常见问题

### @basementstudio/shader-lab 是什么？

用于Shader Lab出口的可移植回放运行时间\.

### 如何安装 @basementstudio/shader-lab？

在项目目录运行 npm install @basementstudio/shader-lab，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：react（^19\.0\.0）、three（^0\.185\.0）、react-dom（^19\.0\.0）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @basementstudio/shader-lab 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @basementstudio/shader-lab 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @basementstudio/shader-lab 可以商用吗？

@basementstudio/shader-lab 使用 未声明 许可。package\.json 没有声明许可证。没有许可证的代码默认保留全部权利，商用前请联系作者或查看仓库中的 LICENSE 文件。以上为概括，不构成法律意见，请以许可原文为准。

### @basementstudio/shader-lab 的下载量有多少？

根据 npm 官方下载统计，@basementstudio/shader-lab 在 2026/10/08 – 2026/11/06 这 30 天内被下载 2,828 次，日均约 94 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @basementstudio/shader-lab 还在维护吗？

最新版本 3\.1\.0 发布于 2026/10/14（24 天前）；至今共发布 30 个版本，其中过去 12 个月发布了 30 个；首次发布于 2026/03/28。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

