• Spherical类定义和实现


    此类是一个全景摄像机视角,书上介绍了详细原理。直接给实现代码。

    类声明:

    #pragma once
    #ifndef __SPHERICAL_HEADER__
    #define __SPHERICAL_HEADER__
    
    #include "camera.h"
    
    class Spherical :public Camera {
    public:
    	Spherical();
    	~Spherical();
    	Spherical(const Spherical& sp);
    	void set_fov(const ldouble hfov, const ldouble vfov);
    	void set_angle(const ldouble deg);
    	Vector3 ray_direction(const Point3& pp, const integer hres, const integer vres, const ldouble s) const;
    	virtual Camera* clone() const;
    	virtual void render_scene(World& w);
    	Spherical& operator=(const Spherical& sp);
    private:
    	ldouble lambda_max, psi_max;
    };
    #endif

    类实现:

    #include "pch.h"
    #include "spherical.h"
    #include "../utilities/world.h"
    #include "../utilities/viewplane.h"
    #include "../samplers/sampler.h"
    #include "../tracers/tracer.h"
    
    Spherical::Spherical() :Camera(), lambda_max(180), psi_max(180) {}
    
    Spherical::~Spherical() {}
    
    Spherical::Spherical(const Spherical& sp) : Camera(sp), lambda_max(sp.lambda_max), psi_max(sp.psi_max) {}
    
    void Spherical::set_fov(const ldouble hfov, const ldouble vfov) {
    	lambda_max = hfov / 2;
    	psi_max = vfov / 2;
    }
    
    void Spherical::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);
    }
    
    Vector3 Spherical::ray_direction(const Point3& pp, const integer hres, const integer vres, const ldouble s) const {
    	Point3 pn(2.0 / (s * hres) * pp.x, 2.0 / (s * vres) * pp.y, 0);
    	ldouble lambda = pn.x * radian(lambda_max),
    		psi = pn.y * radian(psi_max);
    	ldouble phi = M_PI - lambda,
    		theta = 0.5 * M_PI - psi;
    	ldouble sin_phi = std::sin(phi), cos_phi = std::cos(phi), sin_theta = std::sin(theta), cos_theta = std::cos(theta);
    	Vector3 dir = sin_theta * sin_phi * u + cos_theta * v + sin_theta * cos_phi * w;
    	return dir;
    }
    
    Camera* Spherical::clone() const {
    	return new Spherical(*this);
    }
    
    void Spherical::render_scene(World& w) {
    	Ray ray;
    	ViewPlane vp(w.vp);
    	integer depth = 0;
    	Point3 sp, pp;
    	w.open_window(vp.hres, vp.vres);
    	ray.o = eye;
    	vp.s = 1 / vp.s;
    	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;
    				ray.d = ray_direction(pp, vp.hres, vp.vres, vp.s);
    				color += w.tracer_ptr->trace_ray(ray);
    			}
    			color /= vp.nsamples;
    			color *= exposure_time;
    			w.display_pixel(r, c, color);
    		}
    }
    
    Spherical& Spherical::operator=(const Spherical& sp) {
    	if (this == &sp)
    		return*this;
    	Camera::operator=(sp);
    	lambda_max = sp.lambda_max;
    	psi_max = sp.psi_max;
    	return *this;
    }

    测试效果图(等之后加了材质后,再看看效果):

  • 相关阅读:
    百度2015校园招聘前端笔试题汇总
    雅虎网站页面性能优化的34条黄金守则(转)
    web跨域通信问题解决
    setTimeout(fn,0)的作用分析
    阿里校园招聘前端面试
    rownum浅谈(二)
    rownum浅谈(一)
    try catch finally 执行顺序面试题总结
    浅谈CPU、内存、硬盘之间的关系
    【多线程学习(2)】继承Thread类和实现Runnable接口、Callable接口的区别
  • 原文地址:https://www.cnblogs.com/dalgleish/p/12651297.html
Copyright © 2020-2023  润新知