From 60d8221109304bc4f207dda8a42623cae488af5d Mon Sep 17 00:00:00 2001 From: Keuin Date: Sat, 16 Apr 2022 19:08:28 +0800 Subject: Move trace logging to tracelog.h. Pixel-wise, comprehensive, beautiful trace logging. --- CMakeLists.txt | 4 ++-- hitlist.h | 29 ++++++++++------------------- material_dielectric.cpp | 3 +++ material_diffusive.cpp | 4 ++++ material_reflective.cpp | 23 +++++++++++++++++++++-- tracelog.h | 17 +++++++++++++++++ vec.h | 3 +++ viewport.h | 15 ++++++++++++++- 8 files changed, 74 insertions(+), 24 deletions(-) create mode 100644 tracelog.h diff --git a/CMakeLists.txt b/CMakeLists.txt index a197031..fc3e6f3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,9 +12,9 @@ set(CMAKE_VERBOSE_MAKEFILE on) # main executable -add_executable(rt main.cpp vec.h bitmap.h ray.h bitfont.h hitlist.h object.h sphere.h viewport.h aa.h material.h material_diffusive.h material_diffusive.cpp material_reflective.h material_reflective.cpp material_dielectric.cpp material_dielectric.h) +add_executable(rt main.cpp vec.h bitmap.h ray.h bitfont.h hitlist.h object.h sphere.h viewport.h aa.h material.h material_diffusive.h material_diffusive.cpp material_reflective.h material_reflective.cpp material_dielectric.cpp material_dielectric.h tracelog.h) add_executable(image_output main_image_output.cpp vec.h bitmap.h bitfont.h hitlist.h object.h sphere.h viewport.h) -add_executable(simple_scanner main_simple_scanner.cpp vec.h bitmap.h ray.h timer.h bitfont.h hitlist.h object.h sphere.h viewport.h aa.h material.h material_diffusive.h material_diffusive.cpp material_reflective.h material_reflective.cpp material_dielectric.cpp material_dielectric.h) +add_executable(simple_scanner main_simple_scanner.cpp vec.h bitmap.h ray.h timer.h bitfont.h hitlist.h object.h sphere.h viewport.h aa.h material.h material_diffusive.h material_diffusive.cpp material_reflective.h material_reflective.cpp material_dielectric.cpp material_dielectric.h tracelog.h) # googletest diff --git a/hitlist.h b/hitlist.h index 1ad040a..ab9cca3 100644 --- a/hitlist.h +++ b/hitlist.h @@ -11,6 +11,7 @@ #include "ray.h" #include "vec.h" #include "object.h" +#include "tracelog.h" #include #include #include @@ -22,15 +23,6 @@ //#define T_NORM_VISUAL #define T_DIFFUSE -// log ray traces to stderr -//#define LOG_TRACE - -#ifdef LOG_TRACE -#define TRACELOG(...) (fprintf(stderr, __VA_ARGS__)) -#else -#define TRACELOG(...) -#endif - // A world, T is color depth class hitlist { std::vector> objects; @@ -50,9 +42,10 @@ public: pixel color(ray3d r, random_uv_gen_3d &ruvg, uint_fast32_t max_recursion_depth = 64) const { assert(r.decay().is_one()); TRACELOG("+++ start tracing (limit=%zu)\n", max_recursion_depth); - TRACELOG(" ray: [%10f,%10f,%10f], decay=[%10f,%10f,%10f]\n", + TRACELOG(" ray: [%-10f,%-10f,%-10f], decay=[%-10f,%-10f,%-10f]\n", r.direction().x, r.direction().y, r.direction().z, r.decay().x, r.decay().y, r.decay().z); while (max_recursion_depth-- > 0) { + TRACELOG(" step start (remaining: %lu)\n", max_recursion_depth + 1); // Detect hits bool hit = false; double hit_t = std::numeric_limits::infinity(); @@ -77,7 +70,8 @@ public: #ifdef LOG_TRACE const auto _hit_p_ = r.at(hit_t); const auto _rn_ = dot(r.direction(), hit_obj->normal_vector(_hit_p_)); - TRACELOG(" hit object <%p> at [%10f,%10f,%10f], t=%10f, surface=%10f (%s)\n", + TRACELOG(" hit object %s <%p> at [%-10f,%-10f,%-10f], t=%-10f, surface=%-10f (%s)\n", + typeid(*hit_obj).name(), hit_obj.get(), _hit_p_.x, _hit_p_.y, _hit_p_.z, hit_t, _rn_, (_rn_ < 0) ? "outside" : "inside"); #endif @@ -94,7 +88,7 @@ public: #ifdef T_DIFFUSE const auto &materi = hit_obj->material(); if (materi.scatter(r, *hit_obj, hit_t, ruvg)) { - TRACELOG(" scattered: [%10f,%10f,%10f], decay=[%10f,%10f,%10f]\n", + TRACELOG(" scattered ray: [%-10f,%-10f,%-10f], decay=[%-10f,%-10f,%-10f]\n", r.direction().x, r.direction().y, r.direction().z, r.decay().x, r.decay().y, r.decay().z); continue; // The ray is scatted by an object. Continue processing the scattered ray. @@ -105,6 +99,7 @@ public: #endif } + TRACELOG(" hit infinity (light source)\n"); // Does not hit anything. Get background color (infinity) const auto u = (r.direction().y + 1.0) * 0.5; const auto c = mix( @@ -113,19 +108,15 @@ public: 1.0 - u, u ); + + TRACELOG("--- finish (hit infinity)\n"); #ifdef T_DIFFUSE -#ifdef LOG_TRACE - const auto co = pixel8b::from(r.hit(c)); - TRACELOG(" result: [%d, %d, %d]\n", co.r, co.g, co.b); - TRACELOG("--- finish (reached infinity)\n"); -#endif return r.hit(c); #else - TRACELOG("--- finish (hit)\n"); return c; #endif } - TRACELOG("--- finish (max search depth)\n"); + TRACELOG("--- finish (trace step limit reached) [XX]\n"); return pixel::black(); // reached recursion time limit, very little light } }; diff --git a/material_dielectric.cpp b/material_dielectric.cpp index ed8e4eb..61e34ec 100644 --- a/material_dielectric.cpp +++ b/material_dielectric.cpp @@ -3,6 +3,7 @@ // #include "material_dielectric.h" +#include "tracelog.h" bool material_dielectric::scatter(ray3d &r, const object &hit_obj, double hit_t, random_uv_gen_3d &ruvg) const { const auto hit_p = r.at(hit_t); @@ -22,9 +23,11 @@ bool material_dielectric::scatter(ray3d &r, const object &hit_obj, double hit_t, // determine reflection or refraction using Schlick's Approximation. if (reflectance(cos1, ri_) > ruvg.range01_scalar()) { // reflect + TRACELOG(" reflect (dielectric material, schlick, ri=%-10f)\n", ri_); r2 = n.reflect(r.direction()); } else { // refract + TRACELOG(" refract (dielectric material, schlick, ri=%-10f)\n", ri_); r2 = n.refract(r.direction(), ri_); } r.direction(r2.unit_vec()); diff --git a/material_diffusive.cpp b/material_diffusive.cpp index b3f0207..58c9c45 100644 --- a/material_diffusive.cpp +++ b/material_diffusive.cpp @@ -4,6 +4,7 @@ #include "vec.h" #include "material_diffusive.h" +#include "tracelog.h" bool material_diffuse_lambertian::scatter(ray3d &r, const object &hit_obj, double hit_t, random_uv_gen_3d &ruvg) const { @@ -16,6 +17,7 @@ bool material_diffuse_lambertian::scatter(ray3d &r, const object &hit_obj, doubl r.decay(albedo); // lose some light when diffused r.source(hit_point); r.direction((diffuse_target - hit_point).unit_vec()); // the new diffused ray we trace on + TRACELOG(" reflected (diffusive, lambertian material)\n"); return true; } @@ -52,6 +54,7 @@ bool material_diffuse_simple::scatter(ray3d &r, const object &hit_obj, double hi r.decay(albedo); // lose some light when diffused r.source(hit_point); r.direction((diffuse_target - hit_point).unit_vec()); // the new diffused ray we trace on + TRACELOG(" reflected (diffusive, simple material)\n"); return true; } @@ -80,6 +83,7 @@ material_diffuse_hemispherical::scatter(ray3d &r, const object &hit_obj, double r.decay(albedo); // lose some light when diffused r.source(hit_point); r.direction((diffuse_target - hit_point).unit_vec()); // the new diffused ray we trace on + TRACELOG(" reflected (diffusive, hemispherical material)\n"); return true; } diff --git a/material_reflective.cpp b/material_reflective.cpp index aa0d361..6cffcf3 100644 --- a/material_reflective.cpp +++ b/material_reflective.cpp @@ -5,6 +5,7 @@ #include "vec.h" #include "material.h" #include "material_reflective.h" +#include "tracelog.h" // perfectly-smooth reflective template<> @@ -15,7 +16,16 @@ bool material_reflective_::scatter(ray3d &r, const object &hit_obj, doubl r.source(hit_point); r.direction(reflected); r.decay(albedo); - return dot(reflected, nv) > 0; + const auto alive = dot(reflected, nv) > 0; +#ifdef LOG_TRACE + if (!alive) { + TRACELOG(" absorbed (perfectly smooth material) (reflected: [%-10f,%-10f,%-10f], nv: [%-10f,%-10f,%-10f])\n", + reflected.x, reflected.y, reflected.z, nv.x, nv.y, nv.z); + } else { + TRACELOG(" reflected (perfectly smooth material)\n"); + } +#endif + return alive; } // fuzzy reflective @@ -27,5 +37,14 @@ bool material_reflective_::scatter(ray3d &r, const object &hit_obj, double r.source(hit_point); r.direction(reflected.unit_vec()); r.decay(albedo); - return dot(reflected, nv) > 0; + const auto alive = dot(reflected, nv) > 0; +#ifdef LOG_TRACE + if (!alive) { + TRACELOG(" absorbed (fuzzy reflective material) (reflected: [%-10f,%-10f,%-10f], nv: [%-10f,%-10f,%-10f])\n", + reflected.x, reflected.y, reflected.z, nv.x, nv.y, nv.z); + } else { + TRACELOG(" reflected (fuzzy reflective material)\n"); + } +#endif + return alive; } \ No newline at end of file diff --git a/tracelog.h b/tracelog.h new file mode 100644 index 0000000..cee85d4 --- /dev/null +++ b/tracelog.h @@ -0,0 +1,17 @@ +// +// Created by Keuin on 2022/4/16. +// + +#ifndef RT_TRACELOG_H +#define RT_TRACELOG_H + +// log ray traces to stderr +//#define LOG_TRACE + +#ifdef LOG_TRACE +#define TRACELOG(...) (fprintf(stderr, __VA_ARGS__)) +#else +#define TRACELOG(...) +#endif + +#endif //RT_TRACELOG_H diff --git a/vec.h b/vec.h index d2dece0..e3e15b8 100644 --- a/vec.h +++ b/vec.h @@ -10,6 +10,7 @@ #include #include #include +#include "tracelog.h" static inline bool eq(int a, int b) { return a == b; @@ -134,8 +135,10 @@ struct vec3 { // TODO test TIR if (Enable_TIR) { // ri_inv < sin(a1), cannot refract, must reflect (Total Internal Reflection) + TRACELOG(" reflect (TIR, d=%f)\n", d); return reflect(r1); } else { + TRACELOG(" refract (forced, d=%f)\n", d); d = -d; // abs, just make the sqrt has a real solution } } diff --git a/viewport.h b/viewport.h index 85d17f5..2924582 100644 --- a/viewport.h +++ b/viewport.h @@ -10,6 +10,7 @@ #include "ray.h" #include "vec.h" #include "hitlist.h" +#include "tracelog.h" #include #include #include @@ -97,7 +98,19 @@ public: const auto dir = r + off; // direction vector from camera to current pixel on screen ray3d ray{viewpoint, dir}; // from camera to pixel (on the viewport) const auto pixel = world.color(ray, ruvg); - image.set(i + img_hw, -j + img_hh, pixel); + const auto x_ = i + img_hw, y_ = -j + img_hh; + image.set(x_, y_, pixel); + +#ifdef LOG_TRACE + const auto ret = pixel; + const auto ret8b = pixel8b::from(ret); + const auto ret8bg2 = pixel8b::from(ret.gamma2()); + TRACELOG(" ^ apply to pixel: (%d, %d), color: [%f, %f, %f] (8bit: [%d, %d, %d], 8bit-gamma2: [%d, %d, %d])\n", + x_, y_, + (double) ret.r, (double) ret.g, (double) ret.b, + ret8b.r, ret8b.g, ret8b.b, + ret8bg2.r, ret8bg2.g, ret8bg2.b); +#endif } } return image; -- cgit v1.2.3