1
0
mirror of https://github.com/ssloy/tinyraytracer.git synced 2025-09-02 10:32:39 +02:00

a bit of polishing

This commit is contained in:
Dmitry V. Sokolov
2019-01-24 10:06:56 +01:00
parent e203962cea
commit cc608d433d

View File

@@ -8,13 +8,13 @@
#include "geometry.h" #include "geometry.h"
struct Light { struct Light {
Light(const Vec3f &p, const float &i) : position(p), intensity(i) {} Light(const Vec3f &p, const float i) : position(p), intensity(i) {}
Vec3f position; Vec3f position;
float intensity; float intensity;
}; };
struct Material { 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(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() {} Material() : refractive_index(1), albedo(1,0,0,0), diffuse_color(), specular_exponent() {}
float refractive_index; float refractive_index;
Vec4f albedo; Vec4f albedo;
@@ -27,7 +27,7 @@ struct Sphere {
float radius; float radius;
Material material; Material material;
Sphere(const Vec3f &c, const float &r, const Material &m) : center(c), radius(r), material(m) {} 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 { bool ray_intersect(const Vec3f &orig, const Vec3f &dir, float &t0) const {
Vec3f L = center - orig; Vec3f L = center - orig;
@@ -47,17 +47,12 @@ Vec3f reflect(const Vec3f &I, const Vec3f &N) {
return I - N*2.f*(I*N); return I - N*2.f*(I*N);
} }
Vec3f refract(const Vec3f &I, const Vec3f &N, const float &refractive_index) { // Snell's law 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)); float cosi = - std::max(-1.f, std::min(1.f, I*N));
float etai = 1, etat = refractive_index; 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
Vec3f n = N; float eta = eta_i / eta_t;
if (cosi < 0) { // if the ray is inside the object, swap the indices and invert the normal to get the correct result
cosi = -cosi;
std::swap(etai, etat); n = -N;
}
float eta = etai / etat;
float k = 1 - eta*eta*(1 - cosi*cosi); float k = 1 - eta*eta*(1 - cosi*cosi);
return k < 0 ? Vec3f(0,0,0) : I*eta + n*(eta * cosi - sqrtf(k)); 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<Sphere> &spheres, Vec3f &hit, Vec3f &N, Material &material) {
@@ -125,12 +120,12 @@ void render(const std::vector<Sphere> &spheres, const std::vector<Light> &lights
std::vector<Vec3f> framebuffer(width*height); std::vector<Vec3f> framebuffer(width*height);
#pragma omp parallel for #pragma omp parallel for
for (size_t j = 0; j<height; j++) { for (size_t j = 0; j<height; j++) { // actual rendering loop
for (size_t i = 0; i<width; i++) { for (size_t i = 0; i<width; i++) {
float x = (i + 0.5) - width/2.; float dir_x = (i + 0.5) - width/2.;
float y = -(j + 0.5) + height/2.; // flips the image at the same time float dir_y = -(j + 0.5) + height/2.; // this flips the image at the same time
Vec3f dir = Vec3f(x, y, -height/(2.*tan(fov/2.))).normalize(); float dir_z = -height/(2.*tan(fov/2.));
framebuffer[i+j*width] = cast_ray(Vec3f(0,0,0), dir, spheres, lights); framebuffer[i+j*width] = cast_ray(Vec3f(0,0,0), Vec3f(dir_x, dir_y, dir_z).normalize(), spheres, lights);
} }
} }