This commit is contained in:
cannoli-fruit 2026-06-30 01:43:59 -04:00
commit f4d69b664c
9 changed files with 494 additions and 0 deletions

57
bldit.lua Normal file
View file

@ -0,0 +1,57 @@
bldit_version = "1.1.3"
package_version = "1.1.3"
dependencies = {}
exec_name = "ray"
targets = {
default = {
build = function()
e,h,c = os.execute("rm -fr build")
if c ~= 0 and c ~= nil then
print("Build Error")
print("GIVEN UP")
return c
end
e,h,c = os.execute("mkdir build")
if c ~= 0 and c ~= nil then
print("Build Error")
print("GIVEN UP")
return c
end
cmd = [[find src -type f -name "*.c" -print]]
p = io.popen(cmd)
assert(p, "File detection error, GIVEN UP")
for f in p:lines() do
base = f:match("([^/]+)%.c$")
obj = "build/"..base..".o"
cc = "cc -c '"..f.."' -o '"..obj.."'"
e,h,c = os.execute(cc)
if c ~= 0 and c ~= nil then
print("Compilation Error")
print("GIVEN UP")
return c
end
end
p:close()
libs = "-lm"
e,h,c = os.execute("cc build/*.o "..libs.." -o "..exec_name)
if c ~= 0 and c ~= nil then
print("Compilation Error")
print("GIVEN UP")
return c
end
return 0
end,
install = function()
e,h,c = os.execute("cp "..exec_name.." /bin")
return c or 0
end,
uninstall = function()
e,h,c = os.execute("rm /bin"..exec_name)
return c or 0
end,
}
}

56
bldit.lua~ Normal file
View file

@ -0,0 +1,56 @@
bldit_version = "1.1.3"
package_version = "1.1.3"
dependencies = {}
exec_name = "ray"
targets = {
default = {
build = function()
e,h,c = os.execute("rm -fr build")
if c ~= 0 and c ~= nil then
print("Build Error")
print("GIVEN UP")
return c
end
e,h,c = os.execute("mkdir build")
if c ~= 0 and c ~= nil then
print("Build Error")
print("GIVEN UP")
return c
end
cmd = [[find src -type f -name "*.c" -print]]
p = io.popen(cmd)
assert(p, "File detection error, GIVEN UP")
for f in p:lines() do
base = f:match("([^/]+)%.c$")
obj = "build/"..base..".o"
cc = "cc -c '"..f.."' -o '"..obj.."'"
e,h,c = os.execute(cc)
if c ~= 0 and c ~= nil then
print("Compilation Error")
print("GIVEN UP")
return c
end
end
p:close()
e,h,c = os.execute("cc build/*.o -o "..exec_name)
if c ~= 0 and c ~= nil then
print("Compilation Error")
print("GIVEN UP")
return c
end
return 0
end,
install = function()
e,h,c = os.execute("cp "..exec_name.." /bin")
return c or 0
end,
uninstall = function()
e,h,c = os.execute("rm /bin"..exec_name)
return c or 0
end,
}
}

BIN
build/main.o Normal file

Binary file not shown.

BIN
image.ppm Normal file

Binary file not shown.

BIN
main.o Normal file

Binary file not shown.

26
pkgit.lua Normal file
View file

@ -0,0 +1,26 @@
repositories["pkgit"] = {
url = "https://git.symlinx.net/pkgit",
targets = {
default = {
build = function()
e,h,c = os.execute("make")
if c ~= 0 then
print("Compilation Error: ", c, type(c))
print("GIVEN UP")
return c
end
return 0
end,
install = function()
e,h,c = os.execute("make install PREFIX="..prefix)
return c or 0
end,
uninstall = function()
e,h,c = os.execute("make uninstall PREFIX="..prefix)
return c or 0
end,
}
}
}

BIN
ray Executable file

Binary file not shown.

349
src/main.c Normal file
View file

