关于 3d-paper-material
用于在 3D 场景中制作纸张材质的图形技能,通过纤维高度、撕裂轮廓、厚度层和背光透射呈现纸面。示例提供多种纸张类型、细节放大与材质生成流程。
主要功能
- 01烘焙纤维与纸面形成纹理
- 02绘制带毛边纤维的撕裂遮罩
- 03通过偏移层表现纸张厚度
- 04依据纸张结构计算背光透射
- 05支持纸张类型切换和细节放大
适用场景
- 01在 3D 场景中呈现和纸或棉纸
- 02制作带撕裂纤维边缘的纸张模型
- 03表现纸张透光及墨迹渗入
- 04在近景查看纸面纤维细节
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mengto/ skills --skill 3d-paper-material安装后在 Claude Code 中输入/3d-paper-material确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
demo.htmlPROMPT.mdagents/openai.yaml详细介绍
3D 纸张材质
纸张是一片由撕裂轮廓裁出的纤维场:由铺展纤维的高度图和匀度云纹构成表面,由带有扯出纤维的 Alpha 遮罩构成边缘,由偏移副本构成厚度,而背光则根据每个像素处纸张的薄度透射。缺少其中任何一项,纸张就只是一张白色平面。
纸张燃烧或被火焰揭示时,请使用 paper-cinder-transition;此技能呈现的是未燃烧的纸张。它是在场景中悬挂或平放的纸张。翻页书籍需要弯曲绑定,而此技能不提供该功能。
阅读 demo.html,了解可运行的构建示例:使用 onBeforeCompile 修补的 MeshPhysicalMaterial、一次性烘焙到半浮点目标的贴图,以及用 Canvas 2D 绘制的遮罩。其中的 NOISE GLSL、匀度、楮皮纤维和树皮斑点表达式、背光透射、tearLine 以及毛边循环,均原样移植自 Kibori 工坊页面(kibori.html、washiMat、footTear)。
流程
- 烘焙纤维(GPU,一次)。 一次全屏绘制会将
R height, G formation, B fibre, A fleck写入半浮点目标。高度为0.5 + fibre*0.34 + (tooth-0.5)*0.1 - fleck*0.2 - crease*0.55。目标的samples: 0,并启用 mipmap。 - 扭曲网格。 将纤维坐标域扭曲 0.014 个单位,并将其旋转
(gnoise(q*2.1)-0.5)*1.5弧度。再添加一组频率为 2.7 倍、更细更淡的纤维(最大值为 0.55)。 - 绘制遮罩(Canvas 2D,更换纸张时)。
R表示撕口内侧的细条,G表示轮廓加毛边纤维,B表示带低 Alpha 渗色晕圈的墨迹,A表示由绘制在侧边的阴影模糊而成的轮廓(边缘老化程度)。使用getImageData读回数据并写入DataTexture,翻转行,Alpha 作为数据使用。 - 塑造纸张。 使用 168 x 240 平面:悬挂弧度、山形折痕、针孔凹痕,以及保持长度不变的圆柱卷曲(半径 0.23,角度
2.6*curl)。沿法线偏移thick/3、2thick/3、thick,添加三个副本。 - 着色。 根据匀度和纤维生成反照率,在其上叠加墨迹,并根据老化遮罩添加烘黄和褐斑。高度通过以世界单位计量的凹凸效果处理(参见注意事项)。Alpha 表示覆盖率,而非裁切。
- 透射。
emissive += L * tr,其中tr = 0.74 + (0.5-form)*0.85 + (0.5-lowfbm)*0.45 - fibre*0.22 - fleck*0.45,再乘以纸张增益,加上薄条,并减去墨迹。L是纸张后方的花园:天空、阳光斑,以及通过 1.4 的 mip 偏置采样的黑色竹茎。 - 宏观细节。 在焦点处的 0.5 单位窗口中重新烘焙第二张高度图和遮罩,并根据窗口边缘将其混合到基础图上。切勿平铺小纹理。
最终采用的常量
| 和纸 | 棉质布浆纸 | 牛皮纸 | |
|---|---|---|---|
| 色调 | #f0e8d2 | #f0eee6 | #a88f70 |
| 纤维网格 A / B(每单位) | 1.9x54 / 44x2.3 | 15x17 / 16x14 | 7x26 / 26x7 |
| 纤维起伏、凹凸高度(单位) | 0.55, 0.0017 | 0.32, 0.0024 | 0.8, 0.0034 |
| 纸面纹理频率、振幅 | 230, 0.09 | 430, 0.17 | 300, 0.20 |
| 帘纹线条 /unit、振幅、链式系数 | 110, 0.28, 0 | 150, 0.55, 0.5 | 无 |
| 撕裂振幅(T,R,B,L)、毛边缩放 | 64,72,60,76; x12 | 3,58,3,54; x6 | 96,3,4,3; x8 |
| 厚度(单位)、透射率 | 0.0045, 1.0 | 0.0085, 0.42 | 0.011, 0.16 |
| 粗糙度、光泽 | 0.93, 0.4 | 0.9, 0.25 | 0.96, 0.10 |
缩放:1 单位 = 134.8 mm(A4 为 1.55 x 2.2)。基础烘焙为 990 px/unit = 7.3 px/mm;宏观窗口为 1536 px,覆盖 0.5 unit = 22.8 px/mm。撕裂采样为每单位 3400 次。相机视场角为 28 度;宏观距离为 0.46-0.50。
规则及其防止的问题
- 轮廓应由四条彼此独立的撕裂线构成,切勿做成带波纹的矩形。 单条正弦或噪声边缘看起来像 CSS 波浪;
tearLine会沿直线延伸、转向,再继续延伸。切边的振幅设为 3-4,撕裂边设为 60-100。 - 让纤维伸出边缘,并以部分覆盖率绘制。 硬质 alpha 边缘看起来像剪刀剪出来的。纤维宽度为 0.3-0.7 px,alpha 为 30-75%;在深色墙面上,它们会显出浅色细丝。
- 在前层后方叠放三个错位副本,色调为纸张的 0.8-0.94。 单个四边形没有厚度,从侧面看不出任何东西。错位量保持在 0.0045-0.011 单位;再大就像纸板了。
- 扭曲并旋转纤维晶格。 两组正交的脊状纹理会看起来像磨花的玻璃或交叉网格,掠射光下尤其明显。
- 用与反照率相同的场来驱动透射。 固定的自发光常量看起来像卡片里装了灯;薄的纸层结构应透光,而纤维束和墨迹应遮挡光线。
- 让烘烤色带在边缘之外渐淡至零。 fray 部分被烘成棕黑色,会在深色墙面上显得格外突兀。
- 让墨迹在低于墨迹阈值处晕染出光晕,并让纤维和纸层结构带动墨迹扩散。 仅有模糊光晕看起来像失焦的墨迹;
smoothstep(0.62,0.85, halo + fibre*0.4 + (0.5-form)*0.5)会沿着纤维丝渗开。用smoothstep(0.03,0.16, halo)限制这一项,否则远离墨迹的纤维会变黑。 - 让树皮斑点呈圆形。 Kibori 的单元哈希在宏观视图下会产生方块;乘以椭圆函数
smoothstep(0.5,0.12,length((fract(q*cell)-0.5)*vec2(1,1.9)))。 - 为宏观视图烘焙一个窗口。 7 px/mm 的基础贴图在 22 px/mm 时会变成雾状;平铺的 512 px 纸张贴图会显出接缝。
常见问题,按症状排列
- 边缘纤维消失,或边缘外出现一圈纯黑色毛边。
alphaTest会裁掉所有低于 0.5 的值。使用alphaToCoverage: true、将alphaTest设为 0,并开启抗锯齿;四个 MSAA 采样会抖动处理部分 alpha。为阴影深度材质单独设置alphaMap和alphaTest: 0.5。 - 纸张旁边出现大片黑色毛状形状并非错误。 那是纸张在墙上的阴影。用补光或微弱的自发光照亮墙面,让阴影呈现棕色。
- 浮雕在远处看起来更强,到了宏观视图却消失。 three 的
perturbNormalArb会对表面导数进行归一化,因此斜率取决于像素大小。将bumpmap_pars_fragment替换为未归一化的 Mikkelsen 形式,并以世界单位提供高度。 - 边缘老化或墨迹纹理经过预乘后变暗。 切勿通过带 alpha 的画布纹理上传数据。通过
getImageData合并四个画布到DataTexture(行反转,flipY为 false)。 - Safari 中缺少模糊的边缘色带。
ctx.filter不可靠;将形状偏移 20000 px 绘制,并设置shadowOffsetX = -20000,这样只有其模糊效果会落在目标位置。 - 半浮点目标解析成块状图块。 不要在其上启用 MSAA;使用
samples: 0。 - 卷起的角看不见。 正面视角下,65 度的卷起会产生严重缩短;让相机在距离 6 处摆动 0.3 单位,或将主光以约 54 度角掠射。
- 纤维旋涡在概览视图中看起来像大理石纹。 旋转场过强;1.5 rad 是上限,1.9 会看起来像花纹。
播放与生命周期
演示会以缓慢的相机摆动保持空闲;prefers-reduced-motion 会渲染一张合成静帧,并且只在控件输入时重新渲染。页面隐藏时暂停,恢复时重置时间基准,将 dt 限制为不超过 1/30 s,将设备像素比上限设为 2,根据 ResizeObserver 调整尺寸,并使用 1 - exp(-dt*k) 平滑调整背光和宏观视图。控件使用真实的单选按钮、复选框和范围滑块,带有焦点环和实时状态行。
成本(在 Metal 上使用无头 Chrome、1440x900 测量,DPR 1)
空闲时约 85 fps;325k 个三角形,分布在 7 次绘制调用中(正面加三层,共 4x81k);切换纸张会重建,耗时约 320 ms(4 个画布生成遮罩、烘焙、几何体);宏观视图耗时约 150 ms。GPU 内存约 100 MB(基础目标 40、宏观目标 25、遮罩 33)。开销来源:4 个遮罩画布和数万个毛边笔画。非开销来源:烘焙通道和法线采样。低成本的优化手段:基础密度(PPU_B);660 px/unit 可将内存减半,同时保持概览清晰。
来源
内容取自 Kibori 木彫启动页,那里和纸用于背光障子窗格、撕裂的页脚纸张和纸灯笼;此版本在一张纸上重新呈现了这些生成器,并加入宏观模式。
根据锚定评分标准的自评分(0 = 平面,5 = 可平铺的噪声纹理,8 = 具有真实边缘的定向纤维,10 = 在宏观测试中可与照片媲美)
| 项目 | 分数 | 原因 |
|---|---|---|
| 纤维结构 | 8 | 弯曲、旋转的纤维,两个尺度;深度方向没有纤维交叉 |
| 毛边 | 8 | 四种独立的撕裂、毛边纤维、羽化条带;纤维不会投下阴影 |
| 厚度 | 6 | 三层阶梯结构;极斜角下可见阶梯,没有截面纤维 |
| 半透明性 | 8 | 由纤维构造驱动,有茎脉和琥珀色阳光斑;厚度方向没有散射模糊 |
| 卷曲和折痕 | 6 | 卷曲效果可信,折痕在概览视图中不明显 |
| 墨迹 | 6 | 纤维吸墨范围较窄;笔画末端没有积墨 |
| 老化边缘和阴影 | 6 | 焦黄和斑点效果不错;墙上的阴影形状生硬 |
| 纹素密度 | 8 | 宏观视图中为 22.8 px/mm,概览视图中为 7.3 px/mm |