рдПрдХ рд╣рдлреНрддреЗ рдкрд╣рд▓реЗ, рдореИрдВрдиреЗ рдЕрдкрдиреЗ
рдХрдВрдкреНрдпреВрдЯрд░ рдЧреНрд░рд╛рдлрд┐рдХреНрд╕ рд╡реНрдпрд╛рдЦреНрдпрд╛рди рдкрд╛рдареНрдпрдХреНрд░рдо рд╕реЗ
рдПрдХ рдФрд░ рдЕрдзреНрдпрд╛рдп рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд┐рдпрд╛ ; рдЖрдЬ рд╣рдо рдлрд┐рд░ рд╕реЗ рд░реЗ рдЯреНрд░реЗрд╕рд┐рдВрдЧ рдкрд░ рд▓реМрдЯ рдЖрдПрдВрдЧреЗ, рд▓реЗрдХрд┐рди рдЗрд╕ рдмрд╛рд░ рд╣рдо рддреБрдЪреНрдЫ рдХреНрд╖реЗрддреНрд░реЛрдВ рдХреЛ рдкреНрд░рджрд╛рди рдХрд░рдиреЗ рд╕реЗ рдереЛрдбрд╝рд╛ рдЖрдЧреЗ рдмрдврд╝реЗрдВрдЧреЗред рдореБрдЭреЗ рдлреЛрдЯреЛрд░рд┐рдЕрд▓рд┐рдЬрд╝реНрдо рдХреА рдЬрд╝рд░реВрд░рдд рдирд╣реАрдВ рд╣реИ, рдХрд╛рд░реНрдЯреВрди рдХреЗ рдкреНрд░рдпреЛрдЬрдиреЛрдВ рдХреЗ рд▓рд┐рдП,
рдРрд╕рд╛ рд╡рд┐рд╕реНрдлреЛрдЯ , рдпрд╣ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ, рдиреАрдЪреЗ рдЖ рдЬрд╛рдПрдЧрд╛ред
рд╣рдореЗрд╢рд╛ рдХреА рддрд░рд╣, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рд╣рдорд╛рд░реЗ рдирд┐рдкрдЯрд╛рди рдореЗрдВ рдХреЗрд╡рд▓ рдПрдХ рдирдВрдЧреЗ рд╕рдВрдХрд▓рдХ рд╣реИрдВ, рдХрд┐рд╕реА рднреА рддреАрд╕рд░реЗ рдкрдХреНрд╖ рдХреЗ рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдореИрдВ рд╡рд┐рдВрдбреЛ рдореИрдиреЗрдЬрд░, рдорд╛рдЙрд╕ / рдХреАрдмреЛрд░реНрдб рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рдФрд░ рдЗрд╕реА рддрд░рд╣ рд╕реЗ рдкрд░реЗрд╢рд╛рди рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ред рд╣рдорд╛рд░реЗ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдбрд┐рд╕реНрдХ рдкрд░ рд╕рд╣реЗрдЬреА рдЧрдИ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рддрд╕реНрд╡реАрд░ рд╣реЛрдЧреАред рдореИрдВ рдЧрддрд┐ / рдЕрдиреБрдХреВрд▓рди рдХрд╛ рдмрд┐рд▓реНрдХреБрд▓ рднреА рдкреАрдЫрд╛ рдирд╣реАрдВ рдХрд░рддрд╛, рдореЗрд░рд╛ рд▓рдХреНрд╖реНрдп рдореВрд▓ рд╕рд┐рджреНрдзрд╛рдВрддреЛрдВ рдХреЛ рджрд┐рдЦрд╛рдирд╛ рд╣реИред
рдХреБрд▓ рдорд┐рд▓рд╛рдХрд░, рдРрд╕реА рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдХреЗ рддрд╣рдд рдХреЛрдб рдХреА 180 рд▓рд╛рдЗрдиреЛрдВ рдореЗрдВ рдРрд╕реА рддрд╕реНрд╡реАрд░ рдХреИрд╕реЗ рдЦреАрдВрдЪрдиреА рд╣реИ?

рдореБрдЭреЗ рдПрдХ рдПрдирд┐рдореЗрдЯреЗрдб рдЬрд┐рдлрд╝ (рдЫрд╣ рдореАрдЯрд░) рдбрд╛рд▓реЗрдВ:

