Skip to content
This repository has been archived by the owner on Nov 26, 2022. It is now read-only.

Commit

Permalink
Add more metrics and factor out bvhp intersection code
Browse files Browse the repository at this point in the history
  • Loading branch information
raywan committed May 23, 2019
1 parent 344273d commit b7d2e0f
Show file tree
Hide file tree
Showing 12 changed files with 103 additions and 46 deletions.
6 changes: 5 additions & 1 deletion TODO.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ Build:
[x] Create Windows entry point i.e. win32_main.cpp


Multithreading:
Uncategorized:
[ ] Fix off by one error in tile compositing @BUG
[ ] Tile size independent multithreaded rendering
Height and width are must be multiples of the tile size currently
[ ] Add transform to Mesh
[ ] Use memory arena for allocations
[ ] Render suzanne
[ ] Render Cornell Box
74 changes: 40 additions & 34 deletions src/bvh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,44 +175,50 @@ BVHNode *bvh_build(World *world) {
return root;
}

bool bvha_intersect(World *world, BVHPrimitive *bvhp, Ray *r, IntersectInfo *out_ii) {
switch (bvhp->type) {
case PT_SPHERE:
if (sphere_intersect(&(world->spheres[bvhp->p_idx]), r, out_ii)) {
rwth_atomic_add_i64((int64_t volatile *) &mtr_num_sphere_isect, 1);
out_ii->material = &world->sphere_materials[bvhp->p_idx];
return true;
}
break;
case PT_TRIANGLE: {
int f_idx = bvhp->f_idx;
Mesh *cur_mesh = world->meshes[bvhp->mesh_idx];
Triangle triangle;
triangle.v0 = cur_mesh->v[cur_mesh->v_idx[f_idx * 3]];
triangle.v1 = cur_mesh->v[cur_mesh->v_idx[f_idx * 3 + 1]];
triangle.v2 = cur_mesh->v[cur_mesh->v_idx[f_idx * 3 + 2]];
if (triangle_intersect(&triangle, r, out_ii)) {
rwth_atomic_add_i64((int64_t volatile *) &mtr_num_triangle_isect, 1);
// Get surface properties: texture coordinates, vertex normal
Vec3 col = {triangle.u , triangle.v, triangle.w};
out_ii->color = col;
Vec2 uv0 = cur_mesh->uv[cur_mesh->uv_idx[f_idx * 3]];
Vec2 uv1 = cur_mesh->uv[cur_mesh->uv_idx[f_idx * 3 + 1]];
Vec2 uv2 = cur_mesh->uv[cur_mesh->uv_idx[f_idx * 3 + 2]];
out_ii->tex_coord = (triangle.w * uv0) + (triangle.u * uv1) + (triangle.v * uv2);
Vec3 n0 = cur_mesh->n[cur_mesh->n_idx[f_idx * 3]];
Vec3 n1 = cur_mesh->n[cur_mesh->n_idx[f_idx * 3 + 1]];
Vec3 n2 = cur_mesh->n[cur_mesh->n_idx[f_idx * 3 + 2]];
out_ii->normal = (triangle.w * n0) + (triangle.u * n1) + (triangle.v * n2);
out_ii->material = &world->mesh_materials[bvhp->mesh_idx];
return true;
}
} break;
default:
return false;
}
return false;
}

