diff --git a/CMakeLists.txt b/CMakeLists.txt index 21668cb..84d028a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,5 +12,8 @@ add_executable(Raytracer main.c Collision.c Collision.c Collision.c - collosion.h - raytrace.c) + collision.h + raytrace.c + raytrace.h + vectorOp.c + vectorOp.h) diff --git a/collosion.h b/collision.h similarity index 100% rename from collosion.h rename to collision.h diff --git a/examples.c b/examples.c index dc5f114..586f51d 100644 --- a/examples.c +++ b/examples.c @@ -3,6 +3,10 @@ // #include "examples.h" +#include "structs.h" +#include "vectorOp.h" +#include "raytrace.h" +#include void example_color(int width, int height, int channels, unsigned char *image) { for (int i = 0; i < height * width; i++) { @@ -17,3 +21,65 @@ void example_color(int width, int height, int channels, unsigned char *image) { } } } + +void exampleSphere(int height, int width, int channels, unsigned char *image) { + camera cam1; + cam1.origin.x = 0; + cam1.origin.y = 0; + cam1.origin.z = 0; + cam1.direction.x = 0; + cam1.direction.y = 0; + cam1.direction.z = 1; + cam1.resolutionX = width; + cam1.resolutionY = height; + cam1.screenDistance = 1; + cam1.width = 1.920; + cam1.height = 1.080; + vec3 sphereOrigin = (vec3){0,0,5}; + double sphereRadius = 1.0; + sphere obj = (sphere){sphereOrigin, sphereRadius}; + + vec3 worldUp = (vec3){0, 1, 0}; + vec3 screenX = vec3Cross(worldUp, cam1.direction); + vec3 screenY = vec3Cross(screenX, cam1.direction); + vec3 screenMiddlePoint = vec3Add(cam1.origin, vec3Scale(cam1.direction, cam1.screenDistance)); + vec3 screenTopLeft = vec3Add( + vec3Add(screenMiddlePoint, + vec3Scale(screenY, cam1.height)), + vec3Scale(screenX, cam1.width) + ); + double pixelStepX = cam1.width / cam1.resolutionX; + double pixelStepY = cam1.height / cam1.resolutionY; + vec3 vecPixelStepX = vec3Scale(screenX, pixelStepX); + vec3 vecPixelStepY = vec3Scale(screenY, pixelStepY); + for (int i = 0; i < height * width; i++) { + int step = i *channels; + int x = i % width; + int y = i / width; + RGBA pixelColor; + + vec3 *pixelOrigin = (vec3 *)malloc(sizeof(vec3)); + *pixelOrigin = vec3Add(screenTopLeft, + vec3Add( + vec3Scale(vecPixelStepX, x), + vec3Scale(vecPixelStepY, y) + ) + ); + + ray *lightRay = (ray *)malloc(sizeof(ray));; + lightRay->origin = cam1.origin; + + lightRay->direction = vec3Subtract(*pixelOrigin, cam1.origin); + + pixelColor = raytraceSphere(&obj, lightRay); + free(pixelOrigin); + free(lightRay); + + image[step] = (int)(pixelColor.r * 255.0); + image[step+1] = 0; + image[step+2] = 0; + if (channels == 4) { + image[step+3] = 255; + } + } +} diff --git a/examples.h b/examples.h index 6dd67ab..7fc85b1 100644 --- a/examples.h +++ b/examples.h @@ -1,9 +1,2 @@ -// -// Created by ary on 19.07.2026. -// - -#ifndef RAYTRACER_EXAMPLES_H -#define RAYTRACER_EXAMPLES_H - -#endif //RAYTRACER_EXAMPLES_H -void example_color(int, int, int, unsigned char *); \ No newline at end of file +void example_color(int, int, int, unsigned char *); +void exampleSphere(int, int, int, unsigned char *); \ No newline at end of file diff --git a/main.c b/main.c index 480c556..bcd69eb 100644 --- a/main.c +++ b/main.c @@ -10,6 +10,8 @@ #include #define MAXJSONSIZE (100 * 1024) #include "structs.h" +#include "collision.h" +#include "raytrace.h" int main() { int width = 1280; int height = 780; @@ -23,7 +25,12 @@ int main() { rawJSON[i] = ch; cJSON *szene = cJSON_Parse(rawJSON); - example_color(width, height, channels, image); + + + //example_color(width, height, channels, image); + exampleSphere(width, height, channels, image); + + stbi_write_png("C:/Users/ary/CLionProjects/Raytracer/test.png", width, height, channels, image, width * channels); free(image); diff --git a/raytrace.c b/raytrace.c index e69de29..b967db5 100644 --- a/raytrace.c +++ b/raytrace.c @@ -0,0 +1,17 @@ +#include "structs.h" +#include "collision.h" +#include "vectorOp.h" + +RGBA raytraceSphere(sphere *obj, ray *lightray) { + RGBA pixel; + pixel.r = 0; + pixel.g = 0; + pixel.b = 0; + pixel.a = 1; + + vec3 collisionPoint = collisionPointSphere(lightray, obj); + vec3 sphereNormal = vec3Normalize(vec3Subtract(collisionPoint, obj->origin)); + pixel.r = -vec3Product(sphereNormal, lightray->direction); + return pixel; + +} \ No newline at end of file diff --git a/raytrace.h b/raytrace.h new file mode 100644 index 0000000..471bef8 --- /dev/null +++ b/raytrace.h @@ -0,0 +1,4 @@ +#pragma once +#include "structs.h" + +RGBA raytraceSphere(sphere *, ray *); diff --git a/structs.h b/structs.h index 7974b95..129577d 100644 --- a/structs.h +++ b/structs.h @@ -1,3 +1,4 @@ +#pragma once struct vec3 { double x, y, z; }; @@ -15,7 +16,7 @@ struct ray { struct sphere { vec3 origin; - int radius; + double radius; }; typedef struct sphere sphere; struct camera { @@ -25,4 +26,9 @@ struct camera { double width; double resolutionX; double resolutionY; -}; typedef struct camera camera; \ No newline at end of file + double screenDistance; +}; typedef struct camera camera; + +struct rgba { + double r, g, b, a; +}; typedef struct rgba RGBA; \ No newline at end of file diff --git a/test.png b/test.png index 2e8dcc7..12a17ad 100644 Binary files a/test.png and b/test.png differ diff --git a/vectorOp.c b/vectorOp.c new file mode 100644 index 0000000..04f92ed --- /dev/null +++ b/vectorOp.c @@ -0,0 +1,24 @@ +#include "structs.h" +#include "math.h" +vec3 vec3Add(vec3 a, vec3 b) { + return (vec3){a.x + b.x, a.y + b.y, a.z + b.z}; +} +vec3 vec3Subtract(vec3 a, vec3 b) { + return (vec3){a.x - b.x, a.y - b.y, a.z - b.z}; +} +vec3 vec3Scale(vec3 vector, double scalar) { + return (vec3){vector.x * scalar, vector.y * scalar, vector.z * scalar}; +} +double vec3Product(vec3 a, vec3 b) { + return (a.x * b.x + a.y * b.y + a.z * b.z); +} +double vec3Length(vec3 vector) { + return sqrt(vector.x * vector.x + vector.y * vector.y + vector.z * vector.z); +} +vec3 vec3Normalize(vec3 vector) { + double length = vec3Length(vector); + return (vec3){vector.x / length, vector.y / length, vector.z / length}; +} +vec3 vec3Cross(vec3 a, vec3 b) { + return (vec3){a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x}; +} \ No newline at end of file diff --git a/vectorOp.h b/vectorOp.h new file mode 100644 index 0000000..8b325e3 --- /dev/null +++ b/vectorOp.h @@ -0,0 +1,16 @@ +#pragma once +#include "structs.h" + +vec3 vec3Add(vec3, vec3); + +vec3 vec3Subtract(vec3, vec3); + +vec3 vec3Scale(vec3, double); + +double vec3Product(vec3, vec3); + +double vec3Length(vec3); + +vec3 vec3Normalize(vec3); + +vec3 vec3Cross(vec3 a, vec3 b);