这是一款可无限穿行的 3D 图片长廊,基于 Three.js(WebGL 自定义着色器) 配合 GSAP 实现。画面是一条向前延伸的方形隧道,四个面上错落嵌着 110 个作品面板,按住鼠标拖动推进,走到尽头无缝接回起点。悬停时边框亮起,点击进入聚焦视角看大图,按 ESC 返回。地面带倒影、四周叠暗角,沉浸感比常规横向轮播强出一截。
这款 Three.js 无限画廊的四个亮点
真·无限循环:隧道路径是闭合曲线,滚动进度取模循环,没有"到底了"的断点。
图片不变形:面板尺寸随机分配,但横图竖图方图放进去都不拉伸。
13 张素材撑起 110 个展位:图片按规则复用,还穿插了 Canvas 实时生成的动态纹理。
移动端可用:统一走 pointer 事件,触屏拖动同样生效,竖屏自动放宽视场角。
3D 隧道图片展示是怎么做到不变形、不卡顿的
其一,等比裁切放在着色器里做。常规写法是拿到图片宽高后去改几何体尺寸,改一次重建一次网格。这套源码的思路是几何体固定不动,改的是纹理采样区间——图片加载完成后比对宽高比,把多出来的那一边往里收,片元着色器里只用一行就完成了裁切:
vec2 uv = 0.5 + (vUv - 0.5) * uCrop;
结果就是:你换成任意尺寸的图都不用预先裁剪,也不会变形。
其二,地面倒影几乎零成本。倒影不是再渲一遍场景,而是克隆材质、几何体沿地面镜像,关键在于贴图、裁切、悬停这几个 uniform 直接指向原对象的引用而非拷贝。共享之后面板悬停变亮、倒影自动跟着亮,源码里没有一行同步逻辑。
其三,纹理做了缓存池。110 个面板共用 13 份素材,如果各自加载就是 110 次请求。源码用 Map 以图片路径为键分配插槽,第一个面板负责加载,其余直接复用同一份 texture,还没加载完的排队等回调——图片只解码一次,显存只占一份。
怎么换成自己的作品图
结构很干净,就 index.html / style.css / script.js 三个文件加一个 img 目录。换图只需要在脚本里的媒体清单中改路径和作品名,两个字段而已,条数不限,剩下的排布、裁切、复用逻辑会自动接管。
脚本顶部有一个集中的参数对象,推进速度、网格亮度、倒影强度、鼠标带动幅度、展位总数都在那里,关键位置源码中均有注释标注,低端设备调低展位数和倒影强度即可获得更宽裕的帧率。界面文案是 HTML 里的普通元素,配色走 CSS 变量,改起来没有门槛。
运行提示:本素材通过 importmap 引入 Three.js 与 GSAP,并会加载本地图片,需以本地服务器方式打开,详细运行方法请参见压缩包内的帮助文档。
关于这款 3D 画廊特效的常见问题
图片数量有上限吗?
没有。媒体清单是一个数组,加多少条都可以。展位固定 110 个,图少了会自动循环复用,图多了则少复用几次,两种情况都不需要额外改动。
图片尺寸和比例有要求吗?
没有硬性要求,横图、竖图、方图混着放都能正常居中显示,程序会自动做等比裁切。只建议单张控制在 2000px 以内、适当压缩,否则首屏加载会偏慢。
手机上能正常浏览吗?
可以。交互统一走 pointer 事件,触屏拖动与鼠标拖动效果一致,竖屏下相机视场角会自动放宽以适应窄屏。不过 WebGL 对中低端手机有一定压力,建议适当调低展位总数。
可以把展示内容换成视频吗?
可以。素材本身已内置了基于 Canvas 的动态纹理示例,把纹理来源替换成 VideoTexture 即可接入视频,改动集中在媒体加载那一段。
适用场景
适合设计师作品集、摄影个人站、品牌形象页、数字展厅与线上艺术展这类氛围优先的页面,也可裁成活动页开场动画。需 WebGL 支持,主流浏览器近三年版本均可运行。完整源码可下载后本地调试查看。