返回

柳渡

在浏览器里实时渲染的江南水乡:白墙黛瓦、马头墙、石拱桥、乌篷船、垂柳和碧水,一整天的光景约七分钟转一轮。可以在六个视角间切换、上岸漫步,或者坐上乌篷船顺着河道穿过桥洞;整座小镇由 Blender 脚本程序化生成。

作者: Theodore
在线体验
柳渡在线体验

描述

《柳渡》是一座在浏览器里实时渲染的江南水乡:白墙黛瓦、马头墙,挂着灯笼的屋檐下是木格门面,一座石拱桥跨过河道,乌篷船泊在河埠头,垂柳垂在碧水上。加载画面上写着一句:「Follow the water. Come home a little late.」——顺着水走,晚一点回家。

小镇有自己的一天:暮色、蓝调、月夜、黎明、早晨、午后,约七分钟转完一轮,太阳和月亮一直在动,影子跟着慢慢转过去。按住 T 让时间快进;数字键 1–5 直接切到午后、暮色、蓝调、月夜、烟雨五种光景。烟雨是天气而不是时段,选了它时钟就停下,直到再选别的时段。

六个视角用 ←/→ 切换:柳岸(Willow Bank)、月桥(Moon Bridge)、河埠头(Ferry Steps)、茶亭(Tea Pavilion)、雾中小镇(Town in the Mist)和慢船(The Slow Boat)。每个视角配一句英文短句,有的随时段而变,比如柳岸在暮色里是「The sun rests in the arch.」(太阳歇在桥洞里);月桥那句化用了卞之琳《断章》的「你站在桥上看风景,看风景人在楼上看你」。

拖动鼠标环顾,滚轮向前滑行,WASD 漫步(Shift 加速,Q/E 升降),点击画面对焦。界面上的光圈按钮在 f/1.4 到 f/16 之间切换,最后一档关掉景深、全部清晰;镜头默认带一点手持般的轻微晃动(Drift),可以关掉;按 H 隐藏界面。点「Ride the boat」坐上乌篷船,镜头滑到船头,船顺着河道慢慢漂:←/→(A/D)转向,↑(W)划快,↓(S)放慢,松手后它会自己回到航线。河道两边能偏多远是沿航线实测出来的,船不会撞上驳岸、泊着的船和桥洞。

整座小镇都是代码做的:民居、石拱桥、乌篷船、灯笼、垂柳、桃树、驳岸条石和台阶,全部由 Blender Python 脚本生成并导出为 GLB。民居生成器会自动划地块、选户型、按房子高低安排马头墙,在房子之间插进带院墙的小园子;只有河埠头那栋主角房子是手工指定的。天空和一部分墙面、石面、木板、卵石用的是 Poly Haven 的 CC0 照片天空和扫描贴图,其余贴图和全部声音也由脚本生成。

界面只有英文,声音在第一次点击画面后响起。推荐用桌面版 Chrome、Edge 或 Safari 打开,不支持 WebGPU 时自动改用 WebGL2;第一次打开要下载四十多 MB 的资源,会在加载页停留一会儿。

在浏览器里怎么跑起来

网页端基于 three.js r186 的 WebGPU 渲染器,用 Vite 构建,模型用 meshopt 压缩。Blender 导出的模型进网页后按材质名用 TSL 重建材质:水线污渍、青苔、焦散、风化、风吹的摆动、窗户和灯笼的夜光都在着色器里算;TSL 写的材质同样能在 WebGL2 下运行。

花功夫最多的是水面:倒影、折射、浑浊和吸收、太阳与月亮在水上的碎光和月光路、雨点涟漪、风吹出的水斑,还有船的尾迹和船头推开的水。天空是 Poly Haven 的照片天空,时段之间交叉淡入,同时给出环境光和太阳、月亮的方位;云影从小镇、远山和水面上飘过,河面上浮着低低的雾带,还有萤火虫、光尘和雨丝。

后期处理有 SSAO(只作用于环境光)、雾带、辉光、景深、调色和 FXAA。自动对焦像单反一样,从画面中心打一条射线测距(用 three-mesh-bvh 加速),也可以点击指定对焦点。为了跑得动,场景分了图层:盖瓦、花格、铜件这些细节只在主视图里画,离相机 28 米外整块隐藏;河床和卵石不进倒影;石作和树不进 SSAO 的预渲染。主光的阴影只在光源移动时重画,平时每 5 帧更新一次;乌篷船加载时按材质合并部件,草丛和驳岸石作用实例化绘制。

声音全部用 Web Audio 在浏览器里实时合成,没有一个音频文件:拍岸的水声和滴水声(离水越近越响)、柳间的风、白天的鸟叫、夜里的虫鸣和蛙声、远处寺院的钟声、乘船时的摇橹声,还有稀疏的五声音阶拨弦作配乐。