рдФрд░ рдЕрдм рд╣рдо рдкреВрд░реЗ рдХрд╛рд░реНрдп рдХреЛ рдХрдИ рдЪрд░рдгреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░реЗрдВрдЧреЗ:
рд╕реНрдЯреЗрдЬ рдПрдХ: рдкрд┐рдЫрд▓рд╛ рд▓реЗрдЦ рдкрдврд╝реЗрдВ
рд╣рд╛рдБ, рдмрд┐рд▓реНрдХреБрд▓ред
рдкрд┐рдЫрд▓реЗ рдЕрдзреНрдпрд╛рдп рдХреЛ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдмрд╕реЗ рдкрд╣рд▓реА рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдХрд┐рд░рдг рдЕрдиреБрд░реЗрдЦрдг рдХреА рдореВрд▓ рдмрд╛рддреЗрдВ рдмрддрд╛рддреА рд╣реИрдВред рдпрд╣ рдмрд╣реБрдд рдХрдо рд╣реИ, рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рд╕рднреА рдкреНрд░рддрд┐рдмрд┐рдВрдм-рдЕрдкрд╡рд░реНрддрди рдХреЛ рдкрдврд╝рд╛ рдирд╣реАрдВ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдХрдо рд╕реЗ рдХрдо рдЬрдм рддрдХ рдлреИрд▓рд╛рдирд╛ рдкреНрд░рдХрд╛рд╢ рд╡реНрдпрд╡рд╕реНрдерд╛ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ рддрдм рддрдХ рдореИрдВ рдЗрд╕реЗ рдкрдврд╝рдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВред рдХреЛрдб рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИ, рд▓реЛрдЧ рдЗрд╕реЗ рдорд╛рдЗрдХреНрд░реЛрдХрдВрдЯреНрд░реЛрд▓рд░ рдкрд░ рднреА рдЪрд▓рд╛рддреЗ рд╣реИрдВ:

