From e00b331881b02f1b2687db5522a2206bedfedf9d Mon Sep 17 00:00:00 2001 From: Alexander Penev Date: Thu, 11 Apr 2024 21:36:35 +0300 Subject: [PATCH 1/4] Initial import of diff-tracer demo --- demos/ComputerGraphics/build.sh | 2 + .../ComputerGraphics/cpp-smallpt-d/README.md | 6 + demos/ComputerGraphics/cpp-smallpt-d/build.sh | 4 + .../cpp-smallpt-d/cpp-smallpt | Bin 0 -> 23776 bytes .../cpp-smallpt-d/cpp-smallpt.cpp | 222 +++++++++++++ .../cpp-smallpt-d/diff-tracer-1.cpp | 294 +++++++++++++++++ .../cpp-smallpt-d/geometry.hpp | 63 ++++ .../cpp-smallpt-d/imageio.hpp | 38 +++ demos/ComputerGraphics/cpp-smallpt-d/math.hpp | 47 +++ demos/ComputerGraphics/cpp-smallpt-d/rng.hpp | 56 ++++ .../cpp-smallpt-d/sampling.hpp | 40 +++ .../cpp-smallpt-d/specular.hpp | 67 ++++ .../ComputerGraphics/cpp-smallpt-d/sphere.hpp | 116 +++++++ .../ComputerGraphics/cpp-smallpt-d/vector.hpp | 310 ++++++++++++++++++ 14 files changed, 1265 insertions(+) create mode 100755 demos/ComputerGraphics/build.sh create mode 100644 demos/ComputerGraphics/cpp-smallpt-d/README.md create mode 100755 demos/ComputerGraphics/cpp-smallpt-d/build.sh create mode 100755 demos/ComputerGraphics/cpp-smallpt-d/cpp-smallpt create mode 100644 demos/ComputerGraphics/cpp-smallpt-d/cpp-smallpt.cpp create mode 100644 demos/ComputerGraphics/cpp-smallpt-d/diff-tracer-1.cpp create mode 100644 demos/ComputerGraphics/cpp-smallpt-d/geometry.hpp create mode 100644 demos/ComputerGraphics/cpp-smallpt-d/imageio.hpp create mode 100644 demos/ComputerGraphics/cpp-smallpt-d/math.hpp create mode 100644 demos/ComputerGraphics/cpp-smallpt-d/rng.hpp create mode 100644 demos/ComputerGraphics/cpp-smallpt-d/sampling.hpp create mode 100644 demos/ComputerGraphics/cpp-smallpt-d/specular.hpp create mode 100644 demos/ComputerGraphics/cpp-smallpt-d/sphere.hpp create mode 100644 demos/ComputerGraphics/cpp-smallpt-d/vector.hpp diff --git a/demos/ComputerGraphics/build.sh b/demos/ComputerGraphics/build.sh new file mode 100755 index 000000000..1003e1013 --- /dev/null +++ b/demos/ComputerGraphics/build.sh @@ -0,0 +1,2 @@ +#!/bin/bash +clang -Ofast -Xclang -add-plugin -Xclang clad -Xclang -load -Xclang /build/clad/build-clad-tracer/lib/clad.so -I../../include/ -I/usr/lib/gcc/x86_64-linux-gnu/10/include -x c++ -std=c++14 -lstdc++ -lm SmallPT-1.cpp -fopenmp=libiomp5 -o SmallPT-1 "$@" diff --git a/demos/ComputerGraphics/cpp-smallpt-d/README.md b/demos/ComputerGraphics/cpp-smallpt-d/README.md new file mode 100644 index 000000000..681b31fee --- /dev/null +++ b/demos/ComputerGraphics/cpp-smallpt-d/README.md @@ -0,0 +1,6 @@ +Demo project 'cpp-smallpt-d' is base on: + C++ modification of Kevin Baeson's 99 line C++ path tracer + https://github.com/matt77hias/cpp-smallpt + + A Differentiable Renderer supports reverse Parameter and Scene + Reconstruction. diff --git a/demos/ComputerGraphics/cpp-smallpt-d/build.sh b/demos/ComputerGraphics/cpp-smallpt-d/build.sh new file mode 100755 index 000000000..56eb18c05 --- /dev/null +++ b/demos/ComputerGraphics/cpp-smallpt-d/build.sh @@ -0,0 +1,4 @@ +#!/bin/bash +clang -Ofast -Xclang -add-plugin -Xclang clad -Xclang -load -Xclang /build/clad/build-clad-tracer/lib/clad.so -I../../../include/ -x c++ -std=c++14 -lstdc++ -lm cpp-smallpt.cpp -fopenmp=libiomp5 -o cpp-smallpt "$@" + +clang -Ofast -Xclang -add-plugin -Xclang clad -Xclang -load -Xclang /build/clad/build-clad-tracer/lib/clad.so -I../../../include/ -x c++ -std=c++14 -lstdc++ -lm diff-tracer-1.cpp -fopenmp=libiomp5 -o diff-tracer-1 "$@" diff --git a/demos/ComputerGraphics/cpp-smallpt-d/cpp-smallpt b/demos/ComputerGraphics/cpp-smallpt-d/cpp-smallpt new file mode 100755 index 0000000000000000000000000000000000000000..32dc9fdcd0a49bed3ccb90abd51787a74ca67874 GIT binary patch literal 23776 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, 2022 +// Based on smallpt, a Path Tracer by Kevin Beason, 2008 +// Based on: C++ modification of Kevin Baeson's 99 line C++ path tracer +// https://github.com/matt77hias/cpp-smallpt +//----------------------------------------------------------------------------// + +// To compile the demo please type: +// path/to/clang -O3 -Xclang -add-plugin -Xclang clad -Xclang -load -Xclang \ +// path/to/libclad.so -I../../include/ -x c++ -std=c++11 -lstdc++ -lm \ +// cpp-smallpt-d.cpp -fopenmp=libiomp5 -o SmallPT +// +// To run the demo please type: +// ./cpp-smallpt-d 500 && xv image.ppm + +// A typical invocation would be: +// ../../../../../obj/Debug+Asserts/bin/clang -O3 -Xclang -add-plugin -Xclang clad \ +// -Xclang -load -Xclang ../../../../../obj/Debug+Asserts/lib/libclad.dylib \ +// -I../../include/ -x c++ -std=c++11 -lstdc++ -lm cpp-smalpt-d.cpp -fopenmp=libiomp5 \ +// -o cpp-smallpt-d +// ./cpp-smallpt-d 500 && xv image.ppm + + +//----------------------------------------------------------------------------- +// Includes +//----------------------------------------------------------------------------- +#pragma region + +#include "imageio.hpp" +#include "sampling.hpp" +#include "specular.hpp" +#include "sphere.hpp" + +#pragma endregion + +//----------------------------------------------------------------------------- +// System Includes +//----------------------------------------------------------------------------- +#pragma region + +#include +#include + +#pragma endregion + +//----------------------------------------------------------------------------- +// Defines +//----------------------------------------------------------------------------- +#pragma region + +#define REFRACTIVE_INDEX_OUT 1.0 +#define REFRACTIVE_INDEX_IN 1.5 + +#pragma endregion + +//----------------------------------------------------------------------------- +// Declarations and Definitions +//----------------------------------------------------------------------------- +namespace smallpt { + + /*constexpr*/ Sphere* scene[] = { + new Sphere(1e5, Vector3(1e5 + 1, 40.8, 81.6), Vector3(), Vector3(0.75, 0.25, 0.25), Reflection_t::Diffuse), // Left + new Sphere(1e5, Vector3(-1e5 + 99, 40.8, 81.6), Vector3(), Vector3(0.25, 0.25, 0.75), Reflection_t::Diffuse), // Right + new Sphere(1e5, Vector3(50, 40.8, 1e5), Vector3(), Vector3(0.75), Reflection_t::Diffuse), // Back + new Sphere(1e5, Vector3(50, 40.8, -1e5 + 170), Vector3(), Vector3(), Reflection_t::Diffuse), // Front + new Sphere(1e5, Vector3(50, 1e5, 81.6), Vector3(), Vector3(0.75), Reflection_t::Diffuse), // Bottom + new Sphere(1e5, Vector3(50, -1e5 + 81.6, 81.6), Vector3(), Vector3(0.75), Reflection_t::Diffuse), // Top + new Sphere(16.5, Vector3(27, 16.5, 47), Vector3(), Vector3(0.999), Reflection_t::Refractive), // Glass +// new Sphere(16.5, Vector3(55, 30, 57), Vector3(), Vector3(0.999), Reflection_t::Refractive), // Glassr +// new Sphere(16.5, Vector3(80, 60, 67), Vector3(), Vector3(0.999), Reflection_t::Refractive), // Glass + new Sphere(16.5, Vector3(73, 16.5, 78), Vector3(), Vector3(0.999), Reflection_t::Specular),// Mirror + new Sphere(600, Vector3(50, 681.6 - .27, 81.6), Vector3(12), Vector3(), Reflection_t::Diffuse) // Light + }; + + [[nodiscard]] + /*constexpr*/ size_t Intersect(Sphere* g_scene[], const size_t n_scene, const Ray& ray) noexcept { + size_t hit = SIZE_MAX; + for (size_t i = 0u; i < n_scene; ++i) { + if (g_scene[i]->Intersect(ray)) { + hit = i; + } + } + + return hit; + } + + [[nodiscard]] + static const Vector3 Radiance(Sphere* g_scene[], const size_t n_scene, const Ray& ray, RNG& rng) noexcept { + Ray r = ray; + Vector3 L; + Vector3 F(1.0); + + while (true) { + const auto hit = Intersect(g_scene, n_scene, r); + if (hit == SIZE_MAX) { + return L; + } + + const Sphere* shape = g_scene[hit]; + const Vector3 p = r(r.m_tmax); + const Vector3 n = Normalize(p - shape->m_p); + + L += F * shape->m_e; + F *= shape->m_f; + + // Russian roulette + if (4u < r.m_depth) { + const double continue_probability = shape->m_f.Max(); + if (rng.Uniform() >= continue_probability) { + return L; + } + F /= continue_probability; + } + + // Next path segment + switch (shape->m_reflection_t) { + + case Reflection_t::Specular: { + const Vector3 d = IdealSpecularReflect(r.m_d, n); + r = Ray(p, d, EPSILON_SPHERE, INFINITY, r.m_depth + 1u); + break; + } + + case Reflection_t::Refractive: { + double pr; + const Vector3 d = IdealSpecularTransmit(r.m_d, n, + REFRACTIVE_INDEX_OUT, + REFRACTIVE_INDEX_IN, pr, rng); + F *= pr; + r = Ray(p, d, EPSILON_SPHERE, INFINITY, r.m_depth + 1u); + break; + } + + default: { + const Vector3 w = (0.0 > n.Dot(r.m_d)) ? n : -n; + const Vector3 u = Normalize((std::abs(w.m_x) > 0.1 + ? Vector3(0.0, 1.0, 0.0) + : Vector3(1.0, 0.0, 0.0)) + .Cross(w)); + const Vector3 v = w.Cross(u); + + const Vector3 + sample_d = CosineWeightedSampleOnHemisphere(rng.Uniform(), + rng.Uniform()); + const Vector3 d = Normalize(sample_d.m_x * u + sample_d.m_y * v + + sample_d.m_z * w); + r = Ray(p, d, EPSILON_SPHERE, INFINITY, r.m_depth + 1u); + break; + } + } + } + } + + static void Render( + Sphere* g_scene[], const size_t n_scene, // Geometry, Lights + double Vx, double Vy, double Vz, // Params - Center of one sphere // must be Vector3() + const std::uint32_t w, const std::uint32_t h, std::uint32_t nb_samples, size_t fr, // Camera + Vector3 Ls[], const char* fileName // Result + ) noexcept { + + RNG rng; + + // Camera params + const Vector3 eye = {50.0, 52.0, 295.6}; + const Vector3 gaze = Normalize(Vector3(0.0, -0.042612, -1.0)); + const double fov = 0.5135; + const Vector3 cx = {w * fov / h, 0.0, 0.0}; + const Vector3 cy = Normalize(cx.Cross(gaze)) * fov; + + // Change unfixed geometry center + g_scene[6]->m_p = Vector3(Vx, Vy, Vz); + + #pragma omp parallel for schedule(static) + for (int y = 0; y < static_cast(h); ++y) { // pixel row + for (std::size_t x = 0u; x < w; ++x) { // pixel column + for (std::size_t sy = 0u, i = (h - 1u - y) * w + x; sy < 2u; ++sy) { // 2 subpixel row + for (std::size_t sx = 0u; sx < 2u; ++sx) { // 2 subpixel column + Vector3 L; + + for (std::size_t s = 0u; s < nb_samples; ++s) { // samples per subpixel + const double u1 = 2.0 * rng.Uniform(); + const double u2 = 2.0 * rng.Uniform(); + const double dx = u1 < 1.0 ? sqrt(u1) - 1.0 : 1.0 - sqrt(2.0 - u1); + const double dy = u2 < 1.0 ? sqrt(u2) - 1.0 : 1.0 - sqrt(2.0 - u2); + const Vector3 d = cx * (((sx + 0.5 + dx) * 0.5 + x) / w - 0.5) + + cy * (((sy + 0.5 + dy) * 0.5 + y) / h - 0.5) + + gaze; + + L += Radiance(g_scene, n_scene, Ray(eye + d * 130.0, Normalize(d), EPSILON_SPHERE), rng) * (1.0 / nb_samples); + } + + Ls[i] += 0.25 * Clamp(L); + } + } + } + } + + WritePPM(w, h, Ls, fileName); + } +} // namespace smallpt + +#ifndef CPP_EMBED_SMALLPT +using namespace smallpt; +int main(int argc, char* argv[]) { + const std::uint32_t nb_samples = (2 == argc) ? atoi(argv[1]) / 4 : 1; + const std::uint32_t w = 1024; + const std::uint32_t h = 768; + + smallpt::Render( + scene, *(&scene + 1) - scene, // Geometry, Lights + 27, 16.5, 47, // Params - Center of one sphere // must be Vector3() + w, h, nb_samples, 0, // Camera + new Vector3[w*h], "image.ppm" // Result + ); + + return 0; +} +#endif diff --git a/demos/ComputerGraphics/cpp-smallpt-d/diff-tracer-1.cpp b/demos/ComputerGraphics/cpp-smallpt-d/diff-tracer-1.cpp new file mode 100644 index 000000000..d682dfe0d --- /dev/null +++ b/demos/ComputerGraphics/cpp-smallpt-d/diff-tracer-1.cpp @@ -0,0 +1,294 @@ +//--------------------------------------------------------------------*- C++ -*- +// clad - The C++ Clang-based Automatic Differentiator +// +// Demo application of a simple gradient descent algorithm to find +// some params (one sphere position) in ray traced 3D scene. +// Clad is used to calculate the gradient of the cost function. +// Cost function is calculated as norm of differece between two images - +// first is target image and second is interemediate image generated +// during gradient decent algorithm. +// +//----------------------------------------------------------------------------// + +// To run the demo please type: +// path/to/clang -Xclang -add-plugin -Xclang clad -Xclang -load -Xclang \ +// path/to/libclad.so -I../include/ -x c++ -lstdc++ -lm diff-tracer-1.cpp +// +// A typical invocation would be: +// ../../../../obj/Debug+Asserts/bin/clang -Xclang -add-plugin -Xclang clad \ +// -Xclang -load -Xclang ../../../../obj/Debug+Asserts/lib/libclad.dylib \ +// -I../include/ -x c++ -lstdc++ -lm diff-tracer-1.cpp +// +// To plot the results: +// Results are stored in images: image-target.ppm, and image-i-(0..N).ppm + +//#include // For plotting data. +//#include // For std::* +//#include // For std::vector. + +// Necessary for clad to work include +#include "clad/Differentiator/Differentiator.h" + +// Include traces as embed "library" of functions +#define CPP_EMBED_SMALLPT 1 +#include "cpp-smallpt.cpp" + +using namespace smallpt; + +// Structure to represent input dataset +// w and h - represetn width and height of images +// target, current - represents the input/target and +// output data/images respectively +struct Dataset { + const std::uint32_t w = 1024u; + const std::uint32_t h = 768u; + const std::uint32_t nb_samples; + Vector3* target; + Vector3* current; + double learning_rate = 1e-2; + // result + double Vx, Vy, Vz; + int step = 0; + + // Populate the data with target image (render example + random noice) + Dataset(const std::uint32_t nb_samples = 1, const std::uint32_t w = 1024u, const std::uint32_t h = 768u) : + nb_samples(nb_samples), w(w), h(h) { + // Create Target data/image + char fileName[4096]; + snprintf(fileName, sizeof(fileName), "image-target.ppm"); + target = new Vector3[w*h]; + current = new Vector3[w*h]; + Render( + scene, *(&scene + 1) - scene, // Geometry, Lights + 27, 16.5, 47, // Params - Center of one sphere // must be Vector3() + w, h, nb_samples, 0, // Camera + target, fileName // Result + ); + + // For initial position of sphere we use randomized values + Vx = 80.0 * (((double)std::rand())/RAND_MAX) + 10.0; + Vy = 80.0 * (((double)std::rand())/RAND_MAX) + 10.0; + Vz = 80.0 * (((double)std::rand())/RAND_MAX) + 10.0; + } +}; + +// Function to perform a minimization step +// theta_x are the hypothesis parameters, dt is the generated dataset and +// clad_grad is the gradient function generated by Clad +template +void performStep(double& theta_0, double& theta_1, double& theta_2, Dataset dt, T clad_grad) { + double J_theta[3+2]; + double result[3] = {0, 0, 0}; + // current? + for (size_t i = 0; i < dt.w*dt.h; i++) { + J_theta[0] = J_theta[1] = J_theta[2] = J_theta[3] = 0; +// clad_grad.execute(theta_0, theta_1, theta_2, dt.target[i], dt.current[i], +// &J_theta[0], &J_theta[1], &J_theta[2], &J_theta[3], &J_theta[4] +// ); + + result[0] += J_theta[0]; + result[1] += J_theta[1]; + result[2] += J_theta[2]; + } + + theta_0 -= dt.learning_rate * result[0] / (2 * dt.w*dt.h); + theta_1 -= dt.learning_rate * result[1] / (2 * dt.w*dt.h); + theta_2 -= dt.learning_rate * result[2] / (2 * dt.w*dt.h); +} + +// The cost function to minimize using gradient descent +// theta_x are the parameters to learn; x, y are the inputs and outputs of f +double cost(double theta_0, double theta_1, double theta_2, Dataset dt) { + char fileName[4096]; + snprintf(fileName, sizeof(fileName), "image-%d.ppm", dt.step++); + Render( + scene, *(&scene + 1) - scene, // Geometry, Lights + dt.Vx, dt.Vy, dt.Vz, // Params - Center of one sphere // must be Vector3() + dt.w, dt.h, dt.nb_samples, 0, // Camera + dt.current, fileName // Result + ); + for (int i=0; i<=dt.h; i++) { + for (int j=0; j<=dt.w; j++) { +// sum += + } + } + +// double f_x = f(theta_0, theta_1, theta_2, x); +// return (f_x - y) * (f_x - y); + return 0; +} + +double f(double x, double y) { + double t = 0; + for (int i=0; i<10; i++) { + t += x*y; + } + return t; +} + +double f1(double x[], int cnt) { + double sum = 0; + for (int i=0; i _d_x, clad::array_ref _d_y) { + double _d_t = 0; + unsigned long _t0; + int _d_i = 0; + clad::tape _t1 = {}; + clad::tape _t2 = {}; + double t = 0; + _t0 = 0; + for (int i = 0; i < 10; i++) { + _t0++; + t += clad::push(_t2, x) * clad::push(_t1, y); + } + double f_return = t; + goto _label0; + _label0: + _d_t += 1; + for (; _t0; _t0--) { + { + double _r_d0 = _d_t; + _d_t += _r_d0; + double _r0 = _r_d0 * clad::pop(_t1); + * _d_x += _r0; + double _r1 = clad::pop(_t2) * _r_d0; + * _d_y += _r1; + _d_t -= _r_d0; + } + } +} + +void f_g(double x, double y, double result[2]) { + double t_x = 0; + double t_y = 0; + for (int i=0; i::infinity(), + std::uint32_t depth = 0u) noexcept + : m_o(std::move(o)), m_d(std::move(d)), m_tmin(tmin), m_tmax(tmax), + m_depth(depth){}; + constexpr Ray(const Ray& ray) noexcept = default; + constexpr Ray(Ray&& ray) noexcept = default; + ~Ray() = default; + + //--------------------------------------------------------------------- + // Assignment Operators + //--------------------------------------------------------------------- + + Ray& operator=(const Ray& ray) = default; + Ray& operator=(Ray&& ray) = default; + + //--------------------------------------------------------------------- + // Member Methods + //--------------------------------------------------------------------- + + [[nodiscard]] + constexpr const Vector3 operator()(double t) const noexcept { + return m_o + m_d * t; + } + + //--------------------------------------------------------------------- + // Member Variables + //--------------------------------------------------------------------- + + Vector3 m_o, m_d; + mutable double m_tmin, m_tmax; + std::uint32_t m_depth; + }; + + inline std::ostream& operator<<(std::ostream& os, const Ray& r) { + os << "o: " << r.m_o << std::endl; + os << "d: " << r.m_d << std::endl; + return os; + } +} // namespace smallpt diff --git a/demos/ComputerGraphics/cpp-smallpt-d/imageio.hpp b/demos/ComputerGraphics/cpp-smallpt-d/imageio.hpp new file mode 100644 index 000000000..35cd280d4 --- /dev/null +++ b/demos/ComputerGraphics/cpp-smallpt-d/imageio.hpp @@ -0,0 +1,38 @@ +#pragma once + +//----------------------------------------------------------------------------- +// Includes +//----------------------------------------------------------------------------- +#pragma region + +#include "vector.hpp" + +#pragma endregion + +//----------------------------------------------------------------------------- +// System Includes +//----------------------------------------------------------------------------- +#pragma region + +#include + +#pragma endregion + +//----------------------------------------------------------------------------- +// Declarations and Definitions +//----------------------------------------------------------------------------- +namespace smallpt { + + inline void WritePPM(std::uint32_t w, std::uint32_t h, const Vector3* Ls, + const char* fname = "cpp-smallpt-d.ppm") noexcept { + + FILE* fp = fopen(fname, "w"); + + std::fprintf(fp, "P3\n%u %u\n%u\n", w, h, 255u); + for (std::size_t i = 0; i < w * h; ++i) { + std::fprintf(fp, "%u %u %u ", ToByte(Ls[i].m_x), ToByte(Ls[i].m_y), ToByte(Ls[i].m_z)); + } + + std::fclose(fp); + } +} // namespace smallpt diff --git a/demos/ComputerGraphics/cpp-smallpt-d/math.hpp b/demos/ComputerGraphics/cpp-smallpt-d/math.hpp new file mode 100644 index 000000000..592bcc504 --- /dev/null +++ b/demos/ComputerGraphics/cpp-smallpt-d/math.hpp @@ -0,0 +1,47 @@ +#pragma once + +//----------------------------------------------------------------------------- +// System Includes +//----------------------------------------------------------------------------- +#pragma region + +#include +#include +#include +#include + +#pragma endregion + +//----------------------------------------------------------------------------- +// Declarations and Definitions +//----------------------------------------------------------------------------- +namespace smallpt { + + //------------------------------------------------------------------------- + // Constants + //------------------------------------------------------------------------- + + constexpr double g_pi = 3.14159265358979323846; + + //------------------------------------------------------------------------- + // Utilities + //------------------------------------------------------------------------- + + template + [[nodiscard]] + constexpr const T& clamp(const T& v, const T& lo, const T& hi) noexcept { + return clamp(v, lo, hi, [](const T& a, const T& b) noexcept { return (a < b); }); + } + + template + [[nodiscard]] + constexpr const T& clamp(const T& v, const T& lo, const T& hi, Compare comp) noexcept { + return comp(v, lo) ? lo : comp(hi, v) ? hi : v; + } + + [[nodiscard]] + inline std::uint8_t ToByte(double color, double gamma = 2.2) noexcept { + const double gcolor = std::pow(color, 1.0 / gamma); + return static_cast(clamp(255.0 * gcolor, 0.0, 255.0)); + } +} // namespace smallpt diff --git a/demos/ComputerGraphics/cpp-smallpt-d/rng.hpp b/demos/ComputerGraphics/cpp-smallpt-d/rng.hpp new file mode 100644 index 000000000..48546c1e1 --- /dev/null +++ b/demos/ComputerGraphics/cpp-smallpt-d/rng.hpp @@ -0,0 +1,56 @@ +#pragma once + +//----------------------------------------------------------------------------- +// System Includes +//----------------------------------------------------------------------------- +#pragma region + +#include +#include +#include + +#pragma endregion + +//----------------------------------------------------------------------------- +// Declarations and Definitions +//----------------------------------------------------------------------------- +namespace smallpt { + + class RNG { + public: + //--------------------------------------------------------------------- + // Constructors and Destructors + //--------------------------------------------------------------------- + + explicit RNG(std::uint32_t seed = 606418532u) noexcept + : m_generator(), m_distribution() { + Seed(seed); + } + RNG(const RNG& rng) noexcept = default; + RNG(RNG&& rng) noexcept = default; + ~RNG() = default; + + //--------------------------------------------------------------------- + // Assignment Operators + //--------------------------------------------------------------------- + + RNG& operator=(const RNG& rng) = delete; + RNG& operator=(RNG&& rng) = delete; + + //--------------------------------------------------------------------- + // Member Methods + //--------------------------------------------------------------------- + + void Seed(uint32_t seed) noexcept { /*m_generator.seed(seed);*/ } + + double Uniform() noexcept { return m_distribution(m_generator); } + + private: + //--------------------------------------------------------------------- + // Member Variables + //--------------------------------------------------------------------- + + std::default_random_engine m_generator; + std::uniform_real_distribution m_distribution; + }; +} // namespace smallpt diff --git a/demos/ComputerGraphics/cpp-smallpt-d/sampling.hpp b/demos/ComputerGraphics/cpp-smallpt-d/sampling.hpp new file mode 100644 index 000000000..9a85dbe18 --- /dev/null +++ b/demos/ComputerGraphics/cpp-smallpt-d/sampling.hpp @@ -0,0 +1,40 @@ +#pragma once + +//----------------------------------------------------------------------------- +// Includes +//----------------------------------------------------------------------------- +#pragma region + +#include "vector.hpp" + +#pragma endregion + +//----------------------------------------------------------------------------- +// Declarations and Definitions +//----------------------------------------------------------------------------- +namespace smallpt { + + [[nodiscard]] + inline const Vector3 UniformSampleOnSphere(double u1, double u2) noexcept { + const double cos_theta = 1.0 - 2.0 * u1; + const double sin_theta = std::sqrt(std::max(0.0, 1.0 - cos_theta * cos_theta)); + const double phi = 2.0 * g_pi * u2; + return {std::cos(phi) * sin_theta, std::sin(phi) * sin_theta, cos_theta}; + } + + [[nodiscard]] + inline const Vector3 UniformSampleOnHemisphere(double u1, double u2) noexcept { + // u1 := cos_theta + const double sin_theta = std::sqrt(std::max(0.0, 1.0 - u1 * u1)); + const double phi = 2.0 * g_pi * u2; + return {std::cos(phi) * sin_theta, std::sin(phi) * sin_theta, u1}; + } + + [[nodiscard]] + inline const Vector3 CosineWeightedSampleOnHemisphere(double u1, double u2) noexcept { + const double cos_theta = sqrt(1.0 - u1); + const double sin_theta = sqrt(u1); + const double phi = 2.0 * g_pi * u2; + return {std::cos(phi) * sin_theta, std::sin(phi) * sin_theta, cos_theta}; + } +} // namespace smallpt diff --git a/demos/ComputerGraphics/cpp-smallpt-d/specular.hpp b/demos/ComputerGraphics/cpp-smallpt-d/specular.hpp new file mode 100644 index 000000000..56d4bcb27 --- /dev/null +++ b/demos/ComputerGraphics/cpp-smallpt-d/specular.hpp @@ -0,0 +1,67 @@ +#pragma once + +//----------------------------------------------------------------------------- +// Includes +//----------------------------------------------------------------------------- +#pragma region + +#include "rng.hpp" +#include "vector.hpp" + +#pragma endregion + +//----------------------------------------------------------------------------- +// Declarations and Definitions +//----------------------------------------------------------------------------- +namespace smallpt { + + [[nodiscard]] + constexpr double Reflectance0(double n1, double n2) noexcept { + const double sqrt_R0 = (n1 - n2) / (n1 + n2); + return sqrt_R0 * sqrt_R0; + } + + [[nodiscard]] + constexpr double SchlickReflectance(double n1, double n2, double c) noexcept { + const double R0 = Reflectance0(n1, n2); + return R0 + (1.0 - R0) * c * c * c * c * c; + } + + [[nodiscard]] + constexpr const Vector3 IdealSpecularReflect(const Vector3& d, const Vector3& n) noexcept { + return d - 2.0 * n.Dot(d) * n; + } + + [[nodiscard]] + inline const Vector3 IdealSpecularTransmit(const Vector3& d, const Vector3& n, double n_out, + double n_in, double& pr, RNG& rng) noexcept { + const Vector3 d_Re = IdealSpecularReflect(d, n); + + const bool out_to_in = (0.0 > n.Dot(d)); + const Vector3 nl = out_to_in ? n : -n; + const double nn = out_to_in ? n_out / n_in : n_in / n_out; + const double cos_theta = d.Dot(nl); + const double cos2_phi = 1.0 - nn * nn * (1.0 - cos_theta * cos_theta); + + // Total Internal Reflection + if (0.0 > cos2_phi) { + pr = 1.0; + return d_Re; + } + + const Vector3 d_Tr = Normalize(nn * d - nl * (nn * cos_theta + sqrt(cos2_phi))); + const double c = 1.0 - (out_to_in ? -cos_theta : d_Tr.Dot(n)); + + const double Re = SchlickReflectance(n_out, n_in, c); + const double p_Re = 0.25 + 0.5 * Re; + if (rng.Uniform() < p_Re) { + pr = (Re / p_Re); + return d_Re; + } else { + const double Tr = 1.0 - Re; + const double p_Tr = 1.0 - p_Re; + pr = (Tr / p_Tr); + return d_Tr; + } + } +} // namespace smallpt diff --git a/demos/ComputerGraphics/cpp-smallpt-d/sphere.hpp b/demos/ComputerGraphics/cpp-smallpt-d/sphere.hpp new file mode 100644 index 000000000..b89fc6009 --- /dev/null +++ b/demos/ComputerGraphics/cpp-smallpt-d/sphere.hpp @@ -0,0 +1,116 @@ +#pragma once + +//----------------------------------------------------------------------------- +// Includes +//----------------------------------------------------------------------------- +#pragma region + +#include "geometry.hpp" + +#pragma endregion + +//----------------------------------------------------------------------------- +// Defines +//----------------------------------------------------------------------------- +#pragma region + +#define EPSILON_SPHERE 1e-4 + +#pragma endregion + +//----------------------------------------------------------------------------- +// Declarations and Definitions +//----------------------------------------------------------------------------- +namespace smallpt { + + //------------------------------------------------------------------------- + // Declarations and Definitions: Reflection_t + //------------------------------------------------------------------------- + + enum struct Reflection_t : std::uint8_t { + Diffuse = 0u, + Specular, + Refractive + }; + + //------------------------------------------------------------------------- + // Declarations and Definitions: Sphere + //------------------------------------------------------------------------- + + struct Sphere { + + //--------------------------------------------------------------------- + // Constructors and Destructors + //--------------------------------------------------------------------- + + constexpr explicit Sphere(double r, Vector3 p, Vector3 e, Vector3 f, + Reflection_t reflection_t) noexcept + : m_r(r), m_p(std::move(p)), m_e(std::move(e)), m_f(std::move(f)), + m_reflection_t(reflection_t) {} + constexpr Sphere(const Sphere& sphere) noexcept = default; + constexpr Sphere(Sphere&& sphere) noexcept = default; + ~Sphere() = default; + + //--------------------------------------------------------------------- + // Assignment Operators + //--------------------------------------------------------------------- + + Sphere& operator=(const Sphere& sphere) = default; + Sphere& operator=(Sphere&& sphere) = default; + + //--------------------------------------------------------------------- + // Member Methods + //--------------------------------------------------------------------- + + [[nodiscard]] + constexpr bool Intersect(const Ray& ray) const noexcept { + // (o + t*d - p) . (o + t*d - p) - r*r = 0 + // <=> (d . d) * t^2 + 2 * d . (o - p) * t + (o - p) . (o - p) - r*r = 0 + // + // Discriminant check + // (2 * d . (o - p))^2 - 4 * (d . d) * ((o - p) . (o - p) - r*r) (d . (o - p))^2 - (d . d) * ((o - p) . (o - p) - r*r) (d . op)^2 - 1 * (op . op - r*r) b^2 - (op . op) + r*r D t = dop +- sqrt(D) + + const Vector3 op = m_p - ray.m_o; + const double dop = ray.m_d.Dot(op); + const double D = dop * dop - op.Dot(op) + m_r * m_r; + + if (0.0 > D) { + return false; + } + + const double sqrtD = sqrt(D); + + const double tmin = dop - sqrtD; + if (ray.m_tmin < tmin && tmin < ray.m_tmax) { + ray.m_tmax = tmin; + return true; + } + + const double tmax = dop + sqrtD; + if (ray.m_tmin < tmax && tmax < ray.m_tmax) { + ray.m_tmax = tmax; + return true; + } + + return false; + } + + //--------------------------------------------------------------------- + // Member Variables + //--------------------------------------------------------------------- + + double m_r; + Vector3 m_p; // position + Vector3 m_e; // emission + Vector3 m_f; // reflection + Reflection_t m_reflection_t; + }; +} // namespace smallpt diff --git a/demos/ComputerGraphics/cpp-smallpt-d/vector.hpp b/demos/ComputerGraphics/cpp-smallpt-d/vector.hpp new file mode 100644 index 000000000..4b3b46c17 --- /dev/null +++ b/demos/ComputerGraphics/cpp-smallpt-d/vector.hpp @@ -0,0 +1,310 @@ +#pragma once + +//----------------------------------------------------------------------------- +// Includes +//----------------------------------------------------------------------------- +#pragma region + +#include "math.hpp" + +#pragma endregion + +//----------------------------------------------------------------------------- +// System Includes +//----------------------------------------------------------------------------- +#pragma region + +#include + +#pragma endregion + +//----------------------------------------------------------------------------- +// Declarations and Definitions +//----------------------------------------------------------------------------- +namespace smallpt { + + //------------------------------------------------------------------------- + // Vector3 + //------------------------------------------------------------------------- + + struct Vector3 { + + public: + //--------------------------------------------------------------------- + // Constructors and Destructors + //--------------------------------------------------------------------- + + constexpr explicit Vector3(double xyz = 0.0) noexcept + : Vector3(xyz, xyz, xyz) {} + constexpr Vector3(double x, double y, double z) noexcept + : m_x(x), m_y(y), m_z(z) {} + constexpr Vector3(const Vector3& v) noexcept = default; + constexpr Vector3(Vector3&& v) noexcept = default; + ~Vector3() = default; + + //--------------------------------------------------------------------- + // Assignment Operators + //--------------------------------------------------------------------- + + Vector3& operator=(const Vector3& v) = default; + Vector3& operator=(Vector3&& v) = default; + + //--------------------------------------------------------------------- + // Member Methods + //--------------------------------------------------------------------- + + [[nodiscard]] bool HasNaNs() const noexcept { + return std::isnan(m_x) || std::isnan(m_y) || std::isnan(m_z); + } + + [[nodiscard]] constexpr const Vector3 operator-() const noexcept { + return {-m_x, -m_y, -m_z}; + } + + [[nodiscard]] constexpr const Vector3 + operator+(const Vector3& v) const noexcept { + return {m_x + v.m_x, m_y + v.m_y, m_z + v.m_z}; + } + + [[nodiscard]] constexpr const Vector3 + operator-(const Vector3& v) const noexcept { + return {m_x - v.m_x, m_y - v.m_y, m_z - v.m_z}; + } + + [[nodiscard]] constexpr const Vector3 + operator*(const Vector3& v) const noexcept { + return {m_x * v.m_x, m_y * v.m_y, m_z * v.m_z}; + } + + [[nodiscard]] constexpr const Vector3 + operator/(const Vector3& v) const noexcept { + return {m_x / v.m_x, m_y / v.m_y, m_z / v.m_z}; + } + + [[nodiscard]] constexpr const Vector3 operator+(double a) const noexcept { + return {m_x + a, m_y + a, m_z + a}; + } + + [[nodiscard]] constexpr const Vector3 operator-(double a) const noexcept { + return {m_x - a, m_y - a, m_z - a}; + } + + [[nodiscard]] constexpr const Vector3 operator*(double a) const noexcept { + return {m_x * a, m_y * a, m_z * a}; + } + + [[nodiscard]] constexpr const Vector3 operator/(double a) const noexcept { + const double inv_a = 1.0 / a; + return {m_x * inv_a, m_y * inv_a, m_z * inv_a}; + } + + Vector3& operator+=(const Vector3& v) noexcept { + m_x += v.m_x; + m_y += v.m_y; + m_z += v.m_z; + return *this; + } + + Vector3& operator-=(const Vector3& v) noexcept { + m_x -= v.m_x; + m_y -= v.m_y; + m_z -= v.m_z; + return *this; + } + + Vector3& operator*=(const Vector3& v) noexcept { + m_x *= v.m_x; + m_y *= v.m_y; + m_z *= v.m_z; + return *this; + } + + Vector3& operator/=(const Vector3& v) noexcept { + m_x /= v.m_x; + m_y /= v.m_y; + m_z /= v.m_z; + return *this; + } + + Vector3& operator+=(double a) noexcept { + m_x += a; + m_y += a; + m_z += a; + return *this; + } + + Vector3& operator-=(double a) noexcept { + m_x -= a; + m_y -= a; + m_z -= a; + return *this; + } + + Vector3& operator*=(double a) noexcept { + m_x *= a; + m_y *= a; + m_z *= a; + return *this; + } + + Vector3& operator/=(double a) noexcept { + const double inv_a = 1.0 / a; + m_x *= inv_a; + m_y *= inv_a; + m_z *= inv_a; + return *this; + } + + [[nodiscard]] constexpr double Dot(const Vector3& v) const noexcept { + return m_x * v.m_x + m_y * v.m_y + m_z * v.m_z; + } + + [[nodiscard]] constexpr const Vector3 + Cross(const Vector3& v) const noexcept { + return {m_y * v.m_z - m_z * v.m_y, m_z * v.m_x - m_x * v.m_z, + m_x * v.m_y - m_y * v.m_x}; + } + + [[nodiscard]] constexpr bool operator==(const Vector3& rhs) const { + return m_x == rhs.m_x && m_y == rhs.m_y && m_z == rhs.m_z; + } + + [[nodiscard]] constexpr bool operator!=(const Vector3& rhs) const { + return !(*this == rhs); + } + + [[nodiscard]] double& operator[](std::size_t i) noexcept { + return (&m_x)[i]; + } + + [[nodiscard]] constexpr double operator[](std::size_t i) const noexcept { + return (&m_x)[i]; + } + + [[nodiscard]] constexpr std::size_t MinDimension() const noexcept { + return (m_x < m_y && m_x < m_z) ? 0u : ((m_y < m_z) ? 1u : 2u); + } + + [[nodiscard]] constexpr std::size_t MaxDimension() const noexcept { + return (m_x > m_y && m_x > m_z) ? 0u : ((m_y > m_z) ? 1u : 2u); + } + + [[nodiscard]] constexpr double Min() const noexcept { + return std::min(m_x, std::min(m_y, m_z)); + } + [[nodiscard]] constexpr double Max() const noexcept { + return std::max(m_x, std::max(m_y, m_z)); + } + + [[nodiscard]] constexpr double Norm2_squared() const noexcept { + return m_x * m_x + m_y * m_y + m_z * m_z; + } + + [[nodiscard]] double Norm2() const noexcept { + return std::sqrt(Norm2_squared()); + } + + void Normalize() noexcept { + const double a = 1.0 / Norm2(); + m_x *= a; + m_y *= a; + m_z *= a; + } + + //--------------------------------------------------------------------- + // Member Variables + //--------------------------------------------------------------------- + + double m_x, m_y, m_z; + }; + + //------------------------------------------------------------------------- + // Vector3 Utilities + //------------------------------------------------------------------------- + + std::ostream& operator<<(std::ostream& os, const Vector3& v) { + os << '[' << v.m_x << ' ' << v.m_y << ' ' << v.m_z << ']'; + return os; + } + + [[nodiscard]] constexpr const Vector3 operator+(double a, + const Vector3& v) noexcept { + return {a + v.m_x, a + v.m_y, a + v.m_z}; + } + + [[nodiscard]] constexpr const Vector3 operator-(double a, + const Vector3& v) noexcept { + return {a - v.m_x, a - v.m_y, a - v.m_z}; + } + + [[nodiscard]] constexpr const Vector3 operator*(double a, + const Vector3& v) noexcept { + return {a * v.m_x, a * v.m_y, a * v.m_z}; + } + + [[nodiscard]] constexpr const Vector3 operator/(double a, + const Vector3& v) noexcept { + return {a / v.m_x, a / v.m_y, a / v.m_z}; + } + + [[nodiscard]] inline const Vector3 Sqrt(const Vector3& v) noexcept { + return {std::sqrt(v.m_x), std::sqrt(v.m_y), std::sqrt(v.m_z)}; + } + + [[nodiscard]] inline const Vector3 Pow(const Vector3& v, double a) noexcept { + return {std::pow(v.m_x, a), std::pow(v.m_y, a), std::pow(v.m_z, a)}; + } + + [[nodiscard]] inline const Vector3 Abs(const Vector3& v) noexcept { + return {std::abs(v.m_x), std::abs(v.m_y), std::abs(v.m_z)}; + } + + [[nodiscard]] constexpr const Vector3 Min(const Vector3& v1, + const Vector3& v2) noexcept { + return {std::min(v1.m_x, v2.m_x), std::min(v1.m_y, v2.m_y), + std::min(v1.m_z, v2.m_z)}; + } + + [[nodiscard]] constexpr const Vector3 Max(const Vector3& v1, + const Vector3& v2) noexcept { + return {std::max(v1.m_x, v2.m_x), std::max(v1.m_y, v2.m_y), + std::max(v1.m_z, v2.m_z)}; + } + + [[nodiscard]] inline const Vector3 Round(const Vector3& v) noexcept { + return {std::round(v.m_x), std::round(v.m_y), std::round(v.m_z)}; + } + + [[nodiscard]] inline const Vector3 Floor(const Vector3& v) noexcept { + return {std::floor(v.m_x), std::floor(v.m_y), std::floor(v.m_z)}; + } + + [[nodiscard]] inline const Vector3 Ceil(const Vector3& v) noexcept { + return {std::ceil(v.m_x), std::ceil(v.m_y), std::ceil(v.m_z)}; + } + + [[nodiscard]] inline const Vector3 Trunc(const Vector3& v) noexcept { + return {std::trunc(v.m_x), std::trunc(v.m_y), std::trunc(v.m_z)}; + } + + [[nodiscard]] constexpr const Vector3 + Clamp(const Vector3& v, double low = 0.0, double high = 1.0) noexcept { + + return {clamp(v.m_x, low, high), clamp(v.m_y, low, high), + clamp(v.m_z, low, high)}; + } + [[nodiscard]] constexpr const Vector3 Lerp(double a, const Vector3& v1, + const Vector3& v2) noexcept { + return v1 + a * (v2 - v1); + } + + template + [[nodiscard]] constexpr const Vector3 Permute(const Vector3& v) noexcept { + return {v[X], v[Y], v[Z]}; + } + + [[nodiscard]] inline const Vector3 Normalize(const Vector3& v) noexcept { + const double a = 1.0 / v.Norm2(); + return a * v; + } +} // namespace smallpt From bb9a478a236460e1544f7b3e71b08c9d27d62fd5 Mon Sep 17 00:00:00 2001 From: Alexander Penev Date: Thu, 11 Apr 2024 23:42:06 +0000 Subject: [PATCH 2/4] Fix build scripts. Add missed sources --- demos/ComputerGraphics/build.sh | 2 - demos/ComputerGraphics/cpp-smallpt-d/build.sh | 4 +- .../cpp-smallpt-d/cpp-smallpt | Bin 23776 -> 0 bytes demos/ComputerGraphics/smallpt/SmallPT | Bin 0 -> 23584 bytes demos/ComputerGraphics/smallpt/SmallPT-1.cpp | 606 ++++++++++++++++++ demos/ComputerGraphics/smallpt/build.sh | 2 + 6 files changed, 610 insertions(+), 4 deletions(-) delete mode 100755 demos/ComputerGraphics/build.sh delete mode 100755 demos/ComputerGraphics/cpp-smallpt-d/cpp-smallpt create mode 100755 demos/ComputerGraphics/smallpt/SmallPT create mode 100644 demos/ComputerGraphics/smallpt/SmallPT-1.cpp create mode 100755 demos/ComputerGraphics/smallpt/build.sh diff --git a/demos/ComputerGraphics/build.sh b/demos/ComputerGraphics/build.sh deleted file mode 100755 index 1003e1013..000000000 --- a/demos/ComputerGraphics/build.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/bash -clang -Ofast -Xclang -add-plugin -Xclang clad -Xclang -load -Xclang /build/clad/build-clad-tracer/lib/clad.so -I../../include/ -I/usr/lib/gcc/x86_64-linux-gnu/10/include -x c++ -std=c++14 -lstdc++ -lm SmallPT-1.cpp -fopenmp=libiomp5 -o SmallPT-1 "$@" diff --git a/demos/ComputerGraphics/cpp-smallpt-d/build.sh b/demos/ComputerGraphics/cpp-smallpt-d/build.sh index 56eb18c05..6a847dd93 100755 --- a/demos/ComputerGraphics/cpp-smallpt-d/build.sh +++ b/demos/ComputerGraphics/cpp-smallpt-d/build.sh @@ -1,4 +1,4 @@ #!/bin/bash -clang -Ofast -Xclang -add-plugin -Xclang clad -Xclang -load -Xclang /build/clad/build-clad-tracer/lib/clad.so -I../../../include/ -x c++ -std=c++14 -lstdc++ -lm cpp-smallpt.cpp -fopenmp=libiomp5 -o cpp-smallpt "$@" +clang -Ofast -Xclang -add-plugin -Xclang clad -Xclang -load -Xclang ../../../build/lib/clad.so -I../../../include/ -x c++ -std=c++14 -lstdc++ -lm cpp-smallpt.cpp -fopenmp=libiomp5 -o cpp-smallpt "$@" -clang -Ofast -Xclang -add-plugin -Xclang clad -Xclang -load -Xclang /build/clad/build-clad-tracer/lib/clad.so -I../../../include/ -x c++ -std=c++14 -lstdc++ -lm diff-tracer-1.cpp -fopenmp=libiomp5 -o diff-tracer-1 "$@" +clang -Ofast -Xclang -add-plugin -Xclang clad -Xclang -load -Xclang ../../../lib/clad.so -I../../../include/ -x c++ -std=c++14 -lstdc++ -lm diff-tracer-1.cpp -fopenmp=libiomp5 -o diff-tracer-1 "$@" diff --git a/demos/ComputerGraphics/cpp-smallpt-d/cpp-smallpt b/demos/ComputerGraphics/cpp-smallpt-d/cpp-smallpt deleted file mode 100755 index 32dc9fdcd0a49bed3ccb90abd51787a74ca67874..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23776 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 +// Based on smallpt, a Path Tracer by Kevin Beason, 2008 +//----------------------------------------------------------------------------// + +// To compile the demo please type: +// path/to/clang -O3 -Xclang -add-plugin -Xclang clad -Xclang -load -Xclang \ +// path/to/libclad.so -I../../include/ -x c++ -std=c++11 -lstdc++ SmallPT.cpp \ +// -o SmallPT +// +// To run the demo please type: +// ./SmallPT 500 && xv image.ppm + +// A typical invocation would be: +// ../../../../../obj/Debug+Asserts/bin/clang -O3 -Xclang -add-plugin -Xclang clad \ +// -Xclang -load -Xclang ../../../../../obj/Debug+Asserts/lib/libclad.dylib \ +// -I../../include/ -x c++ -std=c++11 -lstdc++ SmallPT.cpp -o SmallPT +// ./SmallPT 500 && xv image.ppm + +// Necessary for clad to work include +#include "clad/Differentiator/Differentiator.h" + +#include +#include +#include + +//TODO: Remove this define and fix float precision issues +#define float double + +// Test types (default is TEST_TYPE_BY_CLAD) +//#define TEST_TYPE_BY_HAND +#define TEST_TYPE_BY_CLAD +//#define TEST_TYPE_BY_NUM + +struct Vec { + float x, y, z; // position, also color (r,g,b) + + Vec(float x_=0, float y_=0, float z_=0) { x=x_; y=y_; z=z_; } + + Vec operator+(const Vec &b) const { return Vec(x+b.x, y+b.y, z+b.z); } + Vec operator-(const Vec &b) const { return Vec(x-b.x, y-b.y, z-b.z); } + Vec operator*(float b) const { return Vec(x*b, y*b, z*b); } + float operator*(const Vec &b) const { return x*b.x+y*b.y+z*b.z; } // dot + Vec operator%(const Vec &b) const { return Vec(y*b.z-z*b.y, z*b.x-x*b.z, x*b.y-y*b.x); } // cross + Vec mult(const Vec &b) const { return Vec(x*b.x, y*b.y, z*b.z); } + Vec& norm() { return *this = *this * (1/sqrt(x*x+y*y+z*z)); } +}; + +struct Ray { + Vec o, d; // Origin and direction + + Ray(Vec o_, Vec d_): o(o_), d(d_) {} +}; + +enum Refl_t { DIFF, SPEC, REFR }; // material types, used in radiance() + +#define inf 1e6 +#define eps 1e-6 + +// Abstract Solid + +class Solid { + public: + Vec e, c; // emission, color + Refl_t refl; // reflection type (DIFFuse, SPECular, REFRactive) + + Solid(Vec e_, Vec c_, Refl_t refl_): e(e_), c(c_), refl(refl_) {} + + // returns distance, 0 if nohit + virtual float intersect(const Ray &r) const { return 0; }; + + // returns normal vector to surface in point pt + virtual Vec normal(const Vec &pt) const { return Vec(1,0,0); }; +}; + +// Abstract Implicit Solid + +class ImplicitSolid : public Solid { + public: + + ImplicitSolid(Vec e_, Vec c_, Refl_t refl_): Solid(e_, c_, refl_) {} + + // TODO: Make this method virtual + // Return signed distance to nearest point on solid surface + float distance_func(float x, float y, float z) const { + return 0; + } + + // implicit surface intersection + // returns distance, 0 if nohit + float intersect(const Ray &r) const override { + float t=2*eps, t1, f; + Vec pt; + do { + pt=r.o+r.d*t; + f=fabs(distance_func(pt.x, pt.y, pt.z)); + t1=t; + t+=f; + if (feps ? t : ((t=b+det)>eps ? t : 0); + } +*/ + + //TODO: Remove this implementation when we make distance_func virtual + + // implicit surface intersection + // returns distance, 0 if nohit + float intersect(const Ray &ray) const override { + float t=2*eps, t1, f; + //float start_sgn = sgn(sphere_distance_func(ray.o.x, ray.o.y, ray.o.z, p, r)), current_sgn; + Vec pt; + do { + pt=ray.o+ray.d*t; + f=fabs(sphere_distance_func(pt.x, pt.y, pt.z, p, r)); + //current_sgn = sgn(f); + //if (current_sgn != start_sgn) return t; + //f=fabs(f); + t1=t; + t+=f; + if (f1 ? 1 : x; +} + +inline int toInt(float x) { + return int(pow(clamp(x),1/2.2)*255+.5); +} + +inline bool intersect(const Ray &ray, float &t, int &id) { + float d; + + t = inf; + for(int i=sizeof(scene)/sizeof(scene[0]); i--; ) { + if ((d = scene[i]->intersect(ray)) && df.y && f.x>f.z ? f.x : f.y>f.z ? f.y : f.z; // max refl + + // object intersection id map test + //return obj.c; + + cl = cl + cf.mult(obj.e); + + if (++depth>5) { + if (erand48(Xi).1 ? Vec(0,1) : Vec(1))%w).norm(), v=w%u; + Vec d = (u*cos(r1)*r2s+v*sin(r1)*r2s+w*sqrt(1-r2)).norm(); + //return obj.e + f.mult(radiance(Ray(x,d), depth, Xi)); + r = Ray(x, d); + continue; + } else if (obj.refl == SPEC) { // Ideal SPECULAR reflection + //return obj.e + f.mult(radiance(Ray(x,r.d-n*2*(n*r.d)), depth, Xi)); + r = Ray(x, r.d-n*2*(n*r.d)); + continue; + } + + // Ideal dielectric REFRACTION + Ray reflRay(x, r.d-n*2*(n*r.d)); + bool into = n*nl>0; // Ray from outside going in? + float nc=1, nt=1.5, nnt=into ? nc/nt : nt/nc, ddn=r.d*nl, cos2t; + + if ((cos2t=1-nnt*nnt*(1-ddn*ddn))<0) { // Total internal reflection + //return obj.e + f.mult(radiance(reflRay, depth, Xi)); + r = reflRay; + continue; + } + + Vec tdir = (r.d*nnt-n*((into?1:-1)*(ddn*nnt+sqrt(cos2t)))).norm(); + float a=nt-nc, b=nt+nc, R0=a*a/(b*b), c=1-(into?-ddn:tdir*n); + float Re=R0+(1-R0)*c*c*c*c*c, Tr=1-Re, P=.25+.5*Re, RP=Re/P, TP=Tr/(1-P); + + //return obj.e + f.mult(depth>2 ? // Russian roulette + // (erand48(Xi)

