aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/camera.hpp2
-rw-r--r--include/rt.hpp12
-rw-r--r--include/vk-renderer.hpp50
-rw-r--r--shaders/compute.comp41
-rw-r--r--src/camera.cpp6
-rw-r--r--src/main.cpp110
6 files changed, 113 insertions, 108 deletions
diff --git a/include/camera.hpp b/include/camera.hpp
index f1b199a..858833b 100644
--- a/include/camera.hpp
+++ b/include/camera.hpp
@@ -17,7 +17,7 @@ class camera {
ray get_ray(double u, double v) const;
point3 position;
- double lens_radius;
+ float lens_radius;
float viewport_width;
float viewport_height;
diff --git a/include/rt.hpp b/include/rt.hpp
index 1961d35..09cf1b0 100644
--- a/include/rt.hpp
+++ b/include/rt.hpp
@@ -29,12 +29,12 @@ inline float clamp(float x, float min, float max) {
#include "vec3.hpp"
#include "ray.hpp"
#include "color.hpp"
-#include "sphere.hpp"
+// #include "sphere.hpp"
#include "camera.hpp"
-#include "material.hpp"
-#include "lambertian.hpp"
-#include "metal.hpp"
-#include "dielectric.hpp"
-#include "hittable_list.hpp"
+// #include "material.hpp"
+// #include "lambertian.hpp"
+// #include "metal.hpp"
+// #include "dielectric.hpp"
+// #include "hittable_list.hpp"
#endif // !__RT_HPP_
diff --git a/include/vk-renderer.hpp b/include/vk-renderer.hpp
index 2e996c8..311b3e5 100644
--- a/include/vk-renderer.hpp
+++ b/include/vk-renderer.hpp
@@ -12,34 +12,46 @@ enum MATERIAL_TYPE: uint32_t {
DIELECTRIC,
};
+struct material {
+ color albedo;
+ float fuzz;
+ float ior;
+ uint32_t type;
+ uint32_t padding;
+};
+
+struct sphere {
+ vec3 position;
+ material mat;
+ float radius;
+ float padding[3];
+};
+
struct input_data {
color sky_color;
color ground_color;
- vec3 camera_pos;
- uint32_t samples_per_pixel;
- float viewport_width;
- float viewport_height;
- float proj_plane_distance;
+ struct camera {
+ vec3 position;
+ vec3 up;
+ vec3 right;
+ vec3 forward;
+ float viewport_width;
+ float viewport_height;
+ float lens_radius;
+ float focus_distance;
+ } cam;
- float random_numbers[200];
+ float random_offset[200];
+ float random_disk[200];
vec3 random_in_sphere[1000];
- struct sphere {
- vec3 position;
- struct material {
- color albedo;
- float fuzz;
- float ior;
- uint32_t type;
- uint32_t padding;
- } material;
- float radius;
- float padding[3];
- } spheres[5];
+ sphere spheres[512];
uint32_t max_bounce;
- float padding[3];
+ uint32_t samples_per_pixel;
+
+ float padding[2];
};
struct path_tracer_data {
diff --git a/shaders/compute.comp b/shaders/compute.comp
index 92fae9d..83302b9 100644
--- a/shaders/compute.comp
+++ b/shaders/compute.comp
@@ -30,24 +30,31 @@ struct sphere {
float[3] padding;
};
-layout(set = 0, binding = 0) buffer Inputs {
- vec4 sky_color;
- vec4 ground_color;
- vec4 camera_pos;
-
- uint samples_per_pixel;
+struct camera {
+ vec4 position;
+ vec4 up;
+ vec4 right;
+ vec4 forward;
float viewport_width;
float viewport_height;
- float proj_plane_distance;
+ float lens_radius;
+ float focus_distance;
+};
- float[200] random_numbers;
+layout(set = 0, binding = 0) buffer Inputs {
+ vec4 sky_color;
+ vec4 ground_color;
+ camera cam;
+ vec2[100] random_offset;
+ vec2[100] random_disk;
vec4[1000] random_in_sphere;
- sphere[5] spheres;
+ sphere[512] spheres;
uint max_bounce;
- float [3] padding;
+ uint samples_per_pixel;
+ float [2] padding;
vec4[] image;
};
@@ -105,7 +112,7 @@ bool hit_spheres(ray r, float min_t, float max_t, out hit_info info) {
float closest_t = max_t;
hit_info temp_info;
bool hit = false;
- for (uint sphere_index = 0; sphere_index < 5; sphere_index++) {
+ for (uint sphere_index = 0; sphere_index < 512; sphere_index++) {
if (hit_sphere(spheres[sphere_index], r, min_t, closest_t, temp_info)) {
info = temp_info;
closest_t = temp_info.t;
@@ -199,15 +206,19 @@ void main() {
uint height = gl_NumWorkGroups.y;
vec2 uv = vec2(float(x) / (width - 1), 1.0 - (float(y) / (height - 1)));
- vec3 first = camera_pos.xyz - vec3(viewport_width / 2.0, viewport_height / 2.0, proj_plane_distance);
+ vec3 horizontal = cam.focus_distance * cam.right.xyz * cam.viewport_width;
+ vec3 vertical = cam.focus_distance * cam.up.xyz * cam.viewport_height;
+ vec3 first = cam.position.xyz - horizontal / 2.0 - vertical / 2.0 + cam.focus_distance * cam.forward.xyz;
image[y * width + x] = vec4(0.0);
for (uint sample_index = 0; sample_index < samples_per_pixel; sample_index++) {
- vec2 jittered_uvs = uv + vec2(random_numbers[sample_index * 2] / (width - 1), random_numbers[sample_index * 2 + 1] / (height - 1));
- vec3 proj_plane_pos = first + vec3(jittered_uvs.x * viewport_width, jittered_uvs.y * viewport_height, 0.0);
+ vec2 jittered_uvs = uv + vec2(random_disk[sample_index].x / (width - 1), random_disk[sample_index].y / (height - 1));
+ vec2 lens_disk = random_disk[sample_index] * cam.lens_radius;
+ vec3 offset = lens_disk.x * cam.right.xyz + lens_disk.y * cam.up.xyz;
+ vec3 proj_plane_pos = first + jittered_uvs.x * horizontal + jittered_uvs.y * vertical;
- image[y * width + x] += ray_color(ray(camera_pos.xyz, proj_plane_pos - camera_pos.xyz), sample_index);
+ image[y * width + x] += ray_color(ray(cam.position.xyz + offset, proj_plane_pos - cam.position.xyz - offset), sample_index);
}
float spp_scale = (1.0 / samples_per_pixel);
diff --git a/src/camera.cpp b/src/camera.cpp
index 592f3d5..c7e2e35 100644
--- a/src/camera.cpp
+++ b/src/camera.cpp
@@ -11,9 +11,9 @@ camera::camera(
double focus_dist
) : position(position), lens_radius(aperture / 2.0) {
- forward = (position - target).unit();
- right = vec3{ 0.0, 1.0, 0.0 }.cross(forward).unit();
- up = forward.cross(right).unit();
+ forward = (target - position).unit();
+ right = forward.cross(vec3{ 0.0, 1.0, 0.0 }).unit();
+ up = right.cross(forward).unit();
auto h = tan(deg_to_rad(v_fov) / 2.0);
viewport_height = 2.0 * h;
diff --git a/src/main.cpp b/src/main.cpp
index 66b1f6a..af8334f 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -10,11 +10,12 @@
color ground_color { 1.0, 1.0, 1.0 };
color sky_color { 0.5, 0.7, 1.0 };
-hittable_list random_scene() {
- hittable_list world;
+void random_scene(sphere *world) {
+ material ground_material = { { 0.5, 0.5, 0.5 } };
+ ground_material.type = MATERIAL_TYPE::LAMBERTIAN;
+ world[0] = sphere{ { 0,-1000,0 }, ground_material, 1000 };
- auto ground_material = std::make_shared<lambertian>(color{ 0.5, 0.5, 0.5 });
- world.add(std::make_shared<sphere>(point3{ 0,-1000,0 }, 1000, ground_material));
+ uint32_t world_sphere_index = 1;
for (int a = -11; a < 11; a++) {
for (int b = -11; b < 11; b++) {
@@ -22,59 +23,44 @@ hittable_list random_scene() {
point3 center(a + 0.9 * randd(), 0.2, b + 0.9 * randd());
if ((center - point3{ 4, 0.2, 0 }).length() > 0.9) {
- std::shared_ptr<material> sphere_material;
+ material sphere_material = {};
if (choose_mat < 0.8) {
// diffuse
- auto albedo = color::random() * color::random();
- sphere_material = std::make_shared<lambertian>(albedo);
- world.add(std::make_shared<sphere>(center, 0.2, sphere_material));
+ sphere_material.albedo = color::random() * color::random();
+ sphere_material.type = MATERIAL_TYPE::LAMBERTIAN;
} else if (choose_mat < 0.95) {
// metal
- auto albedo = color::random(0.5, 1);
- auto fuzz = randd(0, 0.5);
- sphere_material = std::make_shared<metal>(albedo, fuzz);
- world.add(std::make_shared<sphere>(center, 0.2, sphere_material));
+ sphere_material.albedo = color::random(0.5, 1);
+ sphere_material.fuzz = randd(0, 0.5);
+ sphere_material.type = MATERIAL_TYPE::METAL;
} else {
// glass
- sphere_material = std::make_shared<dielectric>(1.5);
- world.add(std::make_shared<sphere>(center, 0.2, sphere_material));
+ sphere_material.ior = 1.5;
+ sphere_material.type = MATERIAL_TYPE::DIELECTRIC;
}
+
+ world[world_sphere_index] = { center, sphere_material, 0.2 };
+ world_sphere_index++;
}
}
}
- auto material1 = std::make_shared<dielectric>(1.5);
- world.add(std::make_shared<sphere>(point3{ 0, 1, 0 }, 1.0, material1));
-
- auto material2 = std::make_shared<lambertian>(color{ 0.4, 0.2, 0.1 });
- world.add(std::make_shared<sphere>(point3{ -4, 1, 0 }, 1.0, material2));
-
- auto material3 = std::make_shared<metal>(color{ 0.7, 0.6, 0.5 }, 0.0);
- world.add(std::make_shared<sphere>(point3{ 4, 1, 0 }, 1.0, material3));
-
- return world;
-}
-
-color ray_color(ray& r, const hittable& world, uint32_t depth) {
- if (depth <= 0) {
- return color{};
- }
-
- struct hit_info info;
- if (world.hit(r, 0.001, infinity, info)) {
- color attenuation;
- ray scattered {};
+ material material1 = {};
+ material1.ior = 1.5;
+ material1.type = MATERIAL_TYPE::DIELECTRIC;
+ world[world_sphere_index] = { { 0, 1, 0 }, material1, 1.0 };
- if (info.mat_ptr->scatter(r, info, attenuation, scattered)) {
- return attenuation * ray_color(scattered, world, depth - 1);
- }
- return color{};
- }
+ material material2 = {};
+ material2.albedo = color{ 0.4, 0.2, 0.1 };
+ material2.type = MATERIAL_TYPE::LAMBERTIAN;
+ world[world_sphere_index + 1] = { { -4, 1, 0 }, material2, 1.0 };
- auto unit_dir = r.direction.unit();
- auto t = (unit_dir.y + 1.0) * 0.5;
- return lerp(ground_color, sky_color, t);
+ material material3 = {};
+ material3.albedo = color{ 0.7, 0.6, 0.5 };
+ material3.fuzz = 0.0;
+ material3.type = MATERIAL_TYPE::METAL;
+ world[world_sphere_index + 2] = { { 4, 1, 0 }, material3, 1.0 };
}
int main() {
@@ -82,38 +68,34 @@ int main() {
// Image dimensions
const float aspect_ratio = 16.0 / 9.0;
- // const float aspect_ratio = 1.0;
const size_t width = 1920;
const size_t height = width / aspect_ratio;
const uint32_t samples_per_pixel = 100;
const uint32_t max_depth = 100;
- // const vec3 camera_position{ 13.0, 2.0, 3.0 };
- const vec3 camera_position{ 0.0, 0.0, 0.0 };
- const vec3 camera_target{ 0.0, 0.0, 1.0 };
- const double aperture = 0.1;
- const double distance_to_focus = 10;
+ const vec3 camera_position{ 13.0, 2.0, 3.0 };
+ const vec3 camera_target{ 0.0, 0.0, 0.0 };
+ const float aperture = 0.1;
+ const float distance_to_focus = 10;
camera camera { camera_position, camera_target, 20.0, aspect_ratio, aperture, distance_to_focus };
struct input_data inputs = {
.sky_color = sky_color,
.ground_color = ground_color,
- .camera_pos = camera_position,
- .samples_per_pixel = samples_per_pixel,
- .viewport_width = 2.f * aspect_ratio,
- .viewport_height = 2.f,
- .proj_plane_distance = 1.f,
- .spheres = {
- { { -1.f, 0.f, -1.f }, { { 0.8f, 0.8f, 0.8f }, 0.3, 1.5, MATERIAL_TYPE::DIELECTRIC }, 0.5f },
- { { -1.f, 0.f, -1.f }, { { 0.8f, 0.8f, 0.8f }, 0.3, 1.5, MATERIAL_TYPE::DIELECTRIC }, -0.4f },
- { { 0.f, 0.f, -1.f }, { { 0.7f, 0.3f, 0.3f }, 0.0, 1.5, MATERIAL_TYPE::DIELECTRIC }, 0.5f },
- { { 1.f, 0.f, -1.f }, { { 0.8f, 0.6f, 0.2f }, 1.0, 0.0, MATERIAL_TYPE::METAL }, 0.5f },
- { { 0.f, -100.5f, -1.f }, { { 0.8f, 0.8f, 0.f }, 0.0, 0.0, MATERIAL_TYPE::LAMBERTIAN }, 100.f }
- },
+ .cam = { camera_position, camera.up, camera.right, camera.forward, camera.viewport_width, camera.viewport_height, camera.lens_radius, distance_to_focus },
+ .spheres = {},
.max_bounce = max_depth,
+ .samples_per_pixel = samples_per_pixel,
};
- for (size_t rand_number_index = 0; rand_number_index < samples_per_pixel * 2; rand_number_index++) {
- inputs.random_numbers[rand_number_index] = randd();
+ for (size_t rand_number_index = 0; rand_number_index < samples_per_pixel * 2; rand_number_index += 2) {
+ inputs.random_offset[rand_number_index] = randd();
+ inputs.random_offset[rand_number_index + 1] = randd();
+ }
+
+ for (size_t rand_number_index = 0; rand_number_index < samples_per_pixel * 2; rand_number_index += 2) {
+ vec3 random_unit_disk = random_in_unit_disk();
+ inputs.random_disk[rand_number_index] = random_unit_disk.x;
+ inputs.random_disk[rand_number_index + 1] = random_unit_disk.y;
}
for (size_t rand_number_index = 0; rand_number_index < max_depth * 10; rand_number_index++) {
@@ -121,7 +103,7 @@ int main() {
}
// World hittable objects
- hittable_list world = random_scene();
+ random_scene(inputs.spheres);
// PPM format header
std::cout << "P3\n" << width << '\n' << height << "\n255" << std::endl;