The crucial step: casting the rays + ray/sphere intersection routine

autostereogram
Dmitry V. Sokolov 2019-01-20 12:15:18 +01:00
parent bd36c98573
commit 5806eb45e9
2 changed files with 38 additions and 3 deletions

BIN
out.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -5,14 +5,48 @@
#include <vector>
#include "geometry.h"
void render() {
struct Sphere {
Vec3f center;
float radius;
Sphere(const Vec3f &c, const float &r) : center(c), radius(r) {}
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;
}
};
Vec3f cast_ray(const Vec3f &orig, const Vec3f &dir, const Sphere &sphere) {
float sphere_dist = std::numeric_limits<float>::max();
if (!sphere.ray_intersect(orig, dir, sphere_dist)) {
return Vec3f(0.2, 0.7, 0.8); // background color
}
return Vec3f(0.4, 0.4, 0.3);
}
void render(const Sphere &sphere) {
const int width = 1024;
const int height = 768;
const int fov = M_PI/2.;
std::vector<Vec3f> framebuffer(width*height);
#pragma omp parallel for
for (size_t j = 0; j<height; j++) {
for (size_t i = 0; i<width; i++) {
framebuffer[i+j*width] = Vec3f(j/float(height),i/float(width), 0);
float x = (2*(i + 0.5)/(float)width - 1)*tan(fov/2.)*width/(float)height;
float y = -(2*(j + 0.5)/(float)height - 1)*tan(fov/2.);
Vec3f dir = Vec3f(x, y, -1).normalize();
framebuffer[i+j*width] = cast_ray(Vec3f(0,0,0), dir, sphere);
}
}
@ -28,7 +62,8 @@ void render() {
}
int main() {
render();
Sphere sphere(Vec3f(-3, 0, -16), 2);
render(sphere);
return 0;
}