Basics of raytracing

This commit is contained in:
Ben Kyd
2019-07-26 23:58:21 +01:00
parent ba7c58dd7c
commit 553f610413
20 changed files with 301 additions and 48 deletions

View File

@@ -57,7 +57,7 @@ include_directories(${executable}
file(GLOB SourceFiles
${SrcDIR}/*
${SrcDIR}/core/*
${SrcDIR}/core/renderengine/*
${SrcDIR}/engine/*
${SrcDIR}/display/*
${SrcDIR}/primatives/*
${SrcDIR}/util/*

View File

@@ -1,6 +1,8 @@
#ifndef INFERNO_COMMON_H_
#define INFERNO_COMMON_H_
#include <SDL2/SDL.h>
#include <string>
enum OperationMode {

View File

@@ -1,5 +0,0 @@
#include "./progressiverenderer.hpp"
ProgressiveRenderer::ProgressiveRenderer() {
}

View File

@@ -1,9 +0,0 @@
#ifndef INFERNO_CORE_RENDERENGINE_PROGRESSIVERENDERER_H_
#define INFERNO_CORE_RENDERENGINE_PROGRESSIVERENDERER_H_
class ProgressiveRenderer {
public:
ProgressiveRenderer();
};
#endif

View File

@@ -2,6 +2,8 @@
#include "../pixel.hpp"
#include "./renderer.hpp"
#include "../engine/progressiverenderer.hpp"
Renderer::Renderer(OperationMode mode) {
m_mode = mode;
}
@@ -11,6 +13,19 @@ void Renderer::SetMode(OperationMode mode, int samples) {
m_samples = samples;
}
void Renderer::Init() {
}
void Renderer::Init(DisplayInterface* display) {
// Add warning
if (!display) return;
if(!m_framebuffer) {
m_framebuffer = display->Framebuffer;
}
m_interface = display;
}
void Renderer::Render() {
if (m_mode == MODE_PROGRESSIVE_GUI || m_mode == MODE_PROGRESSIVE_IMG) {
RenderProgressive();
@@ -32,33 +47,11 @@ void Renderer::Render(uint32_t* framebuffer) {
}
}
void Renderer::Init() {
}
void Renderer::Init(DisplayInterface* display) {
// Add warning
if (!display) return;
if(!m_framebuffer) {
m_framebuffer = display->Framebuffer;
}
m_interface = display;
}
void Renderer::RenderProgressive() {
while (m_interface->Active) {
SDL_Event e;
while (SDL_PollEvent(&e) == SDL_TRUE)
if (e.type == SDL_QUIT) m_interface->Close();
for (int i = 0; i < 360000; i++) {
m_interface->SetPixelSafe(rand() % m_interface->XRes,
rand() % m_interface->YRes,
rgb888(rand() % 255, rand() % 255, rand() % 255));
}
m_interface->Update();
}
m_progressive = new ProgressiveRenderer();
m_progressive->Init(m_interface);
m_progressive->Render();
}
void Renderer::RenderSamples() {

View File

@@ -5,6 +5,8 @@
class DisplayInterface;
class ProgressiveRenderer;
// Function initProgressive or whatever takes a pointer to the display
class Renderer {
public:
@@ -27,8 +29,10 @@ private:
uint32_t* m_framebuffer = nullptr;
void RenderProgressive();
ProgressiveRenderer* m_progressive = nullptr;
void RenderSamples();
};
#endif

View File

@@ -0,0 +1,13 @@
#ifndef INFERNO_DEFINITIONS_CAMERA_H_
#define INFERNO_DEFINITIONS_CAMERA_H_
#include "../maths.hpp"
class Camera {
public:
glm::vec3 point;
glm::vec3 look;
float fov;
};
#endif

View File

@@ -0,0 +1,44 @@
#ifndef INFERNO_DEFINITIONS_PRIMATIVES_PRIMATIVE_H_
#define INFERNO_DEFINITIONS_PRIMATIVES_PRIMATIVE_H_
#include "../maths.hpp"
class Ray;
enum PrimativeType {
TYPE_NONE,
TYPE_SPHERE,
TYPE_PLANE,
TYPE_TRI
};
class Primative {
public:
// Attributes
glm::vec3 center;
// Sphere
float radius;
// Plane
glm::vec3 normal;
PrimativeType type = TYPE_NONE;
// Sphere constructor
Primative(glm::vec3 center, float radius)
: center(center), radius(radius) {
type = TYPE_SPHERE;
}
// Plane constructor
Primative(glm::vec3 center, glm::vec3 normal)
: center(center), normal(normal) {
type = TYPE_PLANE;
}
virtual bool DoesIntersect(Ray& ray, float& t) = 0;
virtual glm::vec3 SurfaceNormal(glm::vec3 hitPoint) = 0;
virtual glm::vec2 TexCoords(glm::vec3 hitPoint) = 0;
virtual void Translate(glm::vec3 trans) = 0;
};
#endif

View File

@@ -0,0 +1,45 @@
#include "sphere.hpp"
#include "ray.hpp"
bool Sphere::DoesIntersect(Ray& ray, float& t) {
float t0, t1; // Solutions for intersect
// glm::vec3 L = ray.origin - center;
// float a = glm::dot(ray.direction, ray.direction);
// float b = 2 * glm::dot(ray.direction, L);
// float c = glm::dot(L, L) - radius;
// if (!quadratic(a, b, c, t0, t1)) {
// t = INFINITY;
// return false;
// };
glm::vec3 l = center - ray.origin;
float tca = glm::dot(l, ray.direction);
if (tca < 0.0f) return false;
float d2 = glm::dot(l, l) - tca * tca;
if (d2 > radius * radius) return false;
float thc = sqrtf(radius * radius - d2);
t0 = tca - thc;
t1 = tca + thc;
if (t0 < t1) t = t0;
else t = t1;
return true; // (t0 > t1 && t1 > 0.0f) ? t1 > 0.0f : t0 > 0.0f;
}
glm::vec3 Sphere::SurfaceNormal(glm::vec3 hitPoint) {
return glm::normalize(hitPoint - center);
}
glm::vec2 Sphere::TexCoords(glm::vec3 hitPoint) {
glm::vec3 hit = hitPoint - center;
return { (1.0 + atan2(hit.z, hit.x) / PI) * 0.5,
acos(hit.y / radius) / PI };
}
void Sphere::Translate(glm::vec3 trans) {
center += trans;
}

View File

@@ -0,0 +1,17 @@
#ifndef INFERNO_DEFINITIONS_PRIMATIVES_SPHERE_H_
#define INFERNO_DEFINITIONS_PRIMATIVES_SPHERE_H_
#include "primative.hpp"
class Sphere : public Primative {
Sphere(glm::vec3 center, float radius)
: Primative(center, radius) { }
bool DoesIntersect(Ray& ray, float& t) override;
glm::vec3 SurfaceNormal(glm::vec3 hitPoint) override;
glm::vec2 TexCoords(glm::vec3 hitPoint) override;
void Translate(glm::vec3 trans) override;
};
#endif

8
src/definitions/ray.cpp Normal file
View File

@@ -0,0 +1,8 @@
#include "ray.hpp"
#include "camera.hpp"
#include "scene.hpp"
Ray GeneratePrimaryRay(int x, int y, Scene& scene, float xSubPix = 0.5f, float ySubPix = 0.5f) {
}

16
src/definitions/ray.hpp Normal file
View File

@@ -0,0 +1,16 @@
#ifndef INFERNO_DEFINITIONS_RAY_H_
#define INFERNO_DEFINITIONS_RAY_H_
#include "../maths.hpp"
class Scene;
class Ray {
public:
glm::vec3 origin;
glm::vec3 direction;
};
Ray GeneratePrimaryRay(int x, int y, Scene& scene, float xSubPix = 0.5f, float ySubPix = 0.5f);
#endif

14
src/definitions/scene.hpp Normal file
View File

@@ -0,0 +1,14 @@
#ifndef INFERNO_DEFINITIONS_SCENE_H_
#define INFERNO_DEFINITIONS_SCENE_H_
#include <vector>
class Camera;
class Primative;
class Scene {
Camera* camera;
std::vector<Primative*> objects;
};
#endif

View File

@@ -1,11 +1,8 @@
#ifndef INFERNO_DISPLAY_DISPLAY_H_
#define INFERNO_DISPLAY_DISPLAY_H_
#include <SDL2/SDL.h>
#include <string>
#include "./displayinterface.hpp"
#include "../common.hpp"
#include "displayinterface.hpp"
class Pixel;

View File

@@ -0,0 +1,31 @@
#include "./progressiverenderer.hpp"
#include "../common.hpp"
#include "../pixel.hpp"
#include "../display/displayinterface.hpp"
ProgressiveRenderer::ProgressiveRenderer() {
}
void ProgressiveRenderer::Init(DisplayInterface* interface) {
m_interface = interface;
}
void ProgressiveRenderer::Render() {
// RENDERING CAN ACTUALLY START
while (m_interface->Active) {
SDL_Event e;
while (SDL_PollEvent(&e) == SDL_TRUE)
if (e.type == SDL_QUIT) m_interface->Close();
for (int i = 0; i < 360000; i++) {
m_interface->SetPixelSafe(rand() % m_interface->XRes,
rand() % m_interface->YRes,
rgb888(rand() % 255, rand() % 255, rand() % 255));
}
m_interface->Update();
}
}

View File

@@ -0,0 +1,18 @@
#ifndef INFERNO_ENGINE_PROGRESSIVERENDERER_H_
#define INFERNO_ENGINE_PROGRESSIVERENDERER_H_
class DisplayInterface;
class ProgressiveRenderer {
public:
ProgressiveRenderer();
void Init(DisplayInterface* interface);
void Render();
private:
DisplayInterface* m_interface = nullptr;
};
#endif

View File

@@ -5,7 +5,10 @@
#include <vector>
#include <utility>
#include "./common.hpp"
#include "common.hpp"
#include "definitions/camera.hpp"
#include "definitions/scene.hpp"
class Display;
class Renderer;

62
src/maths.hpp Normal file
View File

@@ -0,0 +1,62 @@
#ifndef INFERNO_MATHS_H_
#define INFERNO_MATHS_H_
#include <glm/glm.hpp>
#include <algorithm>
#include <math.h>
const float DEG2RAD = 0.01745329251994329576923690768f;
const float RAD2DEG = 57.2957795130823208767981548141f;
const float PI = 3.14159265358979323846264338327f;
const float EPSILON = 0.00001000000000000000000000000f;
inline float fastDegreetoRadian(const float Degree) {
return (Degree * DEG2RAD);
}
inline float fastRadianToDegree(const float Radian) {
return (Radian * RAD2DEG);
}
inline float getFovAdjustment(const float fov) {
return tanf(fov * PI / 360.0f);
}
inline float getAspectRatio(const float w, const float h) {
return (float)w / (float)h;
}
// (-b += sqrt(b^2-4ac)) / 2a
inline bool quadratic(float a, float b, float c, float& x0, float& x1) {
float discr = b * b - 4.0f * a * c;
if (discr < 0.0f) return false;
else if (discr == 0.0f) x0 = x1 = -0.5f * b / a;
else {
float q = (b > 0.0f) ?
-0.5f * (b + sqrtf(discr)) :
-0.5f * (b - sqrtf(discr));
x0 = q / a;
x1 = c / q;
}
if (x0 > x1) std::swap(x0, x1);
return true;
}
inline float clamp(float n, float lower, float upper) {
return std::max(lower, std::min(n, upper));
}
inline void clamp(glm::vec3& col, float lower, float upper) {
clamp(col.r, lower, upper);
clamp(col.g, lower, upper);
clamp(col.b, lower, upper);
}
inline float modulo(float x) {
return x - std::floor(x);
}
#endif