关于 3d-cloth-material
这是面向 Three.js 创作者的 3D 织物材质技能,提供亚麻、丝绸和羊毛的编织、褶皱、缝边与透光规则。重点是以切线角度构造不拉伸的褶皱,并用线程级细节呈现织物质感。
主要功能
- 01构造不拉伸的褶皱曲面
- 02生成平纹、斜纹和缎纹编织
- 03设置丝绸、亚麻和羊毛参数
- 04添加缝线、折边与毛边
- 05呈现褶皱遮蔽和背光透射
适用场景
- 01制作挂布或窗帘材质
- 02为织物宏观特写添加织纹
- 03调试布料褶皱和边缘表现
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mengto/ skills --skill 3d-cloth-material安装后在 Claude Code 中输入/3d-cloth-material确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
demo.htmlPROMPT.mdagents/openai.yaml详细介绍
3D 布料材质
原理: 将布料悬挂成一排排布面,以切线角度作为褶皱信号,使弧长等于静止坐标 s,从而让织物永不拉伸。然后通过线级织法、光泽、折边厚度和缝隙透光,呈现出「布料」的质感。
最接近的相关项目:3d-high-resolution-textures 为任何材质选择纹素密度、mipmap 和交付方式;用它来制定预算,而本项目专注于布料的不同之处(经纬交织、褶皱、光泽、折边)。3d-wood-material、3d-paper-material 和 3d-metal-material 分别涵盖各自的表面;本技能只负责机织和缝制布料。它不是布料模拟:对于角色飘动的披风或会发生碰撞的旗帜,应先进行模拟(Verlet 或 Blender 布料)并烘焙,再采用下述材质规则。
提取自 KIBORI 木彫,这是一个深色 WebGL 工作室,卷起的靛蓝帆布(dōgu-maki)置于暖色主光下,必须经得起微距特写。移植自该项目的内容:织物烘焙、缝线着色器、半圆折边内折、线顶磨损、光泽常量。为本技能新构建的内容(Kibori 只有一种靛蓝帆布,而不是三种布料):切线角度褶皱曲线、缎纹和斜纹交织、丝绸/羊毛/亚麻参数表、杆上的挂环、毛边散丝、褶皱 AO、逆光透射、风。demo.html 是参考示例。
演示:Three.js r169 · WebGL · GLSL(MeshPhysicalMaterial + onBeforeCompile)、原生 JavaScript、无后期处理链。
规则及其防止的问题
- 从角度而非高度生成褶皱。
α(s) = a·(sinθ + 0.16 sin(2θ+0.8)) + …,然后x += ds·cos α,z += ds·sin α。失败情况:高度场z = A·sin(kx)的弧长为 1 + slope²,因此织物会随风游移,每道褶皱都会拉伸 30–80%。使用角度形式时,以米为单位的uv = (s, v)是精确的。保持|α| < 1.45rad;超过此值会钳制成平坦台阶,褶皱会变成带黑色接缝的管状结构。 - Uv 是材质米数,每帧都不能重新拟合。 不要根据移动的表面重新计算 uv。失败情况:织物会随风闪烁、爬动。设置
texture.repeat = 1/(threads × pitch),使一个纹素平铺包含NT根线。亚麻的线距为 1.6 mm,丝绸为 0.7 mm,羊毛为 2.6 mm。 - 烘焙交织结构,而不是噪声。 每根线都有自己的宽度(0.80–0.97)、色调和竹节(通过高斯函数加粗,最多可达 0.34)。经线高度在网格边界处通过
0.5·smoothstep(0.05, 0.5, |t|)混合上下层。平纹 =(A+B)&1,2/1 斜纹 =(A+B)%3 < 2,5 枚缎纹 =(2A+B)%5 != 0表示经线在上。NT必须是重复次数(32、24、40)的倍数,否则平铺会出现接缝。失败情况:平铺噪声法线贴图看起来像灰泥或皮革。 - 纺纱要加捻度。 在每根线的高度上添加
0.22·twist·sin(2π(5·along + 1.3·across))(亚麻和羊毛的捻度为 0.10–0.14,丝绸为 0)。失败情况:亚麻看起来像金属网。 - 两种染料,每根线有自己的色调。 颜色为
mix(warpDye, weftDye, weftOnTop·shot);丝绸的 shot 为 1.0(茜草红经线、金色纬线),其他材质为 0。色调为mix(0.86, 1.14, threadTone),凹处为mix(0.5, 1, smoothstep(0.05, 0.85, height)),色斑 + 经向条纹为1 + var·((blot−0.5)·0.62 + (streak−0.5)·0.22)。失败情况:在织物贴图上使用单一纯色漫反射,看起来像印花。 - 光泽就是织物本身,而且必须微妙。
sheen 0.5–1.0,sheenRoughness 0.28 (silk) – 0.82 (wool),以及sheenColor = dye lightened × 0.62。失败情况:接近白色的sheenColor在暖色主光下会形成过亮的乳白色边缘。运行时绝不要将sheen设为恰好 0(设为 0.0001);跨过零点会重新编译程序,并造成 200+ ms 的卡顿。 - 丝绸使用各向异性,羊毛添加绒毛。 丝绸:
anisotropy 0.85, roughness 0.36;亚麻:0.90粗糙度,sheen 为 0.55;羊毛:0.96粗糙度,sheen 为 1.0。创建时保持anisotropy大于 0(0.0001),避免 define 状态切换。 - 褶皱遮蔽不可或缺。 投射并接收主光的阴影贴图(
normalBias 0.012、bias −0.0004、DoubleSide阴影),并根据褶皱深度添加顶点 AO,在间接光上使用0.62 + 0.38·smoothstep(−0.075, 0.035, zFold)。失败情况:缺少其中任一项都会让谷底像褶皱顶部一样明亮,使褶皱看起来像画上去的。 - 边缘需要厚度。 将每条自由边沿半圆向内翻折,
P = edge + out·r·sinφ − N·r(1−cosφ),φ ∈ [0, 0.94π],r= 丝绸 1.1 mm、亚麻 2.2 mm、羊毛 4.6 mm。将底边沿背面向上翻至2r + 0.2 mm处,并翻转法线。失败情况:零厚度的剪切边是近景中最容易暴露 CG 布料的破绽。 - 在着色器中按布料米数缝制针脚。 针线在针孔之间拱起(跨越 74% 的线距,弧度为
4·x(1−x)),针槽和褶皱通过有限差分影响法线,并用fwidth淡化。卷边上方 3 cm、两侧向内 2.2 cm,接缝宽±7 mm,凸起的缝脊每隔 4 个线距就收皱一次。失败情况:几何针脚会产生 z-fighting 和锯齿;纹理绘制的针脚则不会随褶皱变化。 - 毛边:抽出纬线。 超出切口的部分丢弃片元,仅保留经线(
|fract(u/pitch)−0.5| < 0.36),每根经线的长度随机,为F·(0.3+0.7·hash)。失败情况:alpha 边缘纹理没有线的结构。 - 薄布可以透光。
emissive += trans · lightColour · dye·(1.7,1.2,0.85) · pow(max(0, −N·L), 1.15) · gap · thin,其中gap = mix(1, 0.42, height),让线遮挡光线,空隙透过光线。丝绸 1.05,亚麻 0.6,羊毛 0.06。失败情况:缺少此效果时,窗帘后方即使有亮着的窗户也不会透光。 - 在布料被触碰的位置做旧。
wear = clamp(aWear·(0.25+height) + (fbm−0.5)·0.3, 0, 1)→ 按wear·threadTop将染料混合为较浅的颜色。卷边处 +0.4,褶皱顶部 +0.3。失败情况:均匀的染色看起来像全新布料。
常量
| 亚麻 | 丝绸 | 羊毛 | |
|---|---|---|---|
| 织法 / NT / 间距 | 平纹 / 32 / 1.6 mm | 五枚缎纹 / 40 / 0.7 mm | 斜纹 / 24 / 2.6 mm |
| 法线强度 S · 法线缩放 | 2.6 · 1.15 | 1.5 · 0.6 | 2.9 · 1.45 |
| 粗糙度 · 光泽度 · 光泽半径 | 0.90 · 0.55 · 0.55 | 0.36 · 0.5 · 0.28 | 0.96 · 1.0 · 0.82 |
| 褶皱 λ · amax · 风力增益 | 0.34 m · 0.98 · 1.0 | 0.40 · 1.02 · 1.9 | 0.32 · 0.86 · 0.55 |
| 边缘 | 毛边,3 cm | 3.5 cm 折边 | 5 cm 折边 |
布料尺寸为 2.0 × 1.95 m,网格为 160 × 120(约 21k 个顶点、45k 个三角形)。主聚光灯为 0xffd0a0 × 3.0,角度为 0.44,衰减为 0;冷色补光为 1.0;窗口背光为 0.2–1.8;环境光强度为 0.42;ACES,曝光为 1.0。
易错点,先说症状
- 织纹移动时爬动或闪烁 → uv 是根据弧长重建或滚动的;应将其保持为静止状态下的米制坐标。
- 广角视图中出现水平摩尔纹条带 → 凹凸/折痕项使用了高频噪声的
dFdx;将折痕八度数控制在 17 次/米以下,并缩放至 0.016。mip 贴图和 16× 各向异性过滤可处理织纹本身。 - 褶皱像平板,带有黑色裂缝 →
|α|被限制了。降低amax,使a·env·1.28 < 1.45,不要再增加暗部。 - 背光时所有东西都泛橙光 → 透射颜色同时乘上了暖色灯光和暖色染料。使用
(1.7,1.2,0.85)着色,而不是(2.1,1.35,0.72)。 - envMapIntensity 没有作用 → 在 r163+ 中,它仅在
material.envMap存在时生效;使用scene.environment时应设置scene.environmentIntensity。 - 两个网格共用的
onBeforeCompile着色器却使用了不同 uniforms → 设置customProgramCacheKey,并将 uniforms 放在材质上,而不是网格上。 - 折边条带的绕序错误(受光面朝内) → 首次更新后,根据每个条带首个三角形法线与属性法线的方向符号,确定一次条带的索引顺序。
- 翻折处留下暗色缝隙 → 回折条带必须放在
2r + 0.2 mm处,而不是r处。 - 双面布片出现阴影痤疮 → 使用
normalBias,不要增大bias;过大的偏移会使褶皱阴影脱离表面。
生命周期
prefers-reduced-motion:在 t = 7.3(阵风膨胀至中段)渲染一帧设计好的静态画面,停止循环,保留所有可用控件,并在发生变化时重新渲染。页面隐藏时暂停(document.hidden);恢复时重置 last。将 dt 限制为 1/30 s,将 DPR 上限设为 2,并在 60 帧平均耗时超过 26 ms 时每次降低 0.25。使用 ResizeObserver 确定尺寸。布料循环中不进行逐帧内存分配:重复使用类型化数组,只更新 position/normal。
开销(使用 headless Chrome for Testing,在 Apple GPU 上以 1440×900、DPR 2 测得)
- 布料 CPU 开销(褶皱 + 法线 + 折边 + 布耳 + 流苏):160×120 时为 3.7–4.9 ms。将行数减半(190 → 120)后,开销降低了 40%,且没有丢失任何褶皱,因为褶皱沿垂落方向变化缓慢。
- 整帧耗时:广角视图为 10–11 ms,微距视图为 15 ms。微距视图多出的 4 ms 来自覆盖整个屏幕的片元着色器(织纹 + 缝线 + fbm),而非几何体。
- 启动:包括三张 512² 织纹烘焙在内,首帧耗时 0.8 s。切换织物耗时 25 ms。切换图层耗时 14 ms。
- 非瓶颈项:三角形数量、2048 阴影贴图、布耳、流苏(520 根)。
按评分标准打分(0 = 单色平面,5 = 近距离看起来可信,10 = 微距照片级)
织纹结构 7 · 光泽与染色 6.5 · 褶皱形状与垂坠感 6(悬挂的窗帘,不是会自我接触的自由布料)· 边缘、缝线、接缝 7.5 · 光线透射 6 · 磨损 5.5 · 动态效果 5.5(风力为解析计算,无碰撞)· 性能 8。总分 6.5。提升方向:实现真实的自碰撞褶皱(模拟并烘焙),为羊毛添加纤维光晕几何体,为折痕添加第二种法线缩放。