Cette classe est un angle de caméra panoramique, décrit en détail les principes du livre. Directement au code de mise en œuvre.
Déclaration Classe:
#pragma une fois #ifndef __SPHERICAL_HEADER__ #define __SPHERICAL_HEADER__ #include "camera.h" classe Sphérique: Caméra publique { public: Sphérique (); ~ Sphérique (); Sphérique (const & sphérique sp); set_fov vide (const LDouble HFOV, const LDouble VFOV); set_angle vide (const LDouble deg); Vector3 ray_direction (const Point3 & pp, hres entiers const, vres entiers const, const LDouble s) const; clone caméra virtuel * () const; render_scene vide virtuel (World & w); & Operator = Sphérique (const & sp sphérique); privé: LDouble lambda_max, psi_max; }; #fin si
la mise en œuvre Classe:
#include "pch.h" #include "spherical.h" #include "../utilities/world.h" #include "../utilities/viewplane.h" #include "../samplers/sampler.h" #include "../tracers/tracer.h" sphérique :: sphérique (): Caméra (), lambda_max (180), psi_max (180) {} sphérique :: ~ sphérique () {} sphérique :: sphérique (const & sphérique sp): Caméra (sp), lambda_max (sp.lambda_max), psi_max (sp.psi_max) {} Spherical Void :: set_fov (const LDouble HFOV, const LDouble VFOV) { lambda_max = HFOV / 2; psi_max = VFOV / 2; } Vide 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, hres entiers const, vres entiers const, const LDouble s) const { pn Point3 (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, thêta = 0,5 * M_PI - psi; LDouble sin_phi = std :: sin (phi), cos_phi = std :: cos (phi), sin_theta = std :: sin (thêta), cos_theta = std :: cos (thêta); Vector3 dir = sin_theta * sin_phi * u + v + cos_theta * * sin_theta cos_phi * w; retourner dir; } Caméra * :: clone sphérique () const { return new sphérique (* this); } Spherical Void :: render_scene (World & w) { ray Ray; } ViewPlane vp (w.vp); profondeur entier = 0; Point3 sp, pp; w.open_window (vp.hres, vp.vres); ray.o = oeil; vp.s = 1 / vp.s; pour (nombre entier r = vp.vres - 1; r> = 0; r -) // rendre de coin gauche à droite pour (nombre entier c = 0; c <vp.hres; c ++) { couleur RGBColor; pour (nombre entier 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); couleur + = w.tracer_ptr-> trace_ray (ray); couleur / = vp.nsamples; couleur * = exposure_time; w.display_pixel (r, c, couleur); } } Sphérique et rotule :: operator = (const & sp Sphérique) { if (cette == & sp) retour * ce; Caméra opérateur :: = (sp); lambda_max = sp.lambda_max; psi_max = sp.psi_max; retour * cela; }
rendus d'essai (par exemple après l'addition du matériau, et puis regarder les résultats):