рд╕реНрдЯреЗрдЬ рджреЛ: рдбреНрд░рд╛ рдПрдХ рдХреНрд╖реЗрддреНрд░
рдЪрд▓реЛ рд╕рд╛рдордЧреНрд░реА рдпрд╛ рдкреНрд░рдХрд╛рд╢ рд╡реНрдпрд╡рд╕реНрдерд╛ рд╕реЗ рдкрд░реЗрд╢рд╛рди рдХрд┐рдП рдмрд┐рдирд╛ рдПрдХ рдХреНрд╖реЗрддреНрд░ рдмрдирд╛рддреЗ рд╣реИрдВред рд╕рд╛рджрдЧреА рдХреЗ рд▓рд┐рдП, рдпрд╣ рдХреНрд╖реЗрддреНрд░ рдирд┐рд░реНрджреЗрд╢рд╛рдВрдХ рдХреЗ рдХреЗрдВрджреНрд░ рдореЗрдВ рд░рд╣реЗрдЧрд╛ред рдЗрд╕ рдЪрд┐рддреНрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдореИрдВ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ:
рдпрд╣рд╛рдВ рдХреЛрдб рджреЗрдЦреЗрдВ, рд▓реЗрдХрд┐рди рдореИрдВ рдЖрдкрдХреЛ рд▓реЗрдЦ рдХреЗ рдкрд╛рда рдореЗрдВ рдореБрдЦреНрдп рд░реВрдк рд╕реЗ рд╕реАрдзреЗ рдкреНрд░рд╡реЗрд╢ рджреЗрддрд╛ рд╣реВрдВ:
#define _USE_MATH_DEFINES #include <cmath> #include <algorithm> #include <limits> #include <iostream> #include <fstream> #include <vector> #include "geometry.h" const float sphere_radius = 1.5; float signed_distance(const Vec3f &p) { return p.norm() - sphere_radius; } bool sphere_trace(const Vec3f &orig, const Vec3f &dir, Vec3f &pos) { pos = orig; for (size_t i=0; i<128; i++) { float d = signed_distance(pos); if (d < 0) return true; pos = pos + dir*std::max(d*0.1f, .01f); } return false; } int main() { const int width = 640; const int height = 480; const float fov = M_PI/3.; std::vector<Vec3f> framebuffer(width*height); #pragma omp parallel for for (size_t j = 0; j<height; j++) { // actual rendering loop for (size_t i = 0; i<width; i++) { float dir_x = (i + 0.5) - width/2.; float dir_y = -(j + 0.5) + height/2.; // this flips the image at the same time float dir_z = -height/(2.*tan(fov/2.)); Vec3f hit; if (sphere_trace(Vec3f(0, 0, 3), Vec3f(dir_x, dir_y, dir_z).normalize(), hit)) { // the camera is placed to (0,0,3) and it looks along the -z axis framebuffer[i+j*width] = Vec3f(1, 1, 1); } else { framebuffer[i+j*width] = Vec3f(0.2, 0.7, 0.8); // background color } } } std::ofstream ofs("./out.ppm", std::ios::binary); // save the framebuffer to file ofs << "P6\n" << width << " " << height << "\n255\n"; for (size_t i = 0; i < height*width; ++i) { for (size_t j = 0; j<3; j++) { ofs << (char)(std::max(0, std::min(255, static_cast<int>(255*framebuffer[i][j])))); } } ofs.close(); return 0; }
рд╡реЗрдХреНрдЯрд░ рд╡рд░реНрдЧ рдЬреНрдпрд╛рдорд┐рддрд┐ рдореЗрдВ рд░рд╣рддрд╛ рд╣реИред рдлрд╝рд╛рдЗрд▓ рдореЗрдВ, рдореИрдВ рдЗрд╕реЗ рдпрд╣рд╛рдБ рдирд╣реАрдВ рдмрддрд╛рддрд╛: рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╡рд╣рд╛рдБ рд╕рдм рдХреБрдЫ рддреБрдЪреНрдЫ рд╣реИ, рджреЛ рдФрд░ рддреАрди рдЖрдпрд╛рдореА рд╡реИрдХреНрдЯрд░реЛрдВ рдХрд╛ рд╕рд░рд▓ рд╣реЗрд░рдлреЗрд░ (рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдШрдЯрд╛рд╡, рдЕрд╕рд╛рдЗрдирдореЗрдВрдЯ, рдПрдХ рд╕реНрдХреЗрд▓рд░ рджреНрд╡рд╛рд░рд╛ рдЧреБрдгрд╛, рд╕реНрдХреЗрд▓рд░ рдЙрддреНрдкрд╛рдж), рдФрд░ рджреВрд╕рд░реА рдмрд╛рддред
gbg рдиреЗ рдкрд╣рд▓реЗ рд╣реА рдЗрд╕реЗ рдХрдВрдкреНрдпреВрдЯрд░ рдЧреНрд░рд╛рдлрд┐рдХреНрд╕ рдкрд░ рдПрдХ рд╡реНрдпрд╛рдЦреНрдпрд╛рди рдкрд╛рдареНрдпрдХреНрд░рдо рдХреЗ рд╣рд┐рд╕реНрд╕реЗ рдХреЗ рд░реВрдк рдореЗрдВ
рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ
рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рд╣реИред
рдореИрдВ рддрд╕реНрд╡реАрд░ рдХреЛ
рдкреАрдкреАрдПрдо рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рд╕рд╣реЗрдЬрддрд╛ рд╣реВрдВ; рдпрд╣ рдЫрд╡рд┐рдпреЛрдВ рдХреЛ рдмрдЪрд╛рдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рдЖрд╕рд╛рди рддрд░реАрдХрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рд╣рдореЗрд╢рд╛ рдЖрдЧреЗ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдмрд╕реЗ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдирд╣реАрдВ рд╣реИред
рдЗрд╕рд▓рд┐рдП, рдореБрдЦреНрдп () рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ, рдореЗрд░реЗ рдкрд╛рд╕ рджреЛ рдЪрдХреНрд░ рд╣реИрдВ: рджреВрд╕рд░рд╛ рдЪрдХреНрд░ рдмрд╕ рдЫрд╡рд┐ рдХреЛ рдбрд┐рд╕реНрдХ рдкрд░ рд╕рд╣реЗрдЬрддрд╛ рд╣реИ, рдФрд░ рдкрд╣рд▓рд╛ рдЪрдХреНрд░ рдЫрд╡рд┐ рдХреЗ рд╕рднреА рдкрд┐рдХреНрд╕реЗрд▓ рд╕реЗ рдЧреБрдЬрд░рддрд╛ рд╣реИ, рдЗрд╕ рдкрд┐рдХреНрд╕реЗрд▓ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХреИрдорд░реЗ рд╕реЗ рдПрдХ рдХрд┐рд░рдг рдХрд╛ рдЙрддреНрд╕рд░реНрдЬрди рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдпрд╣ рджреЗрдЦрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдХреНрдпрд╛ рдпрд╣ рдХрд┐рд░рдг рд╣рдорд╛рд░реЗ рдХреНрд╖реЗрддреНрд░ рдХреЗ рд╕рд╛рде рд╣реИред
рдзреНрдпрд╛рди рджреЗрдВ, рд▓реЗрдЦ рдХрд╛ рдореБрдЦреНрдп рд╡рд┐рдЪрд╛рд░: рдпрджрд┐ рдкрд┐рдЫрд▓реЗ рд▓реЗрдЦ рдореЗрдВ рд╣рдордиреЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдгрд╛рддреНрдордХ рд░реВрдк рд╕реЗ рдПрдХ рдХрд┐рд░рдг рдФрд░ рдПрдХ рдЧреЛрд▓реЗ рдХреЗ рдкреНрд░рддрд┐рдЪреНрдЫреЗрджрди рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд┐рдпрд╛ рдерд╛, рддреЛ рдЕрдм рдореИрдВ рдЗрд╕реЗ рд╕рдВрдЦреНрдпрд╛рддреНрдордХ рд░реВрдк рд╕реЗ рдЧрд┐рдирддрд╛ рд╣реВрдВред рд╡рд┐рдЪрд╛рд░ рд╕рд░рд▓ рд╣реИ: рдХреНрд╖реЗрддреНрд░ рдореЗрдВ x ^ 2 + y ^ 2 + z ^ 2 - r ^ 2 = 0 рдХрд╛ рдПрдХ рд╕рдореАрдХрд░рдг рд╣реИ; рд▓реЗрдХрд┐рди рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рдлрд╝рдВрдХреНрд╢рди f (x, y, z) = x ^ 2 + y ^ 2 + z ^ 2 - r ^ 2 рдкреВрд░реЗ рд╕реНрдерд╛рди рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдХреНрд╖реЗрддреНрд░ рдХреЗ рдЕрдВрджрд░, рдлрд╝рдВрдХреНрд╢рди f (x, y, z) рдореЗрдВ рдирдХрд╛рд░рд╛рддреНрдордХ рдорд╛рди рд╣реЛрдВрдЧреЗ, рдФрд░ рдХреНрд╖реЗрддреНрд░ рдХреЗ рдмрд╛рд╣рд░, рдпрд╣ рд╕рдХрд╛рд░рд╛рддреНрдордХ рд╣реЛрдЧрд╛ред рдпрд╣реА рд╣реИ, рдлрд╝рдВрдХреНрд╢рди f (x, y, z) рдмрд┐рдВрджреБ (x, y, z) рдХреЗ рд▓рд┐рдП рд╣рдорд╛рд░реЗ рдЧреЛрд▓реЗ рдХреЗ рд▓рд┐рдП рджреВрд░реА (рдПрдХ рд╕рдВрдХреЗрдд рдХреЗ рд╕рд╛рде!) рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдЬрдм рддрдХ рд╣рдо рдКрдм рдирд╣реАрдВ рдЬрд╛рддреЗ рддрдм рддрдХ рд╣рдо рдмреАрдо рдХреЗ рд╕рд╛рде рдмрд╕ рдлрд┐рд╕рд▓рддреЗ рд╣реИрдВ рдпрд╛ рдлрд╝рдВрдХреНрд╢рди рдЪ (x, y, z) рдирдХрд╛рд░рд╛рддреНрдордХ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред Sphere_trace () рдлрд╝рдВрдХреНрд╢рди рдмрд╕ рдпрд╣реА рдХрд░рддрд╛ рд╣реИред
рд╕реНрдЯреЗрдЬ рддреАрди: рдЖрджрд┐рдо рдкреНрд░рдХрд╛рд╢
рдЪрд▓реЛ рд╕рд░рд▓рддрдо рд╡рд┐рд╕рд░рд┐рдд рдкреНрд░рдХрд╛рд╢ рдХреЛ рдХреЛрдб рдХрд░рддреЗ рд╣реИрдВ, рдореИрдВ рдЖрдЙрдЯрдкреБрдЯ рдкрд░ рдРрд╕реА рддрд╕реНрд╡реАрд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ:

