From b6b58d8e66a24a7769c019457991440b844dfa90 Mon Sep 17 00:00:00 2001 From: Raymond Wan Date: Fri, 24 May 2019 01:16:08 -0400 Subject: [PATCH] Add mesh transform --- TODO.txt | 4 ++-- src/camera.cpp | 2 +- src/global.h | 6 +++--- src/mesh.cpp | 11 +++++++++++ src/mesh.h | 5 +++++ src/primitive.cpp | 42 ++++++++++++++++++++++++------------------ src/render.cpp | 5 ++++- src/world.cpp | 43 +++++++++++++++++++++++-------------------- 8 files changed, 73 insertions(+), 45 deletions(-) diff --git a/TODO.txt b/TODO.txt index de057ff..c04c087 100644 --- a/TODO.txt +++ b/TODO.txt @@ -6,10 +6,10 @@ Build: Uncategorized: [ ] 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 + [x] Add transform to Mesh @done (19-05-24 01:02) + [x] Render suzanne @done (19-05-24 01:02) Miscellaneous: [x] Fix off by one error in tile compositing @BUG @done (19-05-23 13:31) diff --git a/src/camera.cpp b/src/camera.cpp index edcd2f2..14b94b7 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -36,7 +36,7 @@ Camera camera_init_default() { rwm_v3_init(0.0, 0.0, 0.0), // position rwm_v3_init(0.0, 0.0, -1.0), // target rwm_v3_init(0.0, 1.0, 0.0), // up - 90.0f, // fov + 43.0f, // fov 2.0f // aperature ); } diff --git a/src/global.h b/src/global.h index 5425a6b..497e010 100644 --- a/src/global.h +++ b/src/global.h @@ -9,11 +9,11 @@ #define BIAS 0.0001f #define REFRACT_BIAS 0.00001f -#define MAX_DEPTH 5 +#define MAX_DEPTH 3 #define SAMPLES_PER_PIXEL 4 -#define USE_GLOBAL_ILLUMINATION 0 -#define NUM_PT_SAMPLES 32 +#define USE_GLOBAL_ILLUMINATION 1 +#define NUM_PT_SAMPLES 16 #define TILE_X 16 #define TILE_Y 16 diff --git a/src/mesh.cpp b/src/mesh.cpp index 73e9829..4f39efe 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -221,3 +221,14 @@ Mesh mesh_make_plane() { return result; } + +void mesh_attach_transform(Mesh *mesh, Transform obj_world_tr) { + mesh->obj_world_tr = obj_world_tr; + for (int i = 0; i < mesh->v.size(); i++) { + mesh->v[i] = rwtr_pt3_apply(&mesh->obj_world_tr, mesh->v[i]); + } + + for (int i = 0; i < mesh->n.size(); i++) { + mesh->n[i] = rwtr_n3_apply(&mesh->obj_world_tr, mesh->n[i]); + } +} diff --git a/src/mesh.h b/src/mesh.h index 3c5e15d..20046be 100644 --- a/src/mesh.h +++ b/src/mesh.h @@ -22,16 +22,19 @@ typedef struct Mesh { std::vector v_idx; std::vector uv_idx; std::vector n_idx; + std::vector t_idx; // Raw data from the OBJ file std::vector v; std::vector uv; std::vector n; + std::vector t; // Processed face data, index aligned and for GL_ARRAY_BUFFER rendering // NOTE(ray): This is useful for debugging, but we'll be using the packed data // most of the time std::vector buf_v; std::vector buf_uv; std::vector buf_n; + std::vector buf_t; // For EBO float *packed; @@ -47,4 +50,6 @@ Rect3 mesh_get_bounds(Mesh *m); Mesh mesh_make_plane(); +void mesh_attach_transform(Mesh *mesh, Transform obj_world_tr); + #endif diff --git a/src/primitive.cpp b/src/primitive.cpp index cc0ee24..0b51c8c 100644 --- a/src/primitive.cpp +++ b/src/primitive.cpp @@ -144,27 +144,33 @@ bool disk_intersect(Plane *plane, float radius, Ray *r, IntersectInfo *out_ii) { return false; } +bool mesh_tri_intersect(Mesh *mesh, int f_idx, Ray *r, IntersectInfo *out_ii) { + Triangle triangle; + triangle.v0 = mesh->v[mesh->v_idx[f_idx * 3]]; + triangle.v1 = mesh->v[mesh->v_idx[f_idx * 3 + 1]]; + triangle.v2 = mesh->v[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 = mesh->uv[mesh->uv_idx[f_idx * 3]]; + Vec2 uv1 = mesh->uv[mesh->uv_idx[f_idx * 3 + 1]]; + Vec2 uv2 = mesh->uv[mesh->uv_idx[f_idx * 3 + 2]]; + out_ii->tex_coord = (triangle.w * uv0) + (triangle.u * uv1) + (triangle.v * uv2); + Vec3 n0 = mesh->n[mesh->n_idx[f_idx * 3]]; + Vec3 n1 = mesh->n[mesh->n_idx[f_idx * 3 + 1]]; + Vec3 n2 = mesh->n[mesh->n_idx[f_idx * 3 + 2]]; + out_ii->normal = (triangle.w * n0) + (triangle.u * n1) + (triangle.v * n2); + return true; + } + return false; +} + bool mesh_intersect(Mesh *mesh, Ray *r, IntersectInfo *out_ii) { bool did_intersect = false; for (int j = 0; j < mesh->f.size(); j++) { - Triangle triangle; - triangle.v0 = mesh->v[mesh->v_idx[j * 3]]; - triangle.v1 = mesh->v[mesh->v_idx[j * 3 + 1]]; - triangle.v2 = mesh->v[mesh->v_idx[j * 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 = mesh->uv[mesh->uv_idx[j * 3]]; - Vec2 uv1 = mesh->uv[mesh->uv_idx[j * 3 + 1]]; - Vec2 uv2 = mesh->uv[mesh->uv_idx[j * 3 + 2]]; - out_ii->tex_coord = (triangle.w * uv0) + (triangle.u * uv1) + (triangle.v * uv2); - Vec3 n0 = mesh->n[mesh->n_idx[j * 3]]; - Vec3 n1 = mesh->n[mesh->n_idx[j * 3 + 1]]; - Vec3 n2 = mesh->n[mesh->n_idx[j * 3 + 2]]; - out_ii->normal = (triangle.w * n0) + (triangle.u * n1) + (triangle.v * n2); - + if (mesh_tri_intersect(mesh, j, r, out_ii)) { did_intersect = true; } } diff --git a/src/render.cpp b/src/render.cpp index 5efbcd7..0576ab7 100644 --- a/src/render.cpp +++ b/src/render.cpp @@ -206,7 +206,10 @@ Vec3 cast_ray(World *world, Ray *r, int cur_depth) { } else { // "Skybox", just a gradient float t = 0.5f*(r->dir.y + 1.0f); - color = ((1.0f - t)*rwm_v3_init(1.0f, 1.0f, 1.0f) + t * rwm_v3_init(0.5f, 0.7f, 1.0f)) * 0.5f; + // NOTE(ray): Hack? Don't sample skybox if we're sampling indirect light + if (r->type != RT_GI) { + color = ((1.0f - t)*rwm_v3_init(1.0f, 1.0f, 1.0f) + t * rwm_v3_init(0.5f, 0.7f, 1.0f)) * 0.5f; + } } return color; } diff --git a/src/world.cpp b/src/world.cpp index f76faa0..e8383f4 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -8,28 +8,30 @@ void create_world(World *world) { 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_attach_transform(suz, rwtr_trs( + rwm_v3_init(-1.0,0.75,-0.80), + rwm_v3_init(0.5, 0.5, 0.5), + 1, 45.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); + mesh_attach_transform(plane, rwtr_trs( + rwm_v3_init(0.0,0.0,0.0), + rwm_v3_init(2.0,2.0,2.0), + 0, 0) + ); puts("Creating world..."); // world->spheres.push_back({rwm_v3_init(0,0.25,-0.8), 0.5}); // world->spheres.push_back({rwm_v3_init(-1,0.25,-0.5), 0.5}); world->spheres.push_back(sphere_create(rwm_v3_init(0.6,0.12,0.0), 0.25)); world->spheres.push_back(sphere_create(rwm_v3_init(0,0.25,-0.5), 0.5)); - // world->spheres.push_back({rwm_v3_init(1,0.25,-1), 0.5}); + world->spheres.push_back({rwm_v3_init(1,0.25,-1), 0.5}); // world->spheres.push_back({rwm_v3_init(-1,0.25,-1), 0.5}); // world->spheres.push_back({rwm_v3_init(-1,0.25,-2), 1.5}); - // world->sphere_materials.push_back({M_REFLECT, rwm_v3_init(1.0, 1.0, 1.0)}); world->sphere_materials.push_back({M_RR, rwm_v3_init(1.0, 1.0, 1.0), 1.55}); world->sphere_materials.push_back({M_DIFFUSE, rwm_v3_init(1.0, 0.0, 0.0)}); + world->sphere_materials.push_back({M_REFLECT, rwm_v3_init(1.0, 1.0, 1.0)}); // world->sphere_materials.push_back({M_DIFFUSE, rwm_v3_init(1.0, 1.0, 1.0)}); // world->planes.push_back({rwm_v3_init(0,-0.5,-1), rwm_v3_init(0,1.0,0)}); @@ -41,24 +43,25 @@ void create_world(World *world) { // rwm_v3_init(1,-1.0,-5), // rwm_v3_init(0,1.0,-5) // }); - // world->meshes.push_back(&suz); + world->meshes.push_back(suz); world->meshes.push_back(plane); // world->mesh_materials.push_back({M_REFLECT, rwm_v3_zero()}); + world->mesh_materials.push_back({M_DIFFUSE, rwm_v3_init(0.8, 0.8, 0.8), 0, false}); world->mesh_materials.push_back({M_DIFFUSE, rwm_v3_init(1.0, 1.0, 1.0), 0, true}); puts("Adding lights"); world->lights.push_back({ - LT_SPHERE, - rwm_v3_init(2.0, 2.0, 1.0), // position - rwm_v3_init(1.0f, 1.0f, 1.0f), // color - 300.0f, // intensity + LT_SPHERE, + rwm_v3_init(2.0, 2.0, 1.0), // position + rwm_v3_init(1.0f, 1.0f, 1.0f), // color + 100.0f, // intensity }); - // world->lights.push_back((Light) { - // LT_SPHERE, - // rwm_v3_init(-2.0, 2.0, -3.0), // position - // rwm_v3_init(0.0f, 0.0f, 1.0f), // color - // 600.0f, // intensity + // world->lights.push_back({ + // LT_SPHERE, + // rwm_v3_init(-2.0, 2.0, -3.0), // position + // rwm_v3_init(0.0f, 0.0f, 1.0f), // color + // 600.0f, // intensity // }); #if 1