diff --git a/.gitignore b/.gitignore index 5086e3b..cb90211 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ *.cue *.ppm *.png +*.out diff --git a/main-saturn.cpp b/main-saturn.cpp index 8b5fba8..b7b4e0f 100644 --- a/main-saturn.cpp +++ b/main-saturn.cpp @@ -43,7 +43,7 @@ void put_pixel(int32_t x, int32_t y, const vec3& color) if (sx >= 320 || sx < 0 || sy >= 240 || sy < 0) return; - vdp2.vram.u16[512 * sy + sx] = rgb15(color); + vdp2.vram.u32[512 * sy + sx] = rgb24(color); } template @@ -101,16 +101,16 @@ void main_asdf() vdp2.reg.BGON = BGON__N0ON; vdp2.reg.CHCTLA = ( - CHCTLA__N0CHCN__32K_COLOR // 15 bits per pixel, RGB - //CHCTLA__N0CHCN__16M_COLOR // 24 bits per pixel + // CHCTLA__N0CHCN__32K_COLOR // 15 bits per pixel, RGB + CHCTLA__N0CHCN__16M_COLOR // 24 bits per pixel | CHCTLA__N0BMSZ__512x256_DOT | CHCTLA__N0BMEN__BITMAP_FORMAT ); vdp2.reg.MPOFN = MPOFN__N0MP(0); - constexpr s32 plane_size = 512 * 256 * 2; - fill(&vdp2.vram.u32[0x0 / 4], (1 << 31) | (1 << 15), plane_size); + constexpr s32 plane_size = 512 * 256 * 4; + fill(&vdp2.vram.u32[0x0 / 4], (1 << 31), plane_size); vdp2.reg.SCXIN0 = 0; vdp2.reg.SCXDN0 = 0; diff --git a/raytracing.cpp b/raytracing.cpp index 29c0e84..8a600d9 100644 --- a/raytracing.cpp +++ b/raytracing.cpp @@ -23,6 +23,7 @@ struct sphere { fp16_16 radius; vec3 color; fp16_16 specular; + fp16_16 reflective; }; enum class light_type { @@ -52,24 +53,28 @@ constexpr scene scene { 1, // radius {1, 0, 0}, // color 8, // specular + fp16_16(65536 * 0.2, fp_raw_tag{}) // reflective }, { {2, 0, 4}, 1, {0, 0, 1}, - 10 + 10, + fp16_16(65536 * 0.3, fp_raw_tag{}) }, { {-2, 0, 4}, fp16_16(1), {0, 1, 0}, 10, + fp16_16(65536 * 0.4, fp_raw_tag{}) }, { - {0, -61, 0}, - fp16_16(60), + {0, -31, 0}, + fp16_16(30), {1, 1, 0}, - 0 + 0, + fp16_16(65536 * 0.5, fp_raw_tag{}) } }, { // lights @@ -199,12 +204,18 @@ fp16_16 compute_lighting(const vec3& point, const vec3& normal, return intensity; } +constexpr inline vec3 reflect_ray(const vec3& r, const vec3& n) +{ + return n * fp16_16(2) * dot(n, r) - r; +} + static vec3 trace_ray ( const vec3& origin, const vec3& direction, const fp16_16 t_min, - const fp16_16 t_max + const fp16_16 t_max, + const int recursion_depth ) { auto [closest_t, closest_sphere] = closest_intersection(origin, direction, t_min, t_max); @@ -214,8 +225,21 @@ static vec3 trace_ray vec3 point = origin + direction * closest_t; vec3 normal = point - closest_sphere->center; normal = normal * (fp16_16(1) / length(normal)); - return closest_sphere->color * compute_lighting(point, normal, - -direction, closest_sphere->specular); + auto direction_neg = -direction; + auto intensity = compute_lighting(point, normal, direction_neg, closest_sphere->specular); + auto local_color = closest_sphere->color * intensity; + + const auto& reflective = closest_sphere->reflective; + if (recursion_depth <= 0 || reflective <= fp16_16(0)) { + return local_color; + } else { + auto reflected_ray = reflect_ray(direction_neg, normal); + auto reflected_color = trace_ray(point, reflected_ray, + fp16_16(128, fp_raw_tag{}), + fp_limits::max(), + recursion_depth - 1); + return local_color * (fp16_16(1) - reflective) + reflected_color * reflective; + } } } @@ -225,8 +249,8 @@ void render(int half, void (&put_pixel) (int32_t x, int32_t y, const vec3& c)) vec3 origin = vec3(0, 0, 0); - int x_low = half ? 0 : -(width/2); - int x_high = half ? (width/2) : 0; + int x_low = half ? 0 : -(320/2); + int x_high = half ? (320/2) : 0; //for (int x = -(width/2); x < (width/2); x++) { for (int x = x_low; x < x_high; x++) { @@ -234,7 +258,8 @@ void render(int half, void (&put_pixel) (int32_t x, int32_t y, const vec3& c)) vec3 direction = canvas_to_viewport(x, y); vec3 color = trace_ray(origin, direction, fp16_16(1), - fp_limits::max()); + fp_limits::max(), + 2); put_pixel(x, y, color); } }