国风 Three.js 渲染
定位说明:通用 Three.js 教程已经很多(英文社区有大量高质量资源)。 这个技能只做一件他们不做的事——中式美学的实时渲染。
什么时候用
中国风官网 / 文旅 H5 / 品牌活动页 / 水墨风交互 / 国风游戏原型 / 非真实感渲染(NPR)。
不适用:通用 3D 建模、物理仿真、写实渲染——那些去看 Three.js 官方文档更好。
先问清楚
- 载体(PC 官网 / 手机 H5 / 微信内嵌)—— 决定性能预算
- 要哪种中式质感(水墨 / 青绿山水 / 敦煌壁画 / 剪纸皮影)
- 有没有模型(有 glTF?还是用几何体?)
- 动效需求(自动旋转 / 跟随鼠标 / 滚动驱动)
⚠️ 移动端警告:Three.js + 自定义 shader 在中低端安卓上会明显发热掉帧。 H5 项目务必先确认目标机型,必要时降级为静态图。
水墨渲染的三个核心
水墨效果不是加个滤镜,是三件事的组合:
1️⃣ 墨分五色 —— 色阶量化
真实光照是连续的,水墨是分层的。把明暗量化成 5 阶:
float lam = max(dot(N, normalize(uLight)), 0.0);
float steps = 5.0;
float q = floor(clamp(lam, 0.0, 1.0) * steps) / (steps - 1.0);
vec3 col = mix(uInk, uPaper, q); // 浓墨 → 纸白
阶数太多(>8)失去水墨感,太少(<3)像色块。5 阶是甜点。
2️⃣ 边缘积墨 —— rim 压深
毛笔在轮廓处停留更久,墨更浓。用视线与法线夹角模拟:
float rim = 1.0 - max(dot(N, normalize(vV)), 0.0);
float edge = smoothstep(0.45, 0.95, rim);
col = mix(col, uInk, edge * 0.85);
3️⃣ 笔触扰动 —— 噪声打破机械感
纯数学量化的边界太整齐,不像手绘。在量化前扰动光照值:
float n = noise(vP * 5.5 + uTime * 0.06);
lam += (n - 0.5) * 0.16; // 扰动幅度别超过 0.2
再叠一层细噪声当宣纸颗粒:
col *= 0.97 + 0.03 * noise(vP * 40.0);
配色方案
复用中国传统色,三套起步:
| 风格 | 纸色 | 浓墨 | 中间调 |
|------|------|------|--------|
| 水墨 | #F7F5F0 | #2E2A26 | #5A5550 |
| 青绿 | #F2F5F2 | #14322B | #2F6B5E |
| 朱砂 | #FBF7F4 | #3A1512 | #B23A2E |
关键:背景色要和纸色一致,否则物体像贴在画上而不是画在纸上。
完整可运行示例
demo.html 是一个完整的单文件实现(Three.js r170 + importmap,无需构建):
- 实时水墨 shader(上面三个技法全在里面)
- 三套配色可切换
- 实测:2 draw call / 14496 三角面 / WebGL 无错误
在线预览:https://sanhuang520-ship-it.github.io/awesome-chinese-ai-tools/themes/ink3d.html
只做方案审查时
用户明确说“不修改、不运行,只做技术方案或检查现成 Demo”时,先给结论,限制读取范围:
- 先用本文件已有的三项技法、性能要点和 Demo 路径回答。
- 如需核对实现,只搜索
demo.html中与问题直接相关的行;不要整文件输出,也不要读取intro-demo.html,除非用户问开场动画。 - 最多核对 3 类证据:Three.js 版本、shader 关键字、性能保护。每类只摘必要行号与结论。
- 不启动浏览器、不运行 Demo,就明确写“静态源码审查,未做运行时验证”。
静态审查应控制在:技术结论 → 移动端风险 → Demo 路径 → 未验证项,不要因为仓库里已有源码就展开成逐行代码审计。
其他中式风格的思路
| 风格 | 关键技法 | |------|---------| | 青绿山水 | 色阶量化 + 石青石绿双色映射 + 金色描边(edge 用暖金而非墨黑) | | 敦煌壁画 | 基础色阶 + 强噪声做斑驳 + 土红/石青三色限定 | | 剪纸皮影 | 完全平面化(关掉光照)+ 纯剪影 + 背光透射(rim 用暖光而非压深) | | 工笔 | 提高色阶数(8-10)+ 细线描边(Sobel 后处理)+ 高饱和矿物色 |
性能要点
- shader 里的 noise 很贵。手机端把
noise(vP * 40.0)的纸纹改成贴图采样。 - draw call 越少越好。同材质的物体用
InstancedMesh。 - 像素比要限制:
renderer.setPixelRatio(Math.min(devicePixelRatio, 2)),否则高分屏直接卡死。 - 不用后处理就别引 EffectComposer,能在材质里做的就在材质里做。
- 移动端建议 60fps 掉到 30fps 就该降级——加个 FPS 监测自动降质量。
边界
- 不做通用 Three.js 教学。基础用法请看 官方文档,这里只讲中式渲染。
- 不保证跨设备一致。GLSL 在不同 GPU/驱动上有精度差异,重要项目要真机测。
- 不模仿具体画家风格。可以做"水墨感",不做"齐白石风格"——风格模仿有争议。
- 不确定的图形学细节要说明。涉及特定 GPU 兼容性、WebGPU 迁移等,建议查最新文档。
相关
guochao-visual-cn—— 国潮视觉(AI 出图用)chinese-web-themes—— 中式网页主题(2D 排版用)- 三者关系:出图 → 排版 → 3D 呈现