1) Added descriptions to almost all of functions (needs check and additions)
2) Functions and structers were divided in different namespaces for better view 3) Some minor changes in CMakeLists.txtpull/19/head
parent
9dbbdb547d
commit
17bf3d918a
|
@ -1,5 +1,5 @@
|
|||
cmake_minimum_required (VERSION 2.8)
|
||||
project (tinyraytracer)
|
||||
project (raytracer)
|
||||
|
||||
include(CheckCXXCompilerFlag)
|
||||
|
||||
|
@ -23,5 +23,5 @@ enable_cxx_compiler_flag_if_supported("-fopenmp")
|
|||
|
||||
file(GLOB SOURCES *.h *.cpp)
|
||||
|
||||
add_executable(${PROJECT_NAME} ${SOURCES})
|
||||
add_executable(${PROJECT_NAME} ${SOURCES} raytracing/raytracing.cpp)
|
||||
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
#include "raytracing/raytracing.h"
|
||||
|
||||
int main() {
|
||||
raytracing::entities::Material ivory(1.0, Vec4f(0.6, 0.3, 0.1, 0.0), Vec3f(0.4, 0.4, 0.3), 50.);
|
||||
raytracing::entities::Material glass(1.5, Vec4f(0.0, 0.5, 0.1, 0.8), Vec3f(0.6, 0.7, 0.8), 125.);
|
||||
raytracing::entities::Material red_rubber(1.0, Vec4f(0.9, 0.1, 0.0, 0.0), Vec3f(0.3, 0.1, 0.1), 10.);
|
||||
raytracing::entities::Material mirror(1.0, Vec4f(0.0, 10.0, 0.8, 0.0), Vec3f(1.0, 1.0, 1.0), 1425.);
|
||||
|
||||
std::vector<raytracing::entities::Sphere> spheres;
|
||||
spheres.push_back(raytracing::entities::Sphere(Vec3f(-3, 0, -16), 2, ivory));
|
||||
spheres.push_back(raytracing::entities::Sphere(Vec3f(-1.0, -1.5, -12), 2, glass));
|
||||
spheres.push_back(raytracing::entities::Sphere(Vec3f( 1.5, -0.5, -18), 3, red_rubber));
|
||||
spheres.push_back(raytracing::entities::Sphere(Vec3f( 7, 5, -18), 4, mirror));
|
||||
|
||||
std::vector<raytracing::entities::Light> lights;
|
||||
lights.push_back(raytracing::entities::Light(Vec3f(-20, 20, 20), 1.5));
|
||||
lights.push_back(raytracing::entities::Light(Vec3f( 30, 50, -25), 1.8));
|
||||
lights.push_back(raytracing::entities::Light(Vec3f( 30, 20, 30), 1.7));
|
||||
|
||||
raytracing::render(spheres, lights);
|
||||
|
||||
std::cout << "result is saved in build directory in file out.ppm" << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
//
|
||||
// Created by Виктор Задябин on 09.03.2020.
|
||||
//
|
||||
|
||||
#ifndef TINYRAYTRACER_ENTITIES_H
|
||||
#define TINYRAYTRACER_ENTITIES_H
|
||||
namespace raytracing {
|
||||
namespace entities {
|
||||
|
||||
struct Light {
|
||||
/// Light is a source of light
|
||||
/// \param p - position of light source
|
||||
/// \param i - intensity of light source
|
||||
Light(const Vec3f &p, const float i) : position(p), intensity(i) {}
|
||||
|
||||
Vec3f position;
|
||||
float intensity;
|
||||
};
|
||||
|
||||
struct Material {
|
||||
/// Material is a
|
||||
/// \param r
|
||||
/// \param a
|
||||
/// \param color
|
||||
/// \param spec
|
||||
Material(const float r, const Vec4f &a, const Vec3f &color, const float spec) : refractive_index(r),
|
||||
albedo(a),
|
||||
diffuse_color(color),
|
||||
specular_exponent(spec) {}
|
||||
|
||||
Material() : refractive_index(1), albedo(1, 0, 0, 0), diffuse_color(), specular_exponent() {}
|
||||
|
||||
float refractive_index;
|
||||
Vec4f albedo;
|
||||
Vec3f diffuse_color;
|
||||
float specular_exponent;
|
||||
};
|
||||
|
||||
struct Sphere {
|
||||
Vec3f center;
|
||||
float radius;
|
||||
Material material;
|
||||
|
||||
/// Sphere - object that constructed by
|
||||
/// \param c - its center
|
||||
/// \param r - its radius
|
||||
/// \param m - its material
|
||||
Sphere(const Vec3f &c, const float r, const Material &m) : center(c), radius(r), material(m) {}
|
||||
|
||||
/// ray_intersect - checks if ray intersects sphere
|
||||
/// \param orig - position of light
|
||||
/// \param dir - direction of light ray
|
||||
/// \param t0 - coordinate of intersection
|
||||
/// \return true if ray intersects sphere, false otherwise
|
||||
bool ray_intersect(const Vec3f &orig, const Vec3f &dir, float &t0) const;
|
||||
};
|
||||
|
||||
}// namespace entities
|
||||
}
|
||||
#endif //TINYRAYTRACER_ENTITIES_H
|
|
@ -1,52 +1,27 @@
|
|||
#define _USE_MATH_DEFINES
|
||||
#include "raytracing.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include "geometry.h"
|
||||
|
||||
struct Light {
|
||||
Light(const Vec3f &p, const float i) : position(p), intensity(i) {}
|
||||
Vec3f position;
|
||||
float intensity;
|
||||
};
|
||||
|
||||
struct Material {
|
||||
Material(const float r, const Vec4f &a, const Vec3f &color, const float spec) : refractive_index(r), albedo(a), diffuse_color(color), specular_exponent(spec) {}
|
||||
Material() : refractive_index(1), albedo(1,0,0,0), diffuse_color(), specular_exponent() {}
|
||||
float refractive_index;
|
||||
Vec4f albedo;
|
||||
Vec3f diffuse_color;
|
||||
float specular_exponent;
|
||||
};
|
||||
|
||||
struct Sphere {
|
||||
Vec3f center;
|
||||
float radius;
|
||||
Material material;
|
||||
|
||||
Sphere(const Vec3f &c, const float r, const Material &m) : center(c), radius(r), material(m) {}
|
||||
|
||||
bool ray_intersect(const Vec3f &orig, const Vec3f &dir, float &t0) const {
|
||||
Vec3f L = center - orig;
|
||||
float tca = L*dir;
|
||||
float d2 = L*L - tca*tca;
|
||||
if (d2 > radius*radius) return false;
|
||||
float thc = sqrtf(radius*radius - d2);
|
||||
t0 = tca - thc;
|
||||
float t1 = tca + thc;
|
||||
if (t0 < 0) t0 = t1;
|
||||
if (t0 < 0) return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
//TODO : description
|
||||
/// reflect
|
||||
/// \param I
|
||||
/// \param N
|
||||
/// \return
|
||||
Vec3f reflect(const Vec3f &I, const Vec3f &N) {
|
||||
return I - N*2.f*(I*N);
|
||||
return I - N * 2.f * (I * N);
|
||||
}
|
||||
|
||||
//TODO : description
|
||||
/// refract
|
||||
/// \param I
|
||||
/// \param N
|
||||
/// \param eta_t
|
||||
/// \param eta_i
|
||||
/// \return
|
||||
Vec3f refract(const Vec3f &I, const Vec3f &N, const float eta_t, const float eta_i=1.f) { // Snell's law
|
||||
float cosi = - std::max(-1.f, std::min(1.f, I*N));
|
||||
if (cosi<0) return refract(I, -N, eta_i, eta_t); // if the ray comes from the inside the object, swap the air and the media
|
||||
|
@ -55,7 +30,7 @@ Vec3f refract(const Vec3f &I, const Vec3f &N, const float eta_t, const float eta
|
|||
return k<0 ? Vec3f(1,0,0) : I*eta + N*(eta*cosi - sqrtf(k)); // k<0 = total reflection, no ray to refract. I refract it anyways, this has no physical meaning
|
||||
}
|
||||
|
||||
bool scene_intersect(const Vec3f &orig, const Vec3f &dir, const std::vector<Sphere> &spheres, Vec3f &hit, Vec3f &N, Material &material) {
|
||||
bool scene_intersect(const Vec3f &orig, const Vec3f &dir, const std::vector<raytracing::entities::Sphere> &spheres, Vec3f &hit, Vec3f &N, raytracing::entities::Material &material) {
|
||||
float spheres_dist = std::numeric_limits<float>::max();
|
||||
for (size_t i=0; i < spheres.size(); i++) {
|
||||
float dist_i;
|
||||
|
@ -81,9 +56,17 @@ bool scene_intersect(const Vec3f &orig, const Vec3f &dir, const std::vector<Sphe
|
|||
return std::min(spheres_dist, checkerboard_dist)<1000;
|
||||
}
|
||||
|
||||
Vec3f cast_ray(const Vec3f &orig, const Vec3f &dir, const std::vector<Sphere> &spheres, const std::vector<Light> &lights, size_t depth=0) {
|
||||
//TODO : description
|
||||
/// cast_ray
|
||||
/// \param orig
|
||||
/// \param dir
|
||||
/// \param spheres
|
||||
/// \param lights
|
||||
/// \param depth
|
||||
/// \return
|
||||
Vec3f cast_ray(const Vec3f &orig, const Vec3f &dir, const std::vector<raytracing::entities::Sphere> &spheres, const std::vector<raytracing::entities::Light> &lights, size_t depth=0) {
|
||||
Vec3f point, N;
|
||||
Material material;
|
||||
raytracing::entities::Material material;
|
||||
|
||||
if (depth>4 || !scene_intersect(orig, dir, spheres, point, N, material)) {
|
||||
return Vec3f(0.2, 0.7, 0.8); // background color
|
||||
|
@ -103,7 +86,7 @@ Vec3f cast_ray(const Vec3f &orig, const Vec3f &dir, const std::vector<Sphere> &s
|
|||
|
||||
Vec3f shadow_orig = light_dir*N < 0 ? point - N*1e-3 : point + N*1e-3; // checking if the point lies in the shadow of the lights[i]
|
||||
Vec3f shadow_pt, shadow_N;
|
||||
Material tmpmaterial;
|
||||
raytracing::entities::Material tmpmaterial;
|
||||
if (scene_intersect(shadow_orig, light_dir, spheres, shadow_pt, shadow_N, tmpmaterial) && (shadow_pt-shadow_orig).norm() < light_distance)
|
||||
continue;
|
||||
|
||||
|
@ -113,13 +96,38 @@ Vec3f cast_ray(const Vec3f &orig, const Vec3f &dir, const std::vector<Sphere> &s
|
|||
return material.diffuse_color * diffuse_light_intensity * material.albedo[0] + Vec3f(1., 1., 1.)*specular_light_intensity * material.albedo[1] + reflect_color*material.albedo[2] + refract_color*material.albedo[3];
|
||||
}
|
||||
|
||||
void render(const std::vector<Sphere> &spheres, const std::vector<Light> &lights) {
|
||||
const int width = 1024;
|
||||
const int height = 768;
|
||||
const float fov = M_PI/3.;
|
||||
|
||||
|
||||
|
||||
namespace raytracing {
|
||||
|
||||
namespace entities{
|
||||
|
||||
bool Sphere::ray_intersect(const Vec3f &orig, const Vec3f &dir, float &t0) const {
|
||||
Vec3f L = center - orig;
|
||||
float tca = L*dir;
|
||||
float d2 = L*L - tca*tca;
|
||||
if (d2 > radius*radius) return false;
|
||||
float thc = sqrtf(radius*radius - d2);
|
||||
t0 = tca - thc;
|
||||
float t1 = tca + thc;
|
||||
if (t0 < 0) t0 = t1;
|
||||
if (t0 < 0) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}// namespace entities
|
||||
|
||||
|
||||
|
||||
|
||||
void render(const std::vector<entities::Sphere> &spheres, const std::vector<entities::Light> &lights) {
|
||||
const int width = 1920;
|
||||
const int height = 1080;
|
||||
const float fov = M_PI/3.; ///that's a viewing angle
|
||||
std::vector<Vec3f> framebuffer(width*height);
|
||||
|
||||
#pragma omp parallel for
|
||||
#pragma omp parallel for
|
||||
for (size_t j = 0; j<height; j++) { // actual rendering loop
|
||||
for (size_t i = 0; i<width; i++) {
|
||||
float dir_x = (i + 0.5) - width/2.;
|
||||
|
@ -143,25 +151,4 @@ void render(const std::vector<Sphere> &spheres, const std::vector<Light> &lights
|
|||
ofs.close();
|
||||
}
|
||||
|
||||
int main() {
|
||||
Material ivory(1.0, Vec4f(0.6, 0.3, 0.1, 0.0), Vec3f(0.4, 0.4, 0.3), 50.);
|
||||
Material glass(1.5, Vec4f(0.0, 0.5, 0.1, 0.8), Vec3f(0.6, 0.7, 0.8), 125.);
|
||||
Material red_rubber(1.0, Vec4f(0.9, 0.1, 0.0, 0.0), Vec3f(0.3, 0.1, 0.1), 10.);
|
||||
Material mirror(1.0, Vec4f(0.0, 10.0, 0.8, 0.0), Vec3f(1.0, 1.0, 1.0), 1425.);
|
||||
|
||||
std::vector<Sphere> spheres;
|
||||
spheres.push_back(Sphere(Vec3f(-3, 0, -16), 2, ivory));
|
||||
spheres.push_back(Sphere(Vec3f(-1.0, -1.5, -12), 2, glass));
|
||||
spheres.push_back(Sphere(Vec3f( 1.5, -0.5, -18), 3, red_rubber));
|
||||
spheres.push_back(Sphere(Vec3f( 7, 5, -18), 4, mirror));
|
||||
|
||||
std::vector<Light> lights;
|
||||
lights.push_back(Light(Vec3f(-20, 20, 20), 1.5));
|
||||
lights.push_back(Light(Vec3f( 30, 50, -25), 1.8));
|
||||
lights.push_back(Light(Vec3f( 30, 20, 30), 1.7));
|
||||
|
||||
render(spheres, lights);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}// namespace raytracing
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef TINYRAYTRACER_RAYTRACING_H
|
||||
#define TINYRAYTRACER_RAYTRACING_H
|
||||
|
||||
#include "../geometry.h"
|
||||
#include "entities.h"
|
||||
namespace raytracing {
|
||||
|
||||
/// render - function for filling image with blue color, also for adding spheres and lights to
|
||||
/// picture,
|
||||
/// \param spheres - vector of spheres
|
||||
/// \param lights - vector of lights
|
||||
void render(const std::vector<entities::Sphere> &spheres, const std::vector<entities::Light> &lights);
|
||||
|
||||
}//namespace raytracing
|
||||
|
||||
#endif //TINYRAYTRACER_RAYTRACING_H
|
Loading…
Reference in New Issue