diff --git a/tiny_bvh_fenster.cpp b/tiny_bvh_fenster.cpp index 851e7a3..7cd69c1 100644 --- a/tiny_bvh_fenster.cpp +++ b/tiny_bvh_fenster.cpp @@ -6,7 +6,7 @@ using namespace tinybvh; bvhvec4 triangles[259 /* level 3 */ * 6 * 2 * 49 * 3]{}; -int verts = 0, spheres = 0; +int verts = 0; BVH bvh; void sphere_flake( float x, float y, float z, float s, int d = 0 ) @@ -23,7 +23,6 @@ void sphere_flake( float x, float y, float z, float s, int d = 0 ) triangles[verts++] = p[i], triangles[verts++] = p[i + 8], triangles[verts++] = p[i + 1], triangles[verts++] = p[i + 1], triangles[verts++] = p[i + 9], triangles[verts++] = p[i + 8]; - spheres++; if (d < 3) sphere_flake( x + s * 1.55f, y, z, s * 0.5f, d + 1 ); if (d < 3) sphere_flake( x - s * 1.5f, y, z, s * 0.5f, d + 1 ); if (d < 3) sphere_flake( x, y + s * 1.5f, z, s * 0.5f, d + 1 ); @@ -48,12 +47,12 @@ void Tick( uint32_t* buf ) bvhvec3 right = normalize( cross( bvhvec3( 0, 1, 0 ), view ) ); bvhvec3 up = 0.8f * cross( view, right ), C = eye + 2 * view; bvhvec3 p1 = C - right + up, p2 = C + right + up, p3 = C - right - up; - // store primary rays in a buffer + // generate primary rays in a buffer int N = 0; Ray* rays = new Ray[SCRWIDTH * SCRHEIGHT * 16]; for (int y = 0; y < SCRHEIGHT; y++) for (int x = 0; x < SCRWIDTH; x++) { - for (int s = 0; s < 16; s++) + for (int s = 0; s < 16; s++) // 16 samples per pixel { float u = (float)(x * 4 + (s & 3)) / (SCRWIDTH * 4); float v = (float)(y * 4 + (s >> 2)) / (SCRHEIGHT * 4); @@ -61,7 +60,7 @@ void Tick( uint32_t* buf ) rays[N++] = Ray( eye, normalize( P - eye ) ); } } - // trace rays + // trace primary rays for (int i = 0; i < N; i++) bvh.Intersect( rays[i] ); // visualize result for (int i = 0, y = 0; y < SCRHEIGHT; y++) for (int x = 0; x < SCRWIDTH; x++) diff --git a/tiny_bvh_renderer.cpp b/tiny_bvh_renderer.cpp index e30e539..e3471fd 100644 --- a/tiny_bvh_renderer.cpp +++ b/tiny_bvh_renderer.cpp @@ -12,55 +12,43 @@ using namespace tinybvh; -#define SPHERE_COUNT 259 - -struct TriVertex { - TriVertex() = default; - TriVertex( bvhvec3 v ) : x( v.x ), y( v.y ), z( v.z ), dummy( 0 ) {} - float x, y, z, dummy; -}; -TriVertex triangles[SPHERE_COUNT * 6 * 98 * 3]; -int verts = 0, spheres = 0; +bvhvec4 triangles[259 * 6 * 98 * 3]; +int verts = 0, spheres = 259; // ASCII shading: https://stackoverflow.com/a/74186686 char level[92] = "`.-':_,^=;><+!rc*/z?sLTv)J7(|Fi{C}fI31tlu[neoZ5Yxjya]2ESwqkP6h9d4VpOGbUAKXHm8RD#$Bg0MNWQ%&@"; -void create_sphere( float x, float y, float z, float s ) +void sphere_flake( float x, float y, float z, float s, int d = 0 ) { + // procedural tesselated sphere flake object #define P(F,a,b,c) p[i+F*64]={(float)a ,(float)b,(float)c} bvhvec3 p[384], pos( x, y, z ), ofs( 3.5 ); for (int i = 0, u = 0; u < 8; u++) for (int v = 0; v < 8; v++, i++) P( 0, u, v, 0 ), P( 1, u, 0, v ), P( 2, 0, u, v ), - P( 3, u, v, 3 ), P( 4, u, 3, v ), P( 5, 3, u, v ); + P( 3, u, v, 7 ), P( 4, u, 7, v ), P( 5, 7, u, v ); for (int i = 0; i < 384; i++) p[i] = normalize( p[i] - ofs ) * s + pos; - for (int i = 0, side = 0; side < 6; side++, i += 8 ) + for (int i = 0, side = 0; side < 6; side++, i += 8) for (int u = 0; u < 7; u++, i++) for (int v = 0; v < 7; v++, i++) - triangles[verts++] = p[i], triangles[verts++] = p[i + 1], - triangles[verts++] = p[i + 8], triangles[verts++] = p[i + 1], + triangles[verts++] = p[i], triangles[verts++] = p[i + 8], + triangles[verts++] = p[i + 1], triangles[verts++] = p[i + 1], triangles[verts++] = p[i + 9], triangles[verts++] = p[i + 8]; -} - -void sphere_flake( float x, float y, float z, float s, int d = 0 ) -{ - spheres++; - create_sphere( x, y, z, s * 0.5f ); - if (d < 3) sphere_flake( x + s * 0.75f, y, z, s * 0.5f, d + 1 ); - if (d < 3) sphere_flake( x - s * 0.75f, y, z, s * 0.5f, d + 1 ); - if (d < 3) sphere_flake( x, y + s * 0.75f, z, s * 0.5f, d + 1 ); - if (d < 3) sphere_flake( x, x - s * 0.75f, z, s * 0.5f, d + 1 ); - if (d < 3) sphere_flake( x, y, z + s * 0.75f, s * 0.5f, d + 1 ); - if (d < 3) sphere_flake( x, y, z - s * 0.75f, s * 0.5f, d + 1 ); + if (d < 3) sphere_flake( x + s * 1.55f, y, z, s * 0.5f, d + 1 ); + if (d < 3) sphere_flake( x - s * 1.5f, y, z, s * 0.5f, d + 1 ); + if (d < 3) sphere_flake( x, y + s * 1.5f, z, s * 0.5f, d + 1 ); + if (d < 3) sphere_flake( x, x - s * 1.5f, z, s * 0.5f, d + 1 ); + if (d < 3) sphere_flake( x, y, z + s * 1.5f, s * 0.5f, d + 1 ); + if (d < 3) sphere_flake( x, y, z - s * 1.5f, s * 0.5f, d + 1 ); } int main() { // generate a sphere flake scene - sphere_flake( 0, 0, 0, 3 ); + sphere_flake( 0, 0, 0, 1.5f ); // build a BVH over the scene BVH bvh; bvh.Build( (bvhvec4*)triangles, verts / 3 ); - // trace 50x80 primary rays + // trace 120x50 primary rays bvhvec3 eye( -3.5f, -1.5f, -6 ), view = normalize( bvhvec3( 3, 1.5f, 5 ) ); bvhvec3 right = normalize( cross( bvhvec3( 0, 1, 0 ), view ) ); bvhvec3 up = 0.8f * cross( view, right ), C = eye + 2 * view; @@ -71,7 +59,7 @@ int main() { for( x = 0; x < 480; x += 4 ) { - for( sum = 0, s = 0; s < 16; s++ ) + for (sum = 0, s = 0; s < 16; s++) // 16 samples per 'pixel' { float u = (float)(x + (s & 3)) / 480.0f; float v = (float)(y + (s >> 2)) / 200.0f; @@ -89,4 +77,4 @@ int main() // all done. printf( "\nscene: %i spheres, %i triangles.\n", spheres, verts / 3 ); return 0; -} +} \ No newline at end of file