bool bvh_intersect(World *world, BVHNode *root, Ray *orig_ray, IntersectInfo *out_ii, Ray *out_r) {
if (!root) return false;
if (bb_intersect(&root->bounds, orig_ray, out_ii)) {
if (root->leaf) {
BVHPrimitive bvhp = world->bvh_prims[root->prim_idx];
switch (bvhp.type) {
case PT_SPHERE:
if (sphere_intersect(&(world->spheres[bvhp.p_idx]), out_r, out_ii)) {
rwth_atomic_add_i64((int64_t volatile *) &mtr_num_sphere_isect, 1);
out_ii->material = &world->sphere_materials[bvhp.p_idx];
return true;
}
break;
case PT_TRIANGLE: {
int f_idx = bvhp.f_idx;
Mesh *cur_mesh = world->meshes[bvhp.mesh_idx];
Triangle triangle;
triangle.v0 = cur_mesh->v[cur_mesh->v_idx[f_idx * 3]];
triangle.v1 = cur_mesh->v[cur_mesh->v_idx[f_idx * 3 + 1]];
triangle.v2 = cur_mesh->v[cur_mesh->v_idx[f_idx * 3 + 2]];
if (triangle_intersect(&triangle, out_r, out_ii)) {
rwth_atomic_add_i64((int64_t volatile *) &mtr_num_triangle_isect, 1);
// Get surface properties: texture coordinates, vertex normal
Vec3 col = {triangle.u , triangle.v, triangle.w};
out_ii->color = col;
Vec2 uv0 = cur_mesh->uv[cur_mesh->uv_idx[f_idx * 3]];
Vec2 uv1 = cur_mesh->uv[cur_mesh->uv_idx[f_idx * 3 + 1]];
Vec2 uv2 = cur_mesh->uv[cur_mesh->uv_idx[f_idx * 3 + 2]];
out_ii->tex_coord = (triangle.w * uv0) + (triangle.u * uv1) + (triangle.v * uv2);
Vec3 n0 = cur_mesh->n[cur_mesh->n_idx[f_idx * 3]];
Vec3 n1 = cur_mesh->n[cur_mesh->n_idx[f_idx * 3 + 1]];
Vec3 n2 = cur_mesh->n[cur_mesh->n_idx[f_idx * 3 + 2]];
out_ii->normal = (triangle.w * n0) + (triangle.u * n1) + (triangle.v * n2);
out_ii->material = &world->mesh_materials[bvhp.mesh_idx];
return true;
}
} break;
}
return bvha_intersect(world, &world->bvh_prims[root->prim_idx], out_r, out_ii);
} else {
bool left_result = bvh_intersect(world, root->left, orig_ray, out_ii, out_r);
bool right_result = bvh_intersect(world, root->right, orig_ray, out_ii, out_r);
Expand Down
2 changes: 1 addition & 1 deletion src/global.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#define MAX_DEPTH 2
#define SAMPLES_PER_PIXEL 4

#define USE_GLOBAL_ILLUMINATION 1
#define USE_GLOBAL_ILLUMINATION 0
#define NUM_PT_SAMPLES 32

#define TILE_X 16
Expand Down
4 changes: 2 additions & 2 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ void *worker(void *t_arg) {
}

int main(int argc, char *argv[]) {
print_run_info();

rwtm_init();
mtr_start_time = rwtm_now();

Expand All @@ -52,8 +54,6 @@ int main(int argc, char *argv[]) {
}
}

print_run_info();

Camera camera;
if (camera_shot == 0) {
#if 0
Expand Down
4 changes: 3 additions & 1 deletion src/mesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
#include <stdio.h>
#include <sstream>
#include <string>
#include <rw/rw_math.h>
#include <assert.h>
#include <set>

#include <rw/rw_math.h>
#include <rw/rw_transform.h>

using namespace std;

// TODO(ray): Remove any use of std::vector!!!!!!!!!!!!!!!!
Expand Down
3 changes: 3 additions & 0 deletions src/mesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include <vector>
#include <rw/rw_math.h>
#include <rw/rw_transform.h>

#define NUM_PACKED_ELEMENTS 8

Expand Down Expand Up @@ -36,6 +37,8 @@ typedef struct Mesh {
float *packed;

FaceFormat format;

Transform obj_world_tr;
} Mesh;

uint8_t load_obj(Mesh *out_mesh, const char *obj_path, bool pack_data);
Expand Down
27 changes: 26 additions & 1 deletion src/metrics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,20 @@
#include <stdio.h>
#include <stdint.h>
#include "global.h"
#include "ray.h"

#define RWTM_IMPLEMENTATION
#include <rw/rw_time.h>
#define RWTH_IMPLEMENTATION
#include <rw/rw_th.h>

// Metrics
char *output_name;
uint64_t mtr_start_time;
uint64_t mtr_num_rays;
uint64_t mtr_num_primary_rays;
uint64_t mtr_num_gi_rays;
uint64_t mtr_num_other_rays;
uint64_t mtr_num_sphere_tests;
uint64_t mtr_num_sphere_isect;
uint64_t mtr_num_plane_tests;
Expand All @@ -36,12 +42,31 @@ void print_run_info() {
}

void print_post_run_metrics() {
printf("Render time (rwtm): %fs\n", rwtm_to_sec(rwtm_since(mtr_start_time)));
printf("Render time (rwtm): %fs\n\n", rwtm_to_sec(rwtm_since(mtr_start_time)));
printf("Total number of rays: %llu\n", mtr_num_rays);
printf("Total number of primary rays: %llu\n", mtr_num_primary_rays);
printf("Total number of GI rays: %llu\n", mtr_num_gi_rays);
printf("Total number of other rays: %llu\n\n", mtr_num_other_rays);

printf("Total number of sphere tests: %llu\n", mtr_num_sphere_tests);
printf("Total number of sphere intersections: %llu\n", mtr_num_sphere_isect);
printf("Total number of plane tests: %llu\n", mtr_num_plane_tests);
printf("Total number of plane intersections: %llu\n", mtr_num_plane_isect);
printf("Total number of triangle tests: %llu\n", mtr_num_triangle_tests);
printf("Total number of triangle intersections: %llu\n", mtr_num_triangle_isect);
}

void record_ray_metric(Ray *r) {
rwth_atomic_add_i64((int64_t volatile *) &mtr_num_rays, 1);
switch (r->type) {
case RT_CAMERA:
rwth_atomic_add_i64((int64_t volatile *) &mtr_num_primary_rays, 1);
break;
case RT_GI:
rwth_atomic_add_i64((int64_t volatile *) &mtr_num_gi_rays, 1);
break;
default:
rwth_atomic_add_i64((int64_t volatile *) &mtr_num_other_rays, 1);
break;
}
}
5 changes: 5 additions & 0 deletions src/metrics.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@
#define __METRICS_H__

#include <stdint.h>
#include "ray.h"

extern char *output_name;
extern uint64_t mtr_start_time;
extern uint64_t mtr_num_rays;
extern uint64_t mtr_num_primary_rays;
extern uint64_t mtr_num_gi_rays;
extern uint64_t mtr_num_other_rays;
extern uint64_t mtr_num_sphere_tests;
extern uint64_t mtr_num_sphere_isect;
extern uint64_t mtr_num_plane_tests;
Expand All @@ -15,5 +19,6 @@ extern uint64_t mtr_num_triangle_isect;

void print_run_info();
void print_post_run_metrics();
void record_ray_metric(Ray *r);

#endif
1 change: 1 addition & 0 deletions src/ray.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ enum RayType {
RT_SHADOW,
RT_REFLECT,
RT_REFRACT,
RT_GI,
};

struct Ray {
Expand Down
8 changes: 4 additions & 4 deletions src/render.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
#include <math.h>

#include <rw/rw_math.h>
#define RWTH_IMPLEMENTATION
#include <rw/rw_th.h>

#include "global.h"
#include "texture.h"
#include "utils.h"
#include "metrics.h"
#include "bvh.h"

#define USE_BVH 1

std::default_random_engine generator;
std::uniform_real_distribution<float> distribution(0, 1);
std::uniform_real_distribution<float> spp_distribution(0, 1);
Expand Down Expand Up @@ -83,7 +83,7 @@ void calculate_light_contribution(Light *l, IntersectInfo *ii, Vec3 *out_light_d

Vec3 cast_ray(World *world, Ray *r, int cur_depth) {
if (cur_depth > MAX_DEPTH) return rwm_v3_zero();

record_ray_metric(r);
Vec3 color = rwm_v3_zero();
IntersectInfo ii;
if (trace(world, r, &ii)) {
Expand Down Expand Up @@ -133,6 +133,7 @@ Vec3 cast_ray(World *world, Ray *r, int cur_depth) {
ii.hit_point + sample_normal_space * BIAS,
sample_normal_space
);
sample_ray.type = RT_GI;
indirect_lighting += r1 * rwm_v3_scalar_div(cast_ray(world, &sample_ray, cur_depth+1), pdf);
}
indirect_lighting = rwm_v3_scalar_div(indirect_lighting, (float) NUM_PT_SAMPLES);
Expand Down Expand Up @@ -221,7 +222,6 @@ void render(WorkerData *data, Tile t) {
int y = (int) t.top_right.y + TILE_Y - 1 - i;
Vec3 color = rwm_v3_zero();
for (int s = 0; s < SAMPLES_PER_PIXEL; s++) {
rwth_atomic_add_i64((int64_t volatile *) &mtr_num_primary_rays, 1);
float s1 = SAMPLES_PER_PIXEL > 1 ? spp_distribution(generator) : 0;
float s2 = SAMPLES_PER_PIXEL > 1 ? spp_distribution(generator) : 0;
Ray r = camera_get_ray(data->camera, x+s1, y+s2);
Expand Down
6 changes: 4 additions & 2 deletions src/win32_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include <rw/rw_time.h>
#define RWM_IMPLEMENTATION
#include <rw/rw_math.h>
#define RWTR_IMPLEMENTATION
#include <rw/rw_transform.h>

#include "render.h"
#include "mesh.h"
Expand Down Expand Up @@ -43,6 +45,8 @@ unsigned int worker(void *t_arg) {
}

int main(int argc, char *argv[]) {
print_run_info();

rwtm_init();
mtr_start_time = rwtm_now();

Expand All @@ -56,8 +60,6 @@ int main(int argc, char *argv[]) {
}
}

print_run_info();

Camera camera;
if (camera_shot == 0) {
#if 0
Expand Down
9 changes: 9 additions & 0 deletions src/world.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
#include "world.h"
#include <rw/rw_transform.h>

void create_world(World *world) {
printf("Loading OBJ files:\n\t");

Mesh *suz = new Mesh;
load_obj(suz, "suzanne.obj", false);
suz->obj_world_tr = rwtr_trs(
rwm_v3_init(0.0,1.0,-1.0),
rwm_v3_init(1.0,1.0,1.0),
-1, 0);
Mesh *plane = new Mesh;
*plane = mesh_make_plane();
plane->obj_world_tr = rwtr_trs(
rwm_v3_init(0.0,1.0,-1.0),
rwm_v3_init(1.0,1.0,1.0),
-1, 0);

puts("Creating world...");
// world->spheres.push_back({rwm_v3_init(0,0.25,-0.8), 0.5});
Expand Down

0 comments on commit b7d2e0f

Please sign in to comment.