рдкрд┐рдЫрд▓реЗ рд▓реЗрдЦ рдХреА рддрд░рд╣, рдкрдврд╝рдиреЗ рдореЗрдВ рдЖрд╕рд╛рдиреА рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рдПрдХ рдХрджрдо = рдПрдХ рдХрдорд┐рдЯ рдХрд┐рдпрд╛ред рдпрд╣рд╛рдВ рдкрд░рд┐рд╡рд░реНрддрди
рджреЗрдЦреЗ рдЬрд╛ рд╕рдХрддреЗ
рд╣реИрдВ ред
рдлреИрд▓рд╛рдирд╛ рдкреНрд░рдХрд╛рд╢ рдХреЗ рд▓рд┐рдП, рд╕рддрд╣ рдХреЗ рд╕рд╛рде рдмреАрдо рдХреЗ рдЪреМрд░рд╛рд╣реЗ рдХреЗ рдмрд┐рдВрджреБ рдХреА рдЧрдгрдирд╛ рдХрд░рдирд╛ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реИ, рд╣рдореЗрдВ рдЗрд╕ рдмрд┐рдВрджреБ рдкрд░ рд╕рддрд╣ рдХреЗ рд╕рд╛рдорд╛рдиреНрдп рд╡реЗрдХреНрдЯрд░ рдХреЛ рдЬрд╛рдирдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рд╕рддрд╣ рдкрд░ рджреВрд░реА рдХреЗ рд╣рдорд╛рд░реЗ рдХрд╛рд░реНрдп рдореЗрдВ рд╕рд╛рдзрд╛рд░рдг
рдкрд░рд┐рдорд┐рдд рдЕрдВрддрд░ рджреНрд╡рд╛рд░рд╛ рдореБрдЭреЗ рдпрд╣ рд╕рд╛рдорд╛рдиреНрдп рд╡реЗрдХреНрдЯрд░ рдкреНрд░рд╛рдкреНрдд рд╣реБрдЖ:
Vec3f distance_field_normal(const Vec3f &pos) { const float eps = 0.1; float d = signed_distance(pos); float nx = signed_distance(pos + Vec3f(eps, 0, 0)) - d; float ny = signed_distance(pos + Vec3f(0, eps, 0)) - d; float nz = signed_distance(pos + Vec3f(0, 0, eps)) - d; return Vec3f(nx, ny, nz).normalize(); }
рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдЪреВрдВрдХрд┐ рд╣рдо рдПрдХ рдХреНрд╖реЗрддреНрд░ рдмрдирд╛ рд░рд╣реЗ рд╣реИрдВ, рд╕рд╛рдорд╛рдиреНрдп рдХреЛ рдмрд╣реБрдд рдЖрд╕рд╛рди рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рднрд╡рд┐рд╖реНрдп рдХреЗ рд▓рд┐рдП рдПрдХ рд░рд┐рдЬрд░реНрд╡ рдХреЗ рд╕рд╛рде рдРрд╕рд╛ рдХрд┐рдпрд╛ред
рд╕реНрдЯреЗрдЬ рдЪрд╛рд░: рд╣рдорд╛рд░реЗ рдХреНрд╖реЗрддреНрд░ рдкрд░ рдПрдХ рдкреИрдЯрд░реНрди рдмрдирд╛рддреЗ рд╣реИрдВ
рдФрд░ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдХрд┐рд╕реА рддрд░рд╣ рдХрд╛ рдкреИрдЯрд░реНрди рдмрдирд╛рддреЗ рд╣реИрдВ:

рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдкрд┐рдЫрд▓реЗ рдХреЛрдб рдореЗрдВ, рдореИрдВрдиреЗ
рдХреЗрд╡рд▓ рджреЛ рд▓рд╛рдЗрдиреЗрдВ рдмрджрд▓
рджреАрдВ!рдореИрдВрдиреЗ рдпрд╣ рдХреИрд╕реЗ рдХрд┐рдпрд╛? рдмреЗрд╢рдХ, рдореЗрд░реЗ рдкрд╛рд╕ рдХреЛрдИ рдмрдирд╛рд╡рдЯ рдирд╣реАрдВ рд╣реИред рдореИрдВрдиреЗ рдЕрднреА рдлрд╝рдВрдХреНрд╢рди g (x, y, z) = sin (x) * sin (y) * sin (z) рд▓рд┐рдпрд╛; рдЗрд╕реЗ рдлрд┐рд░ рд╕реЗ рдкреВрд░реЗ рдЕрдВрддрд░рд┐рдХреНрд╖ рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЬрдм рдореЗрд░реА рдХрд┐рд░рдг рдХрд┐рд╕реА рдмрд┐рдВрджреБ рдкрд░ рдЧреЛрд▓реЗ рдХреЛ рдкрд╛рд░ рдХрд░рддреА рд╣реИ, рддреЛ рдЗрд╕ рдмрд┐рдВрджреБ рдкрд░ рдлрд╝рдВрдХреНрд╢рди рдЬреА (x, y, z) рдХрд╛ рдорд╛рди рдореЗрд░реЗ рд▓рд┐рдП рдкрд┐рдХреНрд╕реЗрд▓ рдХрд╛ рд░рдВрдЧ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИред
рд╡реИрд╕реЗ, рдЧреЛрд▓реЗ рдХреЗ рдЪрд╛рд░реЛрдВ рдУрд░ рд╕рдВрдХреЗрдВрджреНрд░рд┐рдд рд╣рд▓рдХреЛрдВ рдкрд░ рдзреНрдпрд╛рди рджреЗрдВ - рдпреЗ рдЪреМрд░рд╛рд╣реЗ рдХреА рдореЗрд░реА рд╕рдВрдЦреНрдпрд╛рддреНрдордХ рдЧрдгрдирд╛ рдХреА рдХрд▓рд╛рдХреГрддрд┐рдпрд╛рдВ рд╣реИрдВред
рдкрд╛рдВрдЪ рдХрджрдо: рд╡рд┐рд╕реНрдерд╛рдкрди рдорд╛рдирдЪрд┐рддреНрд░рдг
рдореИрдВ рдЗрд╕ рдкреИрдЯрд░реНрди рдХреЛ рдХреНрдпреЛрдВ рдЦреАрдВрдЪрдирд╛ рдЪрд╛рд╣рддрд╛ рдерд╛? рдФрд░ рд╡рд╣ рдореБрдЭреЗ рдРрд╕рд╛ рд╣реЗрдЬрд▓ рдмрдирд╛рдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдЧрд╛:

