|
8 | 8 | #include "geometry.h" |
9 | 9 |
|
10 | 10 | const float sphere_radius = 1.5; |
11 | | -const float noise_amplitude = 0.2; |
| 11 | +const float noise_amplitude = 1.0; |
| 12 | + |
| 13 | +template <typename T> inline T lerp(const T &v0, const T &v1, float t) { |
| 14 | + return v0 + (v1-v0)*std::max(0.f, std::min(1.f, t)); |
| 15 | +} |
| 16 | + |
| 17 | +float hash(const float n) { |
| 18 | + float x = sin(n)*43758.5453f; |
| 19 | + return x-floor(x); |
| 20 | +} |
| 21 | + |
| 22 | +float noise(const Vec3f &x) { |
| 23 | + Vec3f p(floor(x.x), floor(x.y), floor(x.z)); |
| 24 | + Vec3f f(x.x-p.x, x.y-p.y, x.z-p.z); |
| 25 | + f = f*(f*(Vec3f(3.f, 3.f, 3.f)-f*2.f)); |
| 26 | + float n = p*Vec3f(1.f, 57.f, 113.f); |
| 27 | + return lerp(lerp( |
| 28 | + lerp(hash(n + 0.f), hash(n + 1.f), f.x), |
| 29 | + lerp(hash(n + 57.f), hash(n + 58.f), f.x), f.y), |
| 30 | + lerp( |
| 31 | + lerp(hash(n + 113.f), hash(n + 114.f), f.x), |
| 32 | + lerp(hash(n + 170.f), hash(n + 171.f), f.x), f.y), f.z); |
| 33 | +} |
| 34 | + |
| 35 | +Vec3f rotate(const Vec3f &v) { |
| 36 | + return Vec3f(Vec3f(0.00, 0.80, 0.60)*v, Vec3f(-0.80, 0.36, -0.48)*v, Vec3f(-0.60, -0.48, 0.64)*v); |
| 37 | +} |
| 38 | + |
| 39 | +float fractal_brownian_motion(const Vec3f &x) { |
| 40 | + Vec3f p = rotate(x); |
| 41 | + float f = 0; |
| 42 | + f += 0.5000*noise(p); p = p*2.32; |
| 43 | + f += 0.2500*noise(p); p = p*3.03; |
| 44 | + f += 0.1250*noise(p); p = p*2.61; |
| 45 | + f += 0.0625*noise(p); |
| 46 | + return f/0.9375; |
| 47 | +} |
12 | 48 |
|
13 | 49 | float signed_distance(const Vec3f &p) { |
14 | | - float displacement = sin(16*p.x)*sin(16*p.y)*sin(16*p.z)*noise_amplitude; |
| 50 | + float displacement = -fractal_brownian_motion(p*3.4)*noise_amplitude; |
15 | 51 | return p.norm() - (sphere_radius + displacement); |
16 | 52 | } |
17 | 53 |
|
18 | 54 | bool sphere_trace(const Vec3f &orig, const Vec3f &dir, Vec3f &pos) { |
| 55 | + if (orig*orig - pow(orig*dir, 2) > pow(sphere_radius, 2)) return false; // early discard |
| 56 | + |
19 | 57 | pos = orig; |
20 | 58 | for (size_t i=0; i<128; i++) { |
21 | 59 | float d = signed_distance(pos); |
|
0 commit comments