@ -0,0 +1,349 @@
#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct {
float x;
float y;
float z;
} Vec3;
typedef struct {
float refl;
float brightness;
Vec3 col;
} Material;
typedef struct {
Vec3 p0;
Vec3 p1;
Vec3 p2;
Material mat;
} Triangle;
typedef struct {
Vec3 o;
Vec3 d;
} Ray;
typedef struct {
Vec3 p;
Vec3 normal;
int intersected;
float t;
Material mat;
} Collision;
Vec3 vec3_sub(Vec3 *a, Vec3 *b) {
return (Vec3){
.x = a->x - b->x,
.y = a->y - b->y,
.z = a->z - b->z,
};
}
Vec3 vec3_add(Vec3 *a, Vec3 *b) {
return (Vec3){
.x = a->x + b->x,
.y = a->y + b->y,
.z = a->z + b->z,
};
}
Vec3 vec3_hadamard(Vec3 *a, Vec3 *b) {
return (Vec3){
.x = a->x * b->x,
.y = a->y * b->y,
.z = a->z * b->z,
};
}
Vec3 vec3_scale(float x, Vec3 *v) {
return (Vec3){.x = v->x * x, .y = v->y * x, .z = v->z * x};
}
Vec3 vec3_cross(Vec3 *a, Vec3 *b) {
return (Vec3){.x = a->y * b->z - a->z * b->y,
.y = a->z * b->x - a->x * b->z,
.z = a->x * b->y - a->y * b->x};
}
float vec3_mag(Vec3 *a) {
return sqrt(a->x * a->x + a->y * a->y + a->z * a->z);
}
Vec3 vec3_norm(Vec3 *a) { return vec3_scale(1 / vec3_mag(a), a); }
float vec3_dot(Vec3 *a, Vec3 *b) {
return a->x * b->x + a->y * b->y + a->z * b->z;
}
float clamp(float x, float min, float max) {
if (x < min)
return min;
if (x > max)
return max;
return x;
}
Vec3 clamp_col(Vec3 *c) {
return (Vec3){
.x = pow(clamp(c->x, 0, 1), 1 / 1.8),
.y = pow(clamp(c->y, 0, 1), 1 / 1.8),
.z = pow(clamp(c->z, 0, 1), 1 / 1.8),
};
}
Collision intersect(Ray *r, Triangle *tr) {
Vec3 e1 = vec3_sub(&tr->p1, &tr->p0);
Vec3 e2 = vec3_sub(&tr->p2, &tr->p0);
Vec3 pvec = vec3_cross(&r->d, &e2);
float det = vec3_dot(&e1, &pvec);
if (fabs(det) < 0.01)
return (Collision){0};
float invdet = 1.0 / det;
Vec3 tvec = vec3_sub(&r->o, &tr->p0);
float u = vec3_dot(&pvec, &tvec) * invdet;
if (u < 0.0 || u > 1.0)
return (Collision){0};
Vec3 qvec = vec3_cross(&tvec, &e1);
float v = vec3_dot(&r->d, &qvec) * invdet;
if (v < 0.0 || (u + v) > 1.0)
return (Collision){0};
float t = vec3_dot(&e2, &qvec) * invdet;
if (t < 0.0)
return (Collision){0};
Vec3 td = vec3_scale(t, &r->d);
Vec3 x = vec3_add(&td, &r->o);
Vec3 norm = vec3_cross(&e1, &e2);
norm = vec3_norm(&norm);
if (vec3_dot(&norm, &r->d) > 0.0)
norm = vec3_scale(-1.0f, &norm);
return (Collision){.p = x, //
.normal = norm,
.t = t,
.intersected = 1,
.mat = tr->mat};
}
Collision intersectScene(Ray *r, Triangle *scene, size_t tricnt) {
Collision closestCollision = {0};
for (int i = 0; i < tricnt; ++i) {
Collision c = intersect(r, &scene[i]);
if (c.intersected) {
if (!closestCollision.intersected) {
closestCollision = c;
}
if (c.t < closestCollision.t) {
closestCollision = c;
}
}
}
return closestCollision;
}
float randfloat() { return (float)rand() / 4294967296; }
Vec3 shade(Collision *c, Ray *r, size_t depth, Triangle *scene, size_t tricnt) {
if (!c->intersected) {
return (Vec3){.x = 0.0f, .y = 0.0f, .z = 0.0f};
}
Vec3 col = (Vec3){.x = 0.0f, .y = 0.0f, .z = 0.0f};
Vec3 amb = vec3_scale(0.1, &c->mat.col);
col = vec3_add(&col, &amb);
for (int i = 0; i < 1; ++i) { // Assume only 1 light at 10,10,-2 for now
Vec3 light = (Vec3){.x = 10, .y = -10, .z = -2};
Vec3 lightColor = (Vec3){.x = 1, .y = 1, .z = 1};
float lightStrength = 0.5;
Vec3 toLight = vec3_sub(&light, &c->p);
float lightDist = vec3_mag(&toLight);
toLight = vec3_norm(&toLight);
Vec3 offset = vec3_scale(0.01, &c->normal);
Ray shadow = (Ray){.o = vec3_add(&c->p, &offset), .d = toLight};
Collision shadowC = intersectScene(&shadow, scene, tricnt);
int inShadow =
shadowC.intersected && shadowC.t < lightDist && shadowC.t > 0.1;
if (!inShadow) {
float diff = vec3_dot(&c->normal, &toLight);
if (diff < 0.0)
diff = 0.0;
Vec3 lightContr = vec3_scale(lightStrength * diff, &lightColor);
Vec3 hitColor = vec3_hadamard(&lightContr, &c->mat.col);
Vec3 colNoise = (Vec3){
.x = randfloat() * 0.08,
.y = randfloat() * 0.08,
.z = randfloat() * 0.08,
};
col = vec3_add(&col, &hitColor);
col = vec3_add(&col, &colNoise);
}
}
return col;
}
Vec3 trace(Ray *r, Triangle *scene, size_t tricnt, size_t depth) {
Collision c = intersectScene(r, scene, tricnt);
Vec3 rawcol = shade(&c, r, depth, scene, tricnt);
return clamp_col(&rawcol);
}
void addQuad(Triangle *scene, size_t *tricnt, Vec3 *col, Vec3 p1, Vec3 p2,
Vec3 p3, Vec3 p4) {
scene[(*tricnt)++] = (Triangle){.p0 = p1,
.p1 = p2,
.p2 = p3, //
.mat = (Material){
.refl = 0.7,
.brightness = 0.7,
.col = *col,
}};
scene[(*tricnt)++] = (Triangle){.p0 = p2,
.p1 = p4,
.p2 = p3, //
.mat = (Material){
.refl = 0.7,
.brightness = 0.7,
.col = *col,
}};
}
void addBeam(Triangle *scene, size_t *tricnt, Vec3 *col, float x, float y,
float z, float w, float l, float d) {
Vec3 c1 = (Vec3){.x = x, .y = y, .z = z};
Vec3 c2 = (Vec3){.x = x + w, .y = y, .z = z};
Vec3 c3 = (Vec3){.x = x, .y = y + l, .z = z};
Vec3 c4 = (Vec3){.x = x + w, .y = y + l, .z = z};
Vec3 c5 = (Vec3){.x = x, .y = y, .z = z + d};
Vec3 c6 = (Vec3){.x = x + w, .y = y, .z = z + d};
Vec3 c7 = (Vec3){.x = x, .y = y + l, .z = z + d};
Vec3 c8 = (Vec3){.x = x + w, .y = y + l, .z = z + d};
addQuad(scene, tricnt, col, c1, c2, c3, c4);
addQuad(scene, tricnt, col, c5, c6, c7, c8);
addQuad(scene, tricnt, col, c1, c3, c5, c7);
addQuad(scene, tricnt, col, c2, c4, c6, c8);
addQuad(scene, tricnt, col, c1, c2, c5, c6);
addQuad(scene, tricnt, col, c3, c4, c7, c8);
}
Vec3 rotateX(Vec3 *v, float angle) {
float c = cosf(angle);
float s = sinf(angle);
return (Vec3){.x = v->x, .y = c * v->y - s * v->z, .z = s * v->y + c * v->z};
}
Vec3 rotateY(Vec3 *v, float angle) {
float c = cosf(angle);
float s = sinf(angle);
return (Vec3){.x = c * v->x - s * v->z, .y = v->y, .z = s * v->x + c * v->z};
}
int main() {
printf("Hello World!\n");
size_t W = 640;
size_t H = 480;
FILE *f = fopen("image.ppm", "wb");
fprintf(f, "P6\n");
fprintf(f, "%d %d\n", W, H);
fprintf(f, "255\n", W, H);
size_t tricnt = 0;
Triangle *scene = malloc(128 * sizeof(Triangle));
Vec3 red = (Vec3){.x = 0.8, .y = 0.2, .z = 0.2};
Vec3 green = (Vec3){.x = 0.2, .y = 0.8, .z = 0.2};
Vec3 blue = (Vec3){.x = 0.2, .y = 0.2, .z = 0.8};
float bx = 111;
float by = 113;
float bz = 84;
float l = 16;
float g = 2;
addBeam(scene, &tricnt, &red, bx, by, bz, g, l, g);
addBeam(scene, &tricnt, &green, bx + g, by + l - g, bz, g, g, l);
addBeam(scene, &tricnt, &blue, bx + g, by + l, bz + l - g, l, g, g);
/* Chessboard
for (int i = 0; i < 8; ++i) {
for (int j = 0; j < 8; ++j) {
float lx = i - 4;
float rx = i - 3;
float cz = j + 4;
float fz = j + 5;
float y = -3;
Vec3 col = {0};
if ((i + j) & 1) {
col.x = 138.0 / 255.0;
col.y = 95.0 / 255.0;
col.z = 45.0 / 255.0;
} else {
col.x = 252.0 / 255.0;
col.y = 180.0 / 255.0;
col.z = 93.0 / 255.0;
}
scene[2 * (i + j * 8) + 0] = (Triangle){
.p0 = (Vec3){.x = lx, .y = y, .z = cz}, //
.p1 = (Vec3){.x = rx, .y = y, .z = cz}, //
.p2 = (Vec3){.x = rx, .y = y, .z = fz}, //
.mat = (Material){.refl = 0.7, .brightness = 0.7, .col = col}};
scene[2 * (i + j * 8) + 1] = (Triangle){
.p0 = (Vec3){.x = rx, .y = y, .z = fz}, //
.p1 = (Vec3){.x = lx, .y = y, .z = fz}, //
.p2 = (Vec3){.x = lx, .y = y, .z = cz}, //
.mat = (Material){.refl = 0.7, .brightness = 0.7, .col = col}};
}
}
*/
float aspect = (float)W / (float)H;
for (int j = 0; j < H; ++j) {
for (int i = 0; i < W; ++i) {
Vec3 camOrigin = (Vec3){.x = 0, .y = 0, .z = 0};
float u = (2.0f * (i + 0.5f) / W - 1.0f) * aspect;
float v = 1.0f - 2.0f * (j + 0.5f) / H;
float zoom = 8;
u /= zoom;
v /= zoom;
float rconst = 0.00;
float ur = (randfloat() - 0.5) * rconst;
u += ur;
float vr = (randfloat() - 0.5) * rconst * 0.75;
v += vr;
Vec3 camDir = (Vec3){.x = u, .y = v, .z = 1.0};
camDir = rotateX(&camDir, -0.76);
camDir = rotateY(&camDir, -0.78539);
camDir = vec3_norm(&camDir);
Ray camray = (Ray){.o = camOrigin, .d = camDir};
Vec3 col = trace(&camray, scene, tricnt, 4);
uint8_t quant = 0xD0;
fputc((uint8_t)(0xFF * col.x) & quant, f);
fputc((uint8_t)(0xFF * col.y) & quant, f);
fputc((uint8_t)(0xFF * col.z) & quant, f);
}
}
return 0;
}

6
src/main.c~ Normal file
View file

@ -0,0 +1,6 @@
#include <stdio.h>
int main() {
printf("Hello World!\n");
return 0;
}