1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| #include "../3rdParty/svpng/svpng.inc" #include "Sphere.h" #include "CollisibleList.h" #include <cstdio> #include <limits>
const int WIDTH = 640; const int HEIGHT = 480;
using byte = unsigned char;
void paint(byte *d, int x, int y, Color3f color, float alpha) { d += 4 * ((HEIGHT - y - 1) * WIDTH + x); d[0] = 255 * color.r; d[1] = 255 * color.g; d[2] = 255 * color.b; d[3] = 255 * alpha; }
Color3f mix(const Color3f &a, const Color3f &b, float t) { return a * (1.0f - t) + b * t; }
Color3f paint(const Ray &r, const Collisible &obj) { CollideRecord rec; if (obj.collide(r, 0.0f, std::numeric_limits<float>::max(), rec)) return 0.5f * (rec.normal + Vector3f(1.0f, 1.0f, 1.0f));
Vector3f dir = r.getDir(); float t = 0.5f * (dir.y + 1.0f); return mix({1.0f, 1.0f, 1.0f}, {0.5f, 0.7f, 1.0f}, t); }
int main() { byte d[4 * WIDTH * HEIGHT]; FILE *f = fopen("ch5.png", "wb"); Point3f lowerLeftCorner(-2.0f, -1.5f, -1.0f); Vector3f horizonal(4.0f, 0.0f, 0.0f); Vector3f vertical(0.0f, 3.0f, 0.0f); Point3f origin(0.0f, 0.0f, 0.0f);
CollisibleList list; Collisible *obj[2]; obj[0] = new Sphere({0, 0, -1}, 0.5); obj[1] = new Sphere({0, -100.5, -1}, 100);
list.add(obj[0]); list.add(obj[1]);
for (int x = 0; x < WIDTH; x++) { for (int y = 0; y < HEIGHT; y++) { float u = (float)x / WIDTH; float v = (float)y / HEIGHT; Ray r(origin, lowerLeftCorner + u * horizonal + v * vertical); paint(d, x, y, paint(r, list), 1.0f); } }
delete obj[0]; delete obj[1]; svpng(f, WIDTH, HEIGHT, d, 1); fclose(f); }
|