COSC-3P93-Project/Step 2/include/raytracing.h

109 lines
3.7 KiB
C
Raw Normal View History

2022-10-16 17:53:33 -04:00
/*
* Created by Brett Terpstra 6920201 on 16/10/22.
* Copyright (c) 2022 Brett Terpstra. All Rights Reserved.
*
* The general class for all things raytracing!
*/
#ifndef STEP_2_RAYTRACING_H
#define STEP_2_RAYTRACING_H
#include <math/vectors.h>
#include <image/image.h>
2022-10-17 00:29:34 -04:00
#include <util/parser.h>
#include <world.h>
2022-10-16 17:53:33 -04:00
2022-10-17 00:29:34 -04:00
#include <utility>
2022-10-16 17:53:33 -04:00
2022-10-17 00:29:34 -04:00
namespace Raytracing {
2022-10-16 17:53:33 -04:00
class Camera {
private:
/* Image details */
const Image image;
const PRECISION_TYPE aspectRatio;
/* Camera details */
PRECISION_TYPE viewportHeight;
PRECISION_TYPE viewportWidth;
PRECISION_TYPE focalLength = 1.0;
2022-10-18 23:11:51 -04:00
Vec4 position{0, 0, 0};
Vec4 horizontalAxis;
Vec4 verticalAxis;
Vec4 imageOrigin;
2022-10-16 17:53:33 -04:00
public:
Camera(PRECISION_TYPE fov, const Image& image): image(image),
aspectRatio(double(image.getWidth()) / double(image.getHeight())) {
viewportHeight = (2.0 * tan(degreeeToRadian(fov) / 2));
viewportWidth = (aspectRatio * viewportHeight);
2022-10-18 23:11:51 -04:00
horizontalAxis = (Vec4{viewportWidth, 0, 0, 0});
verticalAxis = (Vec4{0, viewportHeight, 0, 0});
imageOrigin = (position - horizontalAxis / 2 - verticalAxis / 2 - Vec4(0, 0, focalLength, 0));
2022-10-16 17:53:33 -04:00
tlog << viewportHeight << "\n";
tlog << viewportWidth << "\n";
tlog << "\n";
tlog << horizontalAxis << "\n";
tlog << verticalAxis << "\n";
tlog << imageOrigin << "\n";
}
Ray projectRay(PRECISION_TYPE x, PRECISION_TYPE y);
// makes the camera look at the lookatpos from the position p, with respects to the up direction up. (set to 0,1,0)
2022-10-18 23:11:51 -04:00
void lookAt(const Vec4& pos, const Vec4& lookAtPos, const Vec4& up);
2022-10-16 17:53:33 -04:00
2022-10-18 23:11:51 -04:00
void setPosition(const Vec4& pos) { this->position = pos; }
2022-10-17 00:29:34 -04:00
void setRotation(PRECISION_TYPE yaw, PRECISION_TYPE pitch, PRECISION_TYPE roll);
2022-10-16 17:53:33 -04:00
};
2022-10-17 19:16:10 -04:00
static Random rnd{-1, 1};
2022-10-17 00:29:34 -04:00
class Raycaster {
2022-10-16 17:53:33 -04:00
private:
2022-10-17 00:29:34 -04:00
const int maxBounceDepth = 50;
const int raysPerPixel = 50;
Camera& camera;
Image& image;
World& world;
2022-10-18 23:11:51 -04:00
Vec4 raycast(const Ray& ray, int depth);
2022-10-17 19:16:10 -04:00
public:
2022-10-18 23:11:51 -04:00
inline static Vec4 randomUnitVector() {
2022-10-17 00:29:34 -04:00
// there are two methods to generating a random unit sphere
// one which is fast and approximate:
//auto v = vec4(rnd.getDouble(), rnd.getDouble(), rnd.getDouble());
//return v.normalize();
// and the one which generates an actual unit vector
while (true) {
2022-10-18 23:11:51 -04:00
auto v = Vec4(rnd.getDouble(), rnd.getDouble(), rnd.getDouble());
2022-10-17 00:29:34 -04:00
if (v.lengthSquared() >= 1)
continue;
return v;
}
// the second creates better results but is 18% slower (better defined shadows)
// likely due to not over generating unit vectors biased towards the corners
}
2022-10-17 10:09:31 -04:00
// unused but provides another method of diffuse rendering
2022-10-18 23:11:51 -04:00
inline static Vec4 randomUnitHemisphere(const Vec4& normal){
Vec4 v = randomUnitVector().normalize();
if (Vec4::dot(v, normal) > 0.0)
2022-10-17 10:09:31 -04:00
return v;
else
return -v;
}
2022-10-18 23:11:51 -04:00
Raycaster(Camera& c, Image& i, World& world, const Parser& p): camera(c), image(i), world(world) {
world.generateBVH();
}
2022-10-17 00:29:34 -04:00
void run();
2022-10-16 17:53:33 -04:00
};
}
#endif //STEP_2_RAYTRACING_H