Thinhole类声明和实现
Thinhole类说白了就是在眼睛处,放一个放大镜。就像我们平时用放大镜观察物体一样。这样实现的效果的是,周围会模糊。原理书上都说的很清楚了,我把算法截图下来了。这个应用我猜测是在竞技游戏比如csgo中,狙击开镜后效果。具体等之后开发游戏时,再测试一下。如下:
类声明:
#pragma once
#ifndef __THINLENS_HEADER__
#define __THINLENS_HEADER__ #include "camera.h" class Sampler; class Thinlens :public Camera {
public:
Thinlens();
~Thinlens();
Thinlens(const Thinlens& tl);
void set_view_distance(const ldouble a);
void set_focal_distance(const ldouble a);//这个是放大镜的系数,我默认是取0.8,因为我用的物体是1个像素,比较小。
void set_lens_radius(const ldouble rad);//放大镜的半径
void set_zoom(const ldouble factor);//缩放
void set_angle(const ldouble deg);//旋转角
void set_sampler(Sampler* const sampler);//随机采样数组,实现模糊效果
Vector3 ray_direction(const Point3& pixel_point, const Point3& lens_point) const;
virtual Camera* clone() const;
virtual void render_scene(World& w);
Thinlens& operator=(const Thinlens& tl);
private:
ldouble lens_radius, d, f, zoom;
Sampler* sampler;
};
#endif
类实现
#include "pch.h"
#include "thinlens.h"
#include "../utilities/world.h"
#include "../utilities/viewplane.h"
#include "../samplers/sampler.h"
#include "../tracers/tracer.h" Thinlens::Thinlens()
:Camera(), lens_radius(0.5), f(0.8), d(1), zoom(1), sampler(nullptr) {} Thinlens::~Thinlens() {
if (sampler)
delete sampler;
} Thinlens::Thinlens(const Thinlens& tl)
:Camera(tl), lens_radius(tl.lens_radius), f(tl.f), d(tl.d)
, zoom(tl.zoom), sampler(tl.sampler) {} void Thinlens::set_view_distance(const ldouble a) {
d = a;
} void Thinlens::set_focal_distance(const ldouble a) {
f = a;
} void Thinlens::set_lens_radius(const ldouble rad) {
lens_radius = rad;
} void Thinlens::set_zoom(const ldouble factor) {
zoom = factor;
} void Thinlens::set_angle(const ldouble deg) {
ldouble rad = radian(deg);
up = Point3(std::cos(rad) * up.x - std::sin(rad) * up.y,
std::sin(rad) * up.x + std::cos(rad) * up.y, up.z);
} void Thinlens::set_sampler(Sampler* const sam) {
if (sampler) {
delete sampler;
sampler = nullptr;
}
sampler = sam;
sampler->map_to_unit_disk();
} Vector3 Thinlens::ray_direction(const Point3& pixel_point, const Point3& lens_point) const {
Point3 p;
p.x = pixel_point.x * d * f;
p.y = pixel_point.y * d * f;
Vector3 dir = (p.x - lens_point.x) * u + (p.y - lens_point.y) * v - f * w;
dir.normalize();
return dir;
} Camera* Thinlens::clone() const {
return new Thinlens(*this);
} void Thinlens::render_scene(World& w) {
Ray ray;
ViewPlane vp(w.vp);
integer depth = 0;
Point3 sp, pp, lp;
w.open_window(vp.hres, vp.vres);
vp.s = 1 / (vp.s * zoom);
for (integer r = vp.vres - 1; r >= 0; r--)//render from left-corner to right-corner
for (integer c = 0; c < vp.hres; c++) {
RGBColor color;
for (integer p = 0; p < vp.nsamples; p++) {
sp = vp.sampler->sample_unit_square();
pp.x = (c - 0.5 * vp.hres + sp.x) * vp.s;
pp.y = (r - 0.5 * vp.vres + sp.y) * vp.s;
lp = sampler->sample_unit_square() * lens_radius;
ray.o = eye + lp.x * u + lp.y * v;
ray.d = ray_direction(pp, lp);
color += w.tracer_ptr->trace_ray(ray);
}
color /= vp.nsamples;
color *= exposure_time;
w.display_pixel(r, c, color);
}
} Thinlens& Thinlens::operator=(const Thinlens& tl) {
if (this == &tl)
return *this;
Camera::operator= (tl);
lens_radius = tl.lens_radius;
d = tl.d;
f = tl.f;
zoom = tl.zoom;
sampler = tl.sampler;
return *this;
}
需要修改的World类:
void World::build() {
vp.set_hres(200);
vp.set_vres(100);
vp.set_sampler(new Hammersley());
vp.sampler->map_to_sphere();
tracer_ptr = new MultiSphere(this);
Geometrics* obj = new Sphere(0, 0.5);
obj->set_color(RGBColor(1, 0, 0));
add_object(obj);
obj = new Sphere(Point3(0, -100.5, 0), 100);
obj->set_color(RGBColor(0, 0, 1));
add_object(obj);
Thinlens* thinlens = new Thinlens();
thinlens->set_eye(Point3(0, 0, 1));
thinlens->set_lookat(Point3(0));
thinlens->set_view_distance(1.5);
thinlens->set_sampler(new MultiJittered());//书上是采用多重采样,可以替换为其他采样。不过这个采样效果是比较好的。
thinlens->set_angle(-45);
//thinlens->set_zoom(2.0);
thinlens->compute_uvw();
set_camera(thinlens);
}
测试效果图(蓝色和黑色部分已经模糊了,算法测试成功!):
Thinhole类声明和实现的更多相关文章
- EC笔记,第二部分:7.为多态基类声明虚析构函数
7.为多态基类声明虚析构函数 1.为多态基类声明虚析构函数 code1: class A{ public: int* a; A():a(new int(5)) {} ~A(){ delete a; } ...
- C++ 中的模板类声明头文件和实现文件分离后,如何能实现正常编译?
C++ 中的模板类声明头文件和实现文件分离后,如何能实现正常编译? 这个feature叫做Export Template,即外名模板,它的作用在于使得模板代码可依照C/C++语言习惯,将模板声明和实现 ...
- [Effective C++ --007]为多态基类声明virtual析构函数
引言: 我们都知道类的一个很明显的特性是多态,比如我们声明一个水果的基类: class Fruit { public: Fruit() {}; ~Fruit(){}; } 那么我们根据这个Fruit基 ...
- c++,基类声明的指针变量和引用类型变量可以指向派 生类的对象
基类声明的指针变量和引用类型变量可以指向派生类的对象,而反过来派生类的指针却不能指向基类变量. 这与基类和派生类之间,被允许的赋值方向是相反的. 但是从逻辑上很容易推敲其合理性.
- error C2248: “CObject::operator =”: 不可访问 private 员(于“CObject”类声明)
MFC如果编码错误: 演出:error C2248: "CObject::operator =": 不可访问 private 员(于"CObject"类声明) ...
- 类声明、类作用域、前向声明、this指针、嵌套类、PIMPL 技法 等
一.类声明 //类是一种用户自定义类型,声明形式: class 类名称 { public: 公有成员(外部接口) private: 私有 ...
- C++模板类内友元(友元函数,友元类)声明的三种情况
根据<C++ Primer>第三版16.4节的叙述,C++类模板友元分为以下几种情况 1.非模板友元类或友元函数. 书上给了一个例子: class Foo{ void bar(); ...
- Pinhole类声明和实现
针孔相机,带旋转,移动等功能. 类声明: #pragma once #ifndef __PINHOLE_HEADER__ #define __PINHOLE_HEADER__ #include &qu ...
- 07——为多态基类声明为virtual析构函数
当基类确定被继承的时候,析构函数声明为virtual是必须的 当返回的派生类的指针或引用的时候,调用析构函数容易发生内存泄漏 当基类作为抽象类使用,声明pure virtual析构函数 析构函数的顺序 ...
随机推荐
- 一文看懂 ZooKeeper ,面试再也不用背八股(文末送PDF)
ZooKeeper知识点总结 一.ZooKeeper 的工作机制 二.ZooKeeper 中的 ZAB 协议 三.数据模型与监听器 四.ZooKeeper 的选举机制和流程 本文将以如下内容为主线讲解 ...
- linux篇-图解cacti监控安装
1登录 admin admin 2点击devices localhost 3进入配置保存 4保存 http服务要启动哦 5一步步做 6graph tree 7执行/usr/bin/php /var/w ...
- 前端js堆栈
1.介绍创建数据的时候就会占用内容.内存主要开辟了两类空间1. 堆(进程,线程共享) 大小不固定,可随时增加不允许js直接访问堆内存存储引用类型数据按引用访问存储的值大小不定,可动态调整主要用来存放对 ...
- 渗透测试之常用的sql语句
学习路漫漫,常用的sql语句给我们平常所运用的sql语句相差不多,用句土话讲:百变不离其中 注:网络安全时刻警醒,需要打靶的还需要建立自己的靶场,关注博主在以往博客中分享有多种创建靶场可参考 1.判断 ...
- np.r_、np.c_、np.concatenate和np.append
np.r_是按行连接两个矩阵,就是把两矩阵上下相加,要求列数相等,最终结果的行数为两个矩阵行数和. np.c_是按列连接两个矩阵,就是把两矩阵左右相加,要求行数相等,最终结果的列数等于两矩阵的列数和. ...
- Halodoc使用 Apache Hudi 构建 Lakehouse的关键经验
Halodoc 数据工程已经从传统的数据平台 1.0 发展到使用 LakeHouse 架构的现代数据平台 2.0 的改造.在我们之前的博客中,我们提到了我们如何在 Halodoc 实施 Lakehou ...
- 快速 IO
IO 的进化史 cin和cout 刚开始学的时候,老师叫我们用 cin 和 cout 大概是因为这最简单吧 cin>>x; cout<<x scanf和printf 学到函数了 ...
- Puppeteer学习笔记 (1)- 什么是Puppeteer
本文链接:https://www.cnblogs.com/hchengmx/p/11006263.html 1. phantomjs介绍 在介绍puppeteer之前必须介绍一下phantomjs,p ...
- Quartus II 13.0 sp1的官方下载页面
今天为了下个ModelSim跑到网上去找下载资源,清一色的百度网盘,下载速度60k/s,简直有病,于是跑到Intel官网上把连接挖出来了,供各位直接下载 实测使用IDM多线程下载速度可以轻松上到数MB ...
- SAP JSON 格式化及解析。
一.首选:/ui2/cl_json {'key':'value'} /ui2/cl_json=>deserialize( EXPORTING json = json CHANGING d ...