рдЬрд╣рд╛рдВ рдореЗрд░рд╛ рдкреИрдЯрд░реНрди рдХрд╛рд▓рд╛ рдерд╛, рдореИрдВ рд╣рдорд╛рд░реЗ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдПрдХ рдЫреЗрдж рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ, рдФрд░ рдЬрд╣рд╛рдВ рдпрд╣ рд╕рдлреЗрдж рдерд╛, рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд, рдХреВрдмрдбрд╝ рдХреЛ рдлреИрд▓рд╛рдПрдВред
рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдХреЛрдб рдореЗрдВ рдХреЗрд╡рд▓
рддреАрди рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреЛ
рдмрджрд▓реЗрдВ :
float signed_distance(const Vec3f &p) { Vec3f s = Vec3f(p).normalize(sphere_radius); float displacement = sin(16*sx)*sin(16*sy)*sin(16*sz)*noise_amplitude; return p.norm() - (sphere_radius + displacement); }
рдпрд╣реА рд╣реИ, рдореИрдВрдиреЗ рджреВрд░реА рдХреА рдЧрдгрдирд╛ рдХреЛ рд╣рдорд╛рд░реА рд╕рддрд╣ рдкрд░ рдмрджрд▓ рджрд┐рдпрд╛, рдЗрд╕реЗ x ^ 2 + y ^ 2 + z ^ 2 - r ^ 2 - рдкрд╛рдк (x) * рдкрд╛рдк (y) * рдкрд╛рдк (z) рдХреЗ рд░реВрдк рдореЗрдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рд╣рдордиреЗ рдПрдХ
рдирд┐рд╣рд┐рдд рдХрд╛рд░реНрдп рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ред
рдЫрд╣ рдЪрд░рдг: рдПрдХ рдФрд░ рдирд┐рд╣рд┐рдд рдХрд╛рд░реНрдп
рдФрд░ рдореИрдВ рдХреЗрд╡рд▓ рд╣рдорд╛рд░реЗ рдХреНрд╖реЗрддреНрд░ рдХреА рд╕рддрд╣ рдкрд░ рд╕реНрдерд┐рдд рдмрд┐рдВрджреБрдУрдВ рдХреЗ рд▓рд┐рдП рд╕рд╛рдЗрди рдХреЗ рдЙрддреНрдкрд╛рдж рдХрд╛ рдореВрд▓реНрдпрд╛рдВрдХрди рдХреНрдпреЛрдВ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ? рдЖрдЗрдП рдЗрд╕ рддрд░рд╣ рд╕реЗ рд╣рдорд╛рд░реЗ рдирд┐рд╣рд┐рдд рдХрд╛рд░реНрдп рдХреЛ рдлрд┐рд░ рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реЗрдВ:
float signed_distance(const Vec3f &p) { float displacement = sin(16*px)*sin(16*py)*sin(16*pz)*noise_amplitude; return p.norm() - (sphere_radius + displacement); }
рдкрд┐рдЫрд▓реЗ рдХреЛрдб рдХреЗ рд╕рд╛рде рдЕрдВрддрд░ рдмрд╣реБрдд рдЫреЛрдЯрд╛ рд╣реИ,
рдЕрдВрддрд░ рдХреЛ
рджреЗрдЦрдирд╛ рдмреЗрд╣рддрд░ рд╣реИред рдпрд╣рд╛рдБ рдкрд░рд┐рдгрд╛рдо рд╣реИ:

рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдо рдЕрдкрдиреЗ рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рдбрд┐рд╕реНрдХрдиреЗрдХреНрдЯ рдХрд┐рдП рдЧрдП рдШрдЯрдХреЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ!
рдЪрд░рдг рд╕рд╛рдд: рдЫрджреНрдо рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рд╢реЛрд░
рдкрд┐рдЫрд▓реА рддрд╕реНрд╡реАрд░ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдПрдХ рд╡рд┐рд╕реНрдлреЛрдЯ рд╕реЗ рджреВрд░ рд╕реЗ рд╢реБрд░реВ рд╣реЛ рд░рд╣реА рд╣реИ, рд▓реЗрдХрд┐рди рд╕рд╛рдЗрди рдХреЗ рдЙрддреНрдкрд╛рдж рдХрд╛ рдПрдХ рдмрд╣реБрдд рд╣реА рдирд┐рдпрдорд┐рдд рдкреИрдЯрд░реНрди рд╣реИред рд╣рдореЗрдВ рдХреБрдЫ рдФрд░ "рдлрдЯреЗ" рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА, рдЕрдзрд┐рдХ "рдпрд╛рджреГрдЪреНрдЫрд┐рдХ" рдлрд╝рдВрдХреНрд╢рди ...
рдкреЗрд░реНрд▓рд┐рди рдХрд╛ рд╢реЛрд░ рд╣рдорд╛рд░реА рд╕рд╣рд╛рдпрддрд╛ рдХреЗ рд▓рд┐рдП рдЖрдПрдЧрд╛ред рдпрд╣рд╛рдБ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд╕реЗ рд╣реИ рдЬреЛ рд╣рдореЗрдВ рд╕рд╛рдЗрди рдХреЗ рдЙрддреНрдкрд╛рдж рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдмрд╣реБрдд рдмреЗрд╣рддрд░ рд╣реЛрдЧрд╛:

рдЗрд╕ рддрд░рд╣ рдХреЗ рд╢реЛрд░ рдХреЛ рдХреИрд╕реЗ рдЙрддреНрдкрдиреНрди рдХрд┐рдпрд╛ рдЬрд╛рдП, рдпрд╣ рдереЛрдбрд╝рд╛ рдЕрдкрдорд╛рдирдЬрдирдХ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣рд╛рдВ рдореБрдЦреНрдп рд╡рд┐рдЪрд╛рд░ рд╣реИ: рдЖрдкрдХреЛ рд╡рд┐рднрд┐рдиреНрди рд╕рдВрдХрд▓реНрдкреЛрдВ рдХреЗ рд╕рд╛рде рдпрд╛рджреГрдЪреНрдЫрд┐рдХ рдЫрд╡рд┐рдпрд╛рдВ рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЙрдиреНрд╣реЗрдВ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЪрд┐рдХрдирд╛ рдХрд░реЗрдВ:

