83 lines
2.7 KiB
C++
83 lines
2.7 KiB
C++
#pragma once
|
|
|
|
#include <vector>
|
|
#include "./vec.hpp"
|
|
|
|
struct Screen {
|
|
const int W, H;
|
|
const choice_t ASPECT_RATIO;
|
|
constexpr Screen(int W, int H, choice_t ASPECT_RATIO)
|
|
: W(W), H(H), ASPECT_RATIO(ASPECT_RATIO) {}
|
|
};
|
|
|
|
struct Camera {
|
|
v3 pos; v3 rotation; v3 translation{0,0,0};
|
|
choice_t zoom = 0.5;
|
|
choice_t exposure = -0.6;
|
|
choice_t dynamic_range = 1;
|
|
};
|
|
|
|
struct Material {
|
|
choice_t specular = 0.1;
|
|
choice_t roughness = 0.5;
|
|
choice_t ior = 1.2;
|
|
choice_t transparency = 0.8;
|
|
v3 colour;
|
|
};
|
|
|
|
struct Renderable {
|
|
Material specs;
|
|
|
|
Renderable(const Material& specs);
|
|
|
|
virtual int intersect(const v3& eye, const v3& dir, choice_t& hit_dist, v3& hit_loc, v3& hit_normal)=0;
|
|
|
|
/**
|
|
Like #intersect, but for transmission rays inside the object. #eye must
|
|
be on the surface of the object.
|
|
*/
|
|
virtual int transmit(const v3& eye, const v3& dir, choice_t& hit_dist, v3& hit_loc, v3& hit_normal) { return -1; }
|
|
};
|
|
|
|
/**
|
|
Shoots a ray from #eye in direction #dir, (possibly) hitting the closest object from #objs.
|
|
Expects #dir to be normalised.
|
|
|
|
The hit object's distance, location, normal and type will be written in the
|
|
references so-aptly named. If nothing was hit, the contents of those variables is UB.
|
|
|
|
Returns the pointer to the object it hit, or `nullptr' otherwise.
|
|
|
|
Respects the initial value of #hit_dist, et al.
|
|
|
|
Optional parameter #self is a pointer to an object considered 'self' that
|
|
will be skipped during collision checks. The objects are compared by pointer
|
|
address.
|
|
*/
|
|
Renderable* shoot_ray_into_objects(const v3& eye, const v3& dir, const std::vector<Renderable*>& objs,
|
|
choice_t& hit_dist, v3& hit_loc, v3& hit_normal, int& hit_type,
|
|
Renderable* self = nullptr);
|
|
|
|
/**
|
|
Shoots a ray from #eye in (unit) direction #dir into a #scene and returns the
|
|
colour of that ray.
|
|
|
|
#scene must be #objects u #lights.
|
|
|
|
#depth is how much the ray tracer is allowed to recurse.
|
|
*/
|
|
v3 ray_trace(const v3& eye, const v3& dir,
|
|
const std::vector<Renderable*>& scene,
|
|
const std::vector<Renderable*>& objects,
|
|
const std::vector<Renderable*>& lights, int depth,
|
|
Renderable* skip = nullptr,
|
|
choice_t* dist_to_hit = nullptr);
|
|
|
|
choice_t ggx_ndf(const v3& dir, const v3& h, const v3& normal, choice_t roughness);
|
|
choice_t blinn_phong_ndf(const v3& dir, const v3& h, const v3& normal, choice_t roughness);
|
|
choice_t cook_torrance_gaf(const v3& dir, const v3& h, const v3& normal, const v3& light);
|
|
choice_t cook_torrance_fresnel(const v3& dir, const v3& h, choice_t ior);
|
|
|
|
v3 cook_torrance(const v3& dir, const v3& normal, const v3& light, choice_t specular, choice_t roughness,
|
|
choice_t ior, const v3& light_colour, const v3& surface_colour);
|