commit 563ba2d1774f8d785977e68883919605b2f610eb
parent 545ff5be825e3fa35ee502e9bc041bca47845825
Author: Pavel Renev <an2qzavok@gmail.com>
Date: Sun, 21 Mar 2021 21:23:34 +0000
render: add light, finally
Diffstat:
M | render.c | | | 110 | ++++++++++++++++++++++++++++++++++++++++++++----------------------------------- |
1 file changed, 61 insertions(+), 49 deletions(-)
diff --git a/render.c b/render.c
@@ -5,72 +5,75 @@
#define SQR(X) (X * X)
-typedef struct Pixel Pixel;
-typedef struct Dot Dot;
+typedef struct Vect Vect;
typedef struct Ray Ray;
typedef struct Sphere Sphere;
-struct Pixel {
- double r;
- double g;
- double b;
-};
-
-struct Dot {
+struct Vect {
double x;
double y;
double z;
};
-
struct Ray {
- Dot pos;
- Dot dir;
+ Vect pos;
+ Vect dir;
};
struct Sphere {
- Dot pos;
+ Vect pos;
double radius;
};
-Pixel Pwhite = {1, 1, 1};
-Pixel Pblack = {0, 0, 0};
-
-Sphere sphere = {{0.5, 0.5, 0}, 0.5};
+Vect Pwhite = {1, 1, 1};
+Vect Pblack = {0, 0, 0};
double
-dotmod(Dot d)
+vectmod(Vect d)
{
return sqrt(SQR(d.x) + SQR(d.y) + SQR(d.z));
}
-Dot
-dotnorm(Dot d)
+Vect
+vectnorm(Vect d)
{
double m;
- m = dotmod(d);
- return (Dot){d.x/m, d.y/m, d.z/m};
+ m = vectmod(d);
+ return (Vect){d.x/m, d.y/m, d.z/m};
}
-Dot
-dotxdot(Dot d1, Dot d2)
+Vect
+vectxvect(Vect d1, Vect d2)
{
- return (Dot){d1.x * d2.x, d1.y * d2.y, d1.z * d2.z,};
+ return (Vect){d1.x * d2.x, d1.y * d2.y, d1.z * d2.z};
}
-Dot
-adddot(Dot d1, Dot d2)
+
+Vect
+addvect(Vect d1, Vect d2)
{
- return (Dot){d1.x + d2.x, d1.y + d2.y, d1.z + d2.z,};
+ return (Vect){d1.x + d2.x, d1.y + d2.y, d1.z + d2.z};
}
-Dot
-subdot(Dot d1, Dot d2)
+Vect
+subvect(Vect d1, Vect d2)
{
- return adddot(d1, (Dot){-d2.x, -d2.y, -d2.z});
+ return addvect(d1, (Vect){-d2.x, -d2.y, -d2.z});
}
+Vect
+topolar(Vect v)
+{
+ return (Vect){atan(v.y/v.z)*2/PI,
+ atan(v.x/v.z)*2/PI, vectmod(v)};
+}
+
+double
+vectscalar(Vect d1, Vect d2)
+{
+ return d1.x * d2.x + d1.y * d2.y + d1.z * d2.z;
+}
int
spherehit(Ray *v, Sphere s)
{
@@ -78,10 +81,11 @@ spherehit(Ray *v, Sphere s)
int i;
old = Inf(1);
for (i = 0; i < 1024; i++) {
- d = dotmod(subdot(v->pos, s.pos)) - s.radius;
- v->pos = adddot(v->pos,
- dotxdot(dotnorm(v->dir), (Dot){d, d, d}));
- if (d < 0.0001) {
+ d = vectmod(subvect(v->pos, s.pos)) - s.radius;
+ v->pos = addvect(v->pos,
+ vectxvect(vectnorm(v->dir), (Vect){d, d, d}));
+ if (d < 0.00001) {
+ v->dir = subvect(s.pos, v->pos);
return 1;
}
if (d > old) return 0;
@@ -90,28 +94,37 @@ spherehit(Ray *v, Sphere s)
return 0;
}
-Pixel
+Vect
ray(Ray v)
{
- Pixel p = Pblack;
+ Vect vv;
+ vv = v.pos;
+ Sphere sphere = {{0, 0, 10}, 0.95};
+ Vect light = vectnorm((Vect){10, -10, 10});
+ Vect p = Pblack;
if (spherehit(&v, sphere)) {
- p = Pwhite;
+ double f;
+ Vect r;
+ r = vectnorm(v.dir);
+ f = vectscalar(r, light)/(vectmod(light)*vectmod(r));
+ if (f < 0) f = 0;
+ p = (Vect){f, f, f};
}
return p;
}
-int
+u32int
render(int x, int y)
{
- Pixel p;
- int r, g, b;
+ Vect p;
+ u32int r, g, b;
Ray v;
- v.pos = (Dot){ (double)x/256.0, (double)y/256.0, -100 };
- v.dir = (Dot){ 0, 0, 1 };
+ v.pos = (Vect){ (double)x/128.0 - 1, (double)y/128.0 - 1, -100 };
+ v.dir = (Vect){ 0, 0, 1 };
p = ray(v);
- r = 0xff * p.r;
- g = 0xff * p.g;
- b = 0xff * p.b;
+ r = (u32int)(0xff * p.x)&0xff;
+ g = (u32int)(0xff * p.y)&0xff;
+ b = (u32int)(0xff * p.z)&0xff;
return (r<<16)|(g<<8)|b;
}
@@ -119,7 +132,7 @@ void
main(void)
{
int i, x, y;
- int buf[256*256];
+ u32int buf[256*256];
write(1, " x8r8g8b8 ", 12);
write(1, " 0 ", 12);
write(1, " 0 ", 12);
@@ -132,4 +145,4 @@ main(void)
}
write(1, buf, 4 * 256 * 256);
exits(nil);
-}
-\ No newline at end of file
+}