рдФрд░ рдлрд┐рд░ рдмрд╕ рдЙрдиреНрд╣реЗрдВ рдпреЛрдЧ:
рдпрд╣рд╛рдБ рдФрд░
рдпрд╣рд╛рдБ рдкрдврд╝реЗрдВред
рдЖрдЗрдП
рдХреБрдЫ рдХреЛрдб рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ рдЬреЛ рдЗрд╕ рд╢реЛрд░ рдХреЛ рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЗрд╕ рдЪрд┐рддреНрд░ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ:

рдХреГрдкрдпрд╛ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рд░реЗрдВрдбрд░рд┐рдВрдЧ рдХреЛрдб рдореЗрдВ рдореИрдВрдиреЗ рдХреБрдЫ рднреА рдирд╣реАрдВ рдмрджрд▓рд╛ рд╣реИ, рдХреЗрд╡рд▓ рд╡рд╣ рдлрд╝рдВрдХреНрд╢рди рдЬреЛ "рд░рд┐рдВрдХрд▓реНрд╕" рд╣рдорд╛рд░реЗ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдмрджрд▓ рдЧрдпрд╛ рд╣реИред
рд╕реНрдЯреЗрдЬ рдЖрда, рдЕрдВрддрд┐рдо: рд░рдВрдЧ рдЬреЛрдбрд╝реЗрдВ
рдЗрд╕ рдХрдорд┐рдЯ рдореЗрдВ рдореИрдВрдиреЗ рдХреЗрд╡рд▓ рдПрдХ рдЪреАрдЬ
рдмрджрд▓реА рд╣реИ рдХрд┐ рдПрдХ рд╕рдорд╛рди рд╕рдлреЗрдж рд░рдВрдЧ рдХреЗ рдмрдЬрд╛рдп, рдореИрдВрдиреЗ рдПрдХ рд░рдВрдЧ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рд╣реИ рдЬреЛ рд░реИрдЦрд┐рдХ рд░реВрдк рд╕реЗ рд╢реЛрд░ рдХреА рдорд╛рддреНрд░рд╛ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ:
Vec3f palette_fire(const float d) { const Vec3f yellow(1.7, 1.3, 1.0);
рдпрд╣ рдкрд╛рдВрдЪ рдкреНрд░рдореБрдЦ рд░рдВрдЧреЛрдВ рдХреЗ рдмреАрдЪ рдПрдХ рд╕рд░рд▓ рд░реИрдЦрд┐рдХ рдврд╛рд▓ рд╣реИред рдЦреИрд░, рдпрд╣рд╛рдБ рддрд╕реНрд╡реАрд░ рд╣реИ!

рдирд┐рд╖реНрдХрд░реНрд╖
рдЗрд╕ рдХрд┐рд░рдг рдЕрдиреБрд░реЗрдЦрдг рддрдХрдиреАрдХ рдХреЛ рдХрд┐рд░рдг рдорд╛рд░реНрдЪрд┐рдВрдЧ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рд╣реЛрдорд╡рд░реНрдХ рд╕рд░рд▓ рд╣реИ: рд╣рдорд╛рд░реЗ рд╡рд┐рд╕реНрдлреЛрдЯ рдХреЗ рд╕рд╛рде рд▓рд╛рдареА рдФрд░ рдкреНрд░рддрд┐рдмрд┐рдВрдм рдХреЗ рд╕рд╛рде рдкрд┐рдЫрд▓реА рдХрд┐рд░рдг рдЕрдиреБрд░реЗрдЦрдХ рдХреЛ рдкрд╛рд░ рдХрд░реЗрдВ, рддрд╛рдХрд┐ рд╡рд┐рд╕реНрдлреЛрдЯ рднреА рдЪрд╛рд░реЛрдВ рдУрд░ рд╕рдм рдХреБрдЫ рд░реЛрд╢рди рдХрд░реЗ! рд╡реИрд╕реЗ, рдЗрд╕ рд╡рд┐рд╕реНрдлреЛрдЯ рдореЗрдВ рдкрд╛рд░рднрд╛рд╕реА рдХрд╛ рдЕрднрд╛рд╡ рд╣реИред