告别‘纸片感’!用C++手撸一个带虚焦模糊的光线追踪相机(附完整代码)
告别‘纸片感’用C手撸一个带虚焦模糊的光线追踪相机附完整代码你是否曾经觉得自己的光线追踪渲染图缺少一丝真实感那些完美聚焦的物体虽然清晰却总给人一种纸片般的扁平感。今天我们将一起探索如何通过实现虚焦模糊Defocus Blur来为你的渲染图注入电影级的景深效果。这不仅能让你的作品更加接近真实摄影效果还能显著提升场景的立体感和艺术表现力。1. 虚焦模糊背后的光学原理在真实世界中没有任何相机能够同时让所有距离的物体都保持完美聚焦。这种选择性聚焦的效果正是我们所说的景深而在光线追踪领域我们更倾向于使用虚焦模糊这个术语来描述这种现象。薄透镜模型是我们实现虚焦模糊的基础。想象一下光线从场景中的一点发出通过透镜的不同位置汇聚到传感器上的一个点这个过程中有三个关键参数影响着最终的模糊效果光圈大小控制透镜的有效开口直径焦距从透镜到完美聚焦平面的距离聚焦距离相机到需要清晰呈现的物体的距离提示在真实相机中改变聚焦距离通常需要物理移动镜头位置而在我们的虚拟相机中这一切都可以通过数学计算来实现。2. 相机类的关键扩展为了实现虚焦模糊效果我们需要对传统的针孔相机模型进行扩展。以下是改造后的camera类核心新增成员class camera { public: // ...原有成员... double defocus_angle 0; // 虚化圆锥的角度 double focus_dist 10; // 完美聚焦平面的距离 private: // ...其他私有成员... vec3 defocus_disk_u; // 虚化圆盘的水平半径向量 vec3 defocus_disk_v; // 虚化圆盘的垂直半径向量 point3 defocus_disk_sample() const { auto p random_in_unit_disk(); return center (p[0] * defocus_disk_u) (p[1] * defocus_disk_v); } };初始化过程中需要计算的关键步骤根据defocus_angle和focus_dist计算虚化圆盘半径确定圆盘在相机坐标系中的方向向量为后续随机采样做好准备void camera::initialize() { // ...其他初始化代码... // 计算虚化圆盘的基础向量 auto defocus_radius focus_dist * tan(degrees_to_radians(defocus_angle / 2)); defocus_disk_u u * defocus_radius; defocus_disk_v v * defocus_radius; }3. 光线生成算法的改造传统的光线追踪相机所有光线都从单一的相机中心点发出。要实现虚焦模糊我们需要让光线从虚化圆盘上的随机点发出。改造后的get_ray函数ray camera::get_ray(int i, int j) const { auto pixel_center pixel00_loc (i * pixel_delta_u) (j * pixel_delta_v); auto pixel_sample pixel_center pixel_sample_square(); auto ray_origin (defocus_angle 0) ? center : defocus_disk_sample(); auto ray_direction pixel_sample - ray_origin; return ray(ray_origin, ray_direction); }这个改造引入了几个重要概念虚化圆盘采样当defocus_angle大于0时光线从圆盘上的随机点发出聚焦逻辑所有光线都指向焦平面上的同一点确保聚焦区域清晰模糊程度控制defocus_angle越大圆盘半径越大模糊效果越明显4. 随机采样与单位圆盘生成为了实现从虚化圆盘的均匀采样我们需要一个能在单位圆盘内生成随机点的函数。这与常见的单位球体采样不同需要特别注意。高效的单位圆盘采样实现vec3 random_in_unit_disk() { while (true) { auto p vec3(random_double(-1,1), random_double(-1,1), 0); if (p.length_squared() 1) return p; } }这个函数采用拒绝采样法在[-1,1]范围内随机生成x和y坐标检查点是否落在单位圆内如果不在圆内则重新生成注意虽然看起来有无限循环的风险但实际上数学上保证了一定会在有限次尝试后返回有效点。5. 参数调优与效果对比正确设置相机参数对获得理想的虚焦模糊效果至关重要。下面是一个参数配置示例及其对应的视觉效果参数值视觉效果描述defocus_angle0无模糊所有物体都清晰defocus_angle5.0轻微模糊背景略有虚化defocus_angle10.0明显模糊电影级景深效果focus_dist3.4聚焦在近处物体focus_dist10.0聚焦在远处物体典型场景配置camera cam; cam.aspect_ratio 16.0 / 9.0; cam.image_width 400; cam.samples_per_pixel 100; cam.max_depth 50; cam.vfov 20; cam.lookfrom point3(-2,2,1); cam.lookat point3(0,0,-1); cam.vup vec3(0,1,0); cam.defocus_angle 10.0; // 明显的虚焦效果 cam.focus_dist 3.4; // 聚焦在距离相机3.4单位的位置6. 性能考量与优化技巧虚焦模糊虽然能显著提升视觉效果但也会增加渲染时间。以下是几个优化建议采样数平衡增加defocus_angle时需要相应增加samples_per_pixel过大模糊角度会导致噪点增加聚焦距离选择聚焦在场景中的主要兴趣点上次要元素可以适当模糊以减少计算量渐进式渲染先使用低采样数预览效果确定参数后再进行高质量渲染// 快速预览配置 camera preview_cam; preview_cam.samples_per_pixel 10; preview_cam.max_depth 5; preview_cam.defocus_angle 10.0; // 最终渲染配置 camera final_cam; final_cam.samples_per_pixel 100; final_cam.max_depth 50; final_cam.defocus_angle 10.0;7. 艺术化应用与创意效果虚焦模糊不仅是物理准确的模拟更是强大的艺术表达工具。你可以尝试选择性聚焦引导观众视线到场景关键元素极浅景深创造微缩模型般的特殊效果动态模糊结合相机移动模拟运动模糊创意参数组合// 极浅景深效果 cam.defocus_angle 15.0; cam.focus_dist 1.5; // 全景清晰效果 cam.defocus_angle 0.5; cam.focus_dist 20.0;在实际项目中我发现defocus_angle在5-15度之间最能平衡真实感和艺术效果。过大的角度虽然戏剧性强但会失去太多细节而过小的角度又难以产生明显的景深效果。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2438476.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!