问题二十八:ray tracing中的散焦模糊(defocus blur)
来源:互联网 发布:华为云数据 编辑:程序博客网 时间:2024/05/15 02:06
“散焦模糊”在摄影上又称“景深”。
在现实的相机中,我们需要做“散焦模糊”的原因是:我们需要一个更大的孔来收集光线增加图片的亮度(而不是“针孔”)。我们称“更大的孔”为“光圈”。
For a real camera, if you need more light,you make the aperture bigger, and will get more defocus blur.
For our virtual camera, we can have aperfect sensor and never need more light, so we only have an aperture when wewant defocus blur.
光圈的增大,导致图片出现散焦而模糊。
但是我们可以调节成像的位置,改变图片的清晰度,使图片在当前光圈条件下尽可能清晰。
所以,接下来,我们会引入两个参数:aperture(光圈)和focus_dist(成像位置)。
关于成像位置,
在原点的标准正交基e1 = (1, 0, 0), e2 = (0, 1, 0), e3 = (0, 0, 1)的坐标系,成像位置之前被设置在- e3平面(即z=-1的平面);
在任意点的标准正交基u,v,w的坐标系,成像位置之前被设置在-w平面。
引入参数focus_dist之后,成像位置将会是-focus_dist* e3 或者-focus_dist*w平面。图片的高宽都需要乘以参数focus_dist.
关于光圈,
看code的改变吧:
----------------------------------------------camera.h------------------------------------------
camera.h
#ifndef CAMERA_H#define CAMERA_H#include "ray.h"vec3 random_in_unit_disk();class camera{ public: camera(vec3 lookfrom, vec3 lookat, vec3 vup, float vfov, float aspect, float aperture, float focus_dist) { // vfov is top to bottom in degrees lens_radius = aperture / 2; float theta = vfov*M_PI/180; float half_height = tan(theta/2); float half_width = aspect * half_height; origin = lookfrom; w = unit_vector(lookfrom - lookat); u = unit_vector(cross(vup, w)); v = cross(w, u); lower_left_corner = origin - half_width*focus_dist*u - half_height*focus_dist*v -focus_dist*w; horizontal = 2*half_width*focus_dist*u; vertical = 2*half_height*focus_dist*v; } ray get_ray(float s, float t) { vec3 rd = lens_radius*random_in_unit_disk(); vec3 offset = u * rd.x() + v * rd.y(); return ray(origin + offset, lower_left_corner + s*horizontal + t*vertical - origin - offset); } vec3 origin; vec3 lower_left_corner; vec3 horizontal; vec3 vertical; vec3 u, v, w; float lens_radius;};#endif // CAMERA_H
----------------------------------------------camera.cpp------------------------------------------
camera.cpp
#include "camera.h"vec3 random_in_unit_disk() {/*在z=0平面上产生一个“起点在原点,长度小于1,方向随机”的向量。为什么是z=0平面,这个和相机的倾斜方向有关。(相机的倾斜方向为view up (简称vup,一般设置为(0,1,0)))*/ vec3 p; do { p = 2.0*vec3((rand()%(100)/(float)(100)), (rand()%(100)/(float)(100)), 0) - vec3(1,1,0); } while (dot(p,p) >= 1.0); return p;}
贴一张书上产生的图片。
----------------------------------------------main.cpp------------------------------------------
main.cpp
hitable *list[5]; list[0] = new sphere(vec3(0,0,-1), 0.5, new lambertian(vec3(0.1, 0.2, 0.5))); list[1] = new sphere(vec3(0,-100.5,-1), 100, new lambertian(vec3(0.8, 0.8, 0.0))); list[2] = new sphere(vec3(1,0,-1), 0.5, new metal(vec3(0.8, 0.6, 0.2), 0.0)); list[3] = new sphere(vec3(-1,0,-1), 0.5, new dielectric(1.5)); list[4] = new sphere(vec3(-1,0,-1), -0.45, new dielectric(1.5)); hitable *world = new hitable_list(list,5); vec3 lookfrom(3,3,2); vec3 lookat(0,0,-1); float dist_to_focus = (lookfrom - lookat).length(); float aperture = 2.0; camera cam(lookfrom, lookat, vec3(0,1,0), 20, float(nx)/float(ny), aperture, dist_to_focus);
结果图片如下:
- 问题二十八:ray tracing中的散焦模糊(defocus blur)
- 《Ray Tracing in One Weekend》——Chapter 11: Defocus Blur
- 问题十八:怎么对ray tracing图形进行消锯齿
- 问题二十四:怎么模拟ray tracing图形中介质材料的颜色(dielectric)
- 问题二十:C++全局debug “ray tracing图形”实例
- 问题二十九:测试ray tracing中camera几个主要参数
- 问题三十六:ray tracing中的Inverse Mapping(0)——概要
- 问题三十六:ray tracing中的Inverse Mapping(1)——球面Inverse Mapping
- 问题三十六:ray tracing中的Inverse Mapping(3)——圆盘Inverse Mapping
- 问题三十六:ray tracing中的Inverse Mapping(4)——圆柱面Inverse Mapping
- 问题三十六:ray tracing中的Inverse Mapping(5)——圆锥面Inverse Mapping
- 问题三十六:ray tracing中的Inverse Mapping(6)——汇总
- 射线追踪(ray tracing)
- 问题二十一:怎么模拟ray tracing图形中不同材料的颜色(diffuse and metal)
- 问题三十六:ray tracing中的Inverse Mapping(2)——凸四边形(含三角形)Inverse Maping
- Ray Tracing
- Ray Tracing
- 问题十三:怎么用ray tracing画个球
- STM32F103学习记录-----构建库函数雏形
- 数据结构之队列基础练习
- 洛谷 P1056 排座椅
- 程序员面试金典: 9.14 Java 14.2在Java中,若在try-catch-finally的try语句块中插入return语句,finally语句块是否还会执行?
- Android学习之路---ImageSwitcher和TextSwitcher切换图片及文本
- 问题二十八:ray tracing中的散焦模糊(defocus blur)
- 34、(知识篇)SpringMVC11 JSR303 使用 / Spring表单 /错误信息国际化
- PCB布线学习(一)
- 婚姻默想(四)
- C++标准库与STL的关系
- Atom编辑器
- 机器学习:EM算法
- 微信小程序入门之swiper
- javax.el.PropertyNotFoundException: Property 'name' not found on type java.lang.String