Chapter 6: Antialiasing
This commit is contained in:
parent
0c01a876b0
commit
0e5ce7ec07
27
code/camera.h
Normal file
27
code/camera.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#ifndef CAMERA_H
|
||||||
|
#define CAMERA_H
|
||||||
|
|
||||||
|
#include "ray.h"
|
||||||
|
|
||||||
|
class camera
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
camera()
|
||||||
|
{
|
||||||
|
lower_left_corner = vec3(-2.0, -1.0, -1.0);
|
||||||
|
horizontal = vec3(4.0, 0.0, 0.0);
|
||||||
|
vertical = vec3(0.0, 2.0, 0.0);
|
||||||
|
origin = vec3(0.0, 0.0, 0.0);
|
||||||
|
}
|
||||||
|
ray get_ray(float u, float v)
|
||||||
|
{
|
||||||
|
return ray(origin, lower_left_corner + u * horizontal + v * vertical - origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 origin;
|
||||||
|
vec3 lower_left_corner;
|
||||||
|
vec3 horizontal;
|
||||||
|
vec3 vertical;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -1,48 +1,53 @@
|
|||||||
|
#include <float.h>
|
||||||
#include "rt_weekend.h"
|
#include "rt_weekend.h"
|
||||||
#include "ray.h"
|
#include "sphere.h"
|
||||||
|
#include "target_list.h"
|
||||||
|
#include "camera.h"
|
||||||
|
|
||||||
bool hit_sphere(const vec3 ¢er, float radius, const ray &r)
|
vec3 color(const ray &r, target *world)
|
||||||
{
|
{
|
||||||
vec3 oc = r.origin() - center;
|
hit_record rec;
|
||||||
float a = dot(r.direction(), r.direction());
|
if (world->hit(r, 0.0, MAXFLOAT, rec))
|
||||||
float b = 2.0 * dot(oc, r.direction());
|
{
|
||||||
float c = dot(oc, oc) - radius * radius;
|
return 0.5 * vec3(rec.normal.x() + 1, rec.normal.y() + 1, rec.normal.z() + 1);
|
||||||
float discriminant = b * b - 4 * a * c;
|
}
|
||||||
|
else
|
||||||
return (discriminant > 0);
|
{
|
||||||
}
|
vec3 unit_direction = unit_vector(r.direction());
|
||||||
|
float t = 0.5 * (unit_direction.y() + 1.0);
|
||||||
vec3 color (const ray &r)
|
return (1.0 - t) * vec3(1.0, 1.0, 1.0) + t * vec3(0.5, 0.7, 1.0);
|
||||||
{
|
}
|
||||||
if (hit_sphere(vec3(0, 0, -1), 0.5, r))
|
|
||||||
return vec3(1, 0, 0);
|
|
||||||
vec3 unit_direction = unit_vector(r.direction());
|
|
||||||
float t = 0.5 * (unit_direction.y() + 1.0);
|
|
||||||
return (1.0 - t) * vec3(1.0, 1.0, 1.0) + t * vec3(0.5, 0.7, 1.0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
void
|
void
|
||||||
PluginUpdateAndRender(plugin_offscreen_buffer *Buffer)
|
PluginUpdateAndRender(plugin_offscreen_buffer *Buffer)
|
||||||
{
|
{
|
||||||
|
int ns = 1;
|
||||||
int Pitch = Buffer->Pitch;
|
int Pitch = Buffer->Pitch;
|
||||||
uint8_t *Row = (uint8_t *)Buffer->Memory;
|
uint8_t *Row = (uint8_t *)Buffer->Memory;
|
||||||
|
|
||||||
vec3 lower_left_corner(-2.0, -1.0, -1.0);
|
target *list[2];
|
||||||
vec3 horizontal(4.0, 0.0, 0.0);
|
list[0] = new sphere(vec3(0, 0, -1), 0.5);
|
||||||
vec3 vertical(0.0, 2.0, 0.0);
|
list[1] = new sphere(vec3(0, -100.5, -1), 100);
|
||||||
vec3 origin(0.0, 0.0, 0.0);
|
target *world = new target_list(list, 2);
|
||||||
|
camera cam;
|
||||||
|
|
||||||
for(int j = Buffer->Height - 1; j >= 0; j--)
|
for(int j = Buffer->Height - 1; j >= 0; j--)
|
||||||
{
|
{
|
||||||
uint32_t *Pixel = (uint32_t *)Row;
|
uint32_t *Pixel = (uint32_t *)Row;
|
||||||
for(int i = 0; i < Buffer->Width; i++)
|
for(int i = 0; i < Buffer->Width; i++)
|
||||||
{
|
{
|
||||||
float u = float(i) / float(Buffer->Width);
|
vec3 col(0, 0, 0);
|
||||||
float v = float(j) / float(Buffer->Height);
|
for (int s = 0; s < ns; s++)
|
||||||
ray r(origin, lower_left_corner + u * horizontal + v * vertical);
|
{
|
||||||
vec3 col = color(r);
|
float u = float(i + drand48()) / float(Buffer->Width);
|
||||||
|
float v = float(j + drand48()) / float(Buffer->Height);
|
||||||
|
ray r = cam.get_ray(u, v);
|
||||||
|
vec3 p = r.point_at_parameter(2.0);
|
||||||
|
col += color(r, world);
|
||||||
|
}
|
||||||
|
col /= float(ns);
|
||||||
int ir = int(255.99 * col[0]);
|
int ir = int(255.99 * col[0]);
|
||||||
int ig = int(255.99 * col[1]);
|
int ig = int(255.99 * col[1]);
|
||||||
int ib = int(255.99 * col[2]);
|
int ib = int(255.99 * col[2]);
|
||||||
|
|||||||
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
const char *WindowTitle = "Ray Tracing in a Weekend";
|
const char *WindowTitle = "Ray Tracing in a Weekend";
|
||||||
|
|
||||||
const uint32_t TARGET_FRAME_RATE = 15;
|
const uint32_t TARGET_FRAME_RATE = 10;
|
||||||
const uint32_t TICKS_PER_FRAME = 1000 / TARGET_FRAME_RATE;
|
const uint32_t TICKS_PER_FRAME = 1000 / TARGET_FRAME_RATE;
|
||||||
const uint32_t WINDOW_WIDTH = 500;
|
const uint32_t WINDOW_WIDTH = 500;
|
||||||
const uint32_t WINDOW_HEIGHT = 250;
|
const uint32_t WINDOW_HEIGHT = 250;
|
||||||
|
|||||||
46
code/sphere.h
Normal file
46
code/sphere.h
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#ifndef SPHERE_H
|
||||||
|
#define SPHERE_H
|
||||||
|
|
||||||
|
#include "target.h"
|
||||||
|
|
||||||
|
class sphere: public target
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
sphere() {};
|
||||||
|
sphere(vec3 cen, float r) : center(cen), radius(r) {};
|
||||||
|
virtual bool hit(const ray &r, float t_min, float t_max, hit_record &rec) const;
|
||||||
|
vec3 center;
|
||||||
|
float radius;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool sphere::hit(const ray &r, float t_min, float t_max, hit_record &rec) const
|
||||||
|
{
|
||||||
|
vec3 oc = r.origin() - center;
|
||||||
|
float a = dot(r.direction(), r.direction());
|
||||||
|
float b = dot(oc, r.direction());
|
||||||
|
float c = dot(oc, oc) - radius * radius;
|
||||||
|
float discriminant = b * b - a * c;
|
||||||
|
|
||||||
|
if (discriminant > 0)
|
||||||
|
{
|
||||||
|
float temp = (-b - sqrt(discriminant)) / a;
|
||||||
|
if (temp < t_max && temp > t_min)
|
||||||
|
{
|
||||||
|
rec.t = temp;
|
||||||
|
rec.p = r.point_at_parameter(rec.t);
|
||||||
|
rec.normal = (rec.p - center) / radius;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
temp = (-b + sqrt(discriminant)) / a;
|
||||||
|
if (temp < t_max && temp > t_min)
|
||||||
|
{
|
||||||
|
rec.t = temp;
|
||||||
|
rec.p = r.point_at_parameter(rec.t);
|
||||||
|
rec.normal = (rec.p - center) / radius;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
19
code/target.h
Normal file
19
code/target.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#ifndef TARGET_H
|
||||||
|
#define TARGET_H
|
||||||
|
|
||||||
|
#include "ray.h"
|
||||||
|
|
||||||
|
struct hit_record
|
||||||
|
{
|
||||||
|
float t;
|
||||||
|
vec3 p;
|
||||||
|
vec3 normal;
|
||||||
|
};
|
||||||
|
|
||||||
|
class target
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual bool hit(const ray &r, float t_min, float t_max, hit_record &rec) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
33
code/target_list.h
Normal file
33
code/target_list.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#ifndef TARGETLIST_H
|
||||||
|
#define TARGETLIST_H
|
||||||
|
|
||||||
|
#include "target.h"
|
||||||
|
|
||||||
|
class target_list: public target
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
target_list() {}
|
||||||
|
target_list(target **l, int n) { list = l; list_size = n; }
|
||||||
|
virtual bool hit(const ray &r, float t_min, float t_max, hit_record &rec) const;
|
||||||
|
target **list;
|
||||||
|
int list_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool target_list::hit(const ray &r, float t_min, float t_max, hit_record &rec) const
|
||||||
|
{
|
||||||
|
hit_record temp_rec;
|
||||||
|
bool hit_anything = false;
|
||||||
|
double closest_so_far = t_max;
|
||||||
|
for (int i = 0; i < list_size; i++)
|
||||||
|
{
|
||||||
|
if (list[i]->hit(r, t_min, closest_so_far, temp_rec))
|
||||||
|
{
|
||||||
|
hit_anything = true;
|
||||||
|
closest_so_far = temp_rec.t;
|
||||||
|
rec = temp_rec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return hit_anything;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -32,10 +32,12 @@ public:
|
|||||||
{
|
{
|
||||||
return sqrt(e[0] * e[0] + e[1] * e[1] + e[2] * e[2]);
|
return sqrt(e[0] * e[0] + e[1] * e[1] + e[2] * e[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline float squared_length() const
|
inline float squared_length() const
|
||||||
{
|
{
|
||||||
return e[0] * e[0] + e[1] * e[1] + e[2] * e[2];
|
return e[0] * e[0] + e[1] * e[1] + e[2] * e[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void make_unit_vector();
|
inline void make_unit_vector();
|
||||||
|
|
||||||
float e[3];
|
float e[3];
|
||||||
@ -88,7 +90,7 @@ inline vec3 operator*(float t, const vec3 &v)
|
|||||||
|
|
||||||
inline vec3 operator/(vec3 v, float t)
|
inline vec3 operator/(vec3 v, float t)
|
||||||
{
|
{
|
||||||
return vec3(v.e[0]/t, v.e[1]/t, v.e[2]/t);
|
return vec3(v.e[0] / t, v.e[1] / t, v.e[2] / t);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline vec3 operator*(const vec3 &v, float t)
|
inline vec3 operator*(const vec3 &v, float t)
|
||||||
|
|||||||
Reference in New Issue
Block a user