ray-tracing-renderer 相机进阶:LensCamera 光圈景深让渲染画面更有电影感
【免费下载链接】ray-tracing-renderer[UNMAINTAINED] Real-time path tracing on the web with three.js项目地址: https://gitcode.com/gh_mirrors/ra/ray-tracing-renderer
ray-tracing-renderer 是一个基于 three.js 的 WebGL2 实时路径追踪渲染器,其内置的 LensCamera 相机支持光圈景深效果:只需调整 aperture 参数,就能让渲染画面获得虚实分明的电影感。这篇相机进阶指南将带你理解 LensCamera 的工作原理,并快速掌握光圈景深的开启方法与参数调优技巧。
为什么路径追踪相机需要 LensCamera
传统 three.js 的 PerspectiveCamera 是一个理想化的针孔相机模型:所有光线都从同一点出发,画面处处清晰锐利。而真实相机的镜头有光圈,光通过有限直径的孔径进入,因此只有位于对焦平面上的物体才是清晰的,前后的物体会形成弥散圆,这就是景深。
ray-tracing-renderer 的路径追踪器天生适合模拟真实光学:它可以为每一像素采样穿过镜头不同位置的光线,天然地计算出散景(Bokeh)效果。为此项目专门实现了 LensCamera.js 类,它继承自 three.js 的 PerspectiveCamera,仅增加了一个aperture(光圈)属性,默认值为 0.01:
export class LensCamera extends PerspectiveCamera { constructor(...args) { super(...args); this.aperture = 0.01; } }LensCamera 光圈景深的快速开启方法
在示例 renderer-test/main.js 和 sample-models/main.js 中,都能看到 LensCamera 的标准用法,开启景深只需三步:
第一步:用 LensCamera 替换默认相机。将new THREE.PerspectiveCamera()换成new THREE.LensCamera(),配合 OrbitControls 使用体验最佳:
const camera = new THREE.LensCamera(); camera.fov = 35; camera.aperture = 0.01;第二步:设置对焦距离 focus。focus属性决定焦点落在哪里,通常让它跟随控制器的观察目标,示例中正是这样做的:camera.focus = controls.target.distanceTo(camera.position);即相机到观察目标的距离,保证主体始终清晰。
第三步:调节光圈 aperture 控制景深强度。aperture值越大,光圈开得越大,景深越浅、散景越明显;值越小画面越接近全清晰。示例中camera.aperture = 0.01 * distance还会根据模型大小自动缩放光圈,保证不同场景下景深观感一致。
薄透镜模型:光圈景深的物理原理
LensCamera 的景深实现遵循 PBRT 中的薄透镜模型(Thin Lens Model),核心代码位于 rayTrace.frag 的主着色器中:
// Thin lens model with depth-of-field vec2 lensPoint = camera.aperture * sampleCircle(randomSampleVec2()); vec3 focusPoint = -direction * camera.focus / direction.z; vec3 origin = vec3(lensPoint, 0.0); direction = normalize(focusPoint - origin);这段逻辑用三行代码诠释了景深的本质:
- 首先在镜头圆盘上随机采样一个点
lensPoint(半径由aperture决定); - 然后计算该像素方向与对焦平面(距离为
focus)的交点focusPoint; - 最后让光线从镜头采样点出发、射向对焦点,路径追踪器会为每条光线随机扰动起点。
由于每条光线的起点都略有不同,处于对焦平面上的物体成像位置一致而清晰,偏离对焦平面的物体则会形成逐渐扩散的弥散圆。配合路径追踪的渐进式采样,散景会随着渲染帧数增加而自然收敛,产生柔和真实的电影感虚化。
与之配套的focus与aperture字段定义在 rayTraceCore.glsl 的 Camera 结构体中,路径追踪主循环则在 rayTrace.frag 中完成光线求交与反弹计算。
光圈参数调优技巧:从 0.01 到电影感
想要调出理想的电影感景深,可以遵循以下调参思路:
小光圈(0.001 ~ 0.005):画面几乎全清晰,适合产品展示与建筑可视化,强调场景完整性。渲染器测试场景 renderer-test/main.js 中 fov 较大、光圈取 0.01,配合多材质球体用来展示材质细节。
中等光圈(0.01 ~ 0.05):主体清晰、背景轻微虚化,这是最常用的"叙事"档位,适合人像、产品特写,让观众的视线聚焦在核心物体上。示例 sample-models/main.js 默认即为此档。
大光圈(0.05 以上):浅景深、强散景,光斑明显,电影感最足,适合氛围营造。但注意路径追踪需要更多采样才能让虚化区域收敛干净,静止相机渲染数秒后效果最佳。
黄金配比:focus始终对准主体 +aperture根据场景尺度缩放(如0.01 * distance),这是项目示例给出的最稳妥方案,无论加载多大的模型都能得到和谐的景深效果。
景深 × 环境光照:电影感渲染组合技
LensCamera 的景深效果与 ray-tracing-renderer 的环境光照是绝配:环境光负责让画面充满真实的全局光照、柔和阴影与金属反射,光圈景深则负责强化空间层次与叙事焦点。两者叠加后,即使是最普通的场景也能呈现出电影级的视觉质感。你可以参考 sample-models/main.js 中的完整场景搭建流程,先用内置 HDR 环境贴图布光(详见 环境光照指南),再叠加 LensCamera 景深,轻松产出氛围感拉满的渲染作品。
常见问题解答
Q:为什么我设置了 aperture 但画面没有虚化?请确认相机使用的是THREE.LensCamera而非普通 PerspectiveCamera,并且正确设置了camera.focus对焦距离;若 focus 恰好等于所有物体的距离,画面自然全清晰。
Q:景深渲染噪点很多怎么办?路径追踪是渐进式渲染,浅景深需要更多采样才能收敛。请保持相机静止,等待渲染器积累足够帧数后画面会逐渐清晰(项目已内置渐进累积机制)。
Q:aperture 和真实相机的 f 值是一回事吗?不完全是。这里aperture是镜头圆盘采样的物理半径,是相对值而非 F 数,需要根据场景尺度试调,示例中的0.01 * distance缩放策略就是很好的起点。
结语
LensCamera 用极简的aperture+focus两个参数,为 ray-tracing-renderer 的路径追踪渲染带来了真实的物理景深:虚化自然、散景柔和,配合环境光照轻松获得电影感画面。从new THREE.LensCamera()开始,调整光圈、对准焦点,你的 three.js 渲染作品将立刻拉开与普通 WebGL 的差距。想亲手体验?克隆仓库git clone https://gitcode.com/gh_mirrors/ra/ray-tracing-renderer,打开 scenes/renderer-test/ 示例页面,感受光圈景深带来的电影质感吧。
【免费下载链接】ray-tracing-renderer[UNMAINTAINED] Real-time path tracing on the web with three.js项目地址: https://gitcode.com/gh_mirrors/ra/ray-tracing-renderer
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考