Date: Thu, 11 Apr 2024 23:46:59 +0000 Subject: [PATCH 3/4] Add source file --- demos/ComputerGraphics/smallpt/SmallPT | Bin 23584 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100755 demos/ComputerGraphics/smallpt/SmallPT diff --git a/demos/ComputerGraphics/smallpt/SmallPT b/demos/ComputerGraphics/smallpt/SmallPT deleted file mode 100755 index fc23c2e796ad60c753b2322e335d394327d92056..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23584 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 Date: Fri, 12 Apr 2024 05:21:55 +0000 Subject: [PATCH 4/4] Fix build errors --- demos/ComputerGraphics/cpp-smallpt-d/build.sh | 5 ++--- .../ComputerGraphics/cpp-smallpt-d/diff-tracer-1.cpp | 11 ++++++----- demos/ComputerGraphics/smallpt/build.sh | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/demos/ComputerGraphics/cpp-smallpt-d/build.sh b/demos/ComputerGraphics/cpp-smallpt-d/build.sh index 6a847dd93..c70356a69 100755 --- a/demos/ComputerGraphics/cpp-smallpt-d/build.sh +++ b/demos/ComputerGraphics/cpp-smallpt-d/build.sh @@ -1,4 +1,3 @@ #!/bin/bash -clang -Ofast -Xclang -add-plugin -Xclang clad -Xclang -load -Xclang ../../../build/lib/clad.so -I../../../include/ -x c++ -std=c++14 -lstdc++ -lm cpp-smallpt.cpp -fopenmp=libiomp5 -o cpp-smallpt "$@" - -clang -Ofast -Xclang -add-plugin -Xclang clad -Xclang -load -Xclang ../../../lib/clad.so -I../../../include/ -x c++ -std=c++14 -lstdc++ -lm diff-tracer-1.cpp -fopenmp=libiomp5 -o diff-tracer-1 "$@" +clang-18 -Ofast -Xclang -add-plugin -Xclang clad -Xclang -load -Xclang ../../../inst/lib/clad.so -I../../../include/ -x c++ -std=c++14 -lstdc++ -lm cpp-smallpt.cpp -fopenmp=libiomp5 -o cpp-smallpt "$@" +clang-18 -Ofast -Xclang -add-plugin -Xclang clad -Xclang -load -Xclang ../../../inst/lib/clad.so -I../../../include/ -x c++ -std=c++14 -lstdc++ -lm diff-tracer-1.cpp -fopenmp=libiomp5 -o diff-tracer-1 "$@" diff --git a/demos/ComputerGraphics/cpp-smallpt-d/diff-tracer-1.cpp b/demos/ComputerGraphics/cpp-smallpt-d/diff-tracer-1.cpp index d682dfe0d..eca391652 100644 --- a/demos/ComputerGraphics/cpp-smallpt-d/diff-tracer-1.cpp +++ b/demos/ComputerGraphics/cpp-smallpt-d/diff-tracer-1.cpp @@ -99,8 +99,9 @@ void performStep(double& theta_0, double& theta_1, double& theta_2, Dataset dt, // The cost function to minimize using gradient descent // theta_x are the parameters to learn; x, y are the inputs and outputs of f double cost(double theta_0, double theta_1, double theta_2, Dataset dt) { - char fileName[4096]; - snprintf(fileName, sizeof(fileName), "image-%d.ppm", dt.step++); + const size_t fileNameMaxSize = 4096; + char fileName[fileNameMaxSize]; + snprintf(fileName, fileNameMaxSize, "image-%d.ppm", dt.step++); Render( scene, *(&scene + 1) - scene, // Geometry, Lights dt.Vx, dt.Vy, dt.Vz, // Params - Center of one sphere // must be Vector3() @@ -151,9 +152,9 @@ void optimize(double theta[3], Dataset dt, unsigned int maxSteps, double eps) { std::cout << "Steps #" << currentStep << " Theta 0: " << theta[0] << " Theta 1: " << theta[1] << " Theta 2: " << theta[2] << std::endl; - hasConverged = abs(diff[0] - theta[0]) <= eps && - abs(diff[1] - theta[1]) <= eps && - abs(diff[2] - theta[2]) <= eps; + hasConverged = std::abs(diff[0] - theta[0]) <= eps && + std::abs(diff[1] - theta[1]) <= eps && + std::abs(diff[2] - theta[2]) <= eps; diff = theta; } while (currentStep++ < maxSteps && !hasConverged); diff --git a/demos/ComputerGraphics/smallpt/build.sh b/demos/ComputerGraphics/smallpt/build.sh index 21078bb5b..9de7d5b1a 100755 --- a/demos/ComputerGraphics/smallpt/build.sh +++ b/demos/ComputerGraphics/smallpt/build.sh @@ -1,2 +1,2 @@ #!/bin/bash -clang -Ofast -Xclang -add-plugin -Xclang clad -Xclang -load -Xclang ../../../build/lib/clad.so -I../../../include/ -I/usr/lib/gcc/x86_64-linux-gnu/10/include -x c++ -std=c++14 -lstdc++ -lm SmallPT.cpp -fopenmp=libiomp5 -o SmallPT "$@" +clang-18 -Ofast -Xclang -add-plugin -Xclang clad -Xclang -load -Xclang ../../../inst/lib/clad.so -I../../../include/ -I/usr/lib/gcc/x86_64-linux-gnu/10/include -x c++ -std=c++14 -lstdc++ -lm SmallPT.cpp -fopenmp=libiomp5 -o SmallPT "$@"