diff --git a/CMakeLists.txt b/CMakeLists.txt index b3a5d0b..31883ba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,4 +18,6 @@ add_executable(Raytracer main.c vectorOp.c vectorOp.h interface.c - interface.h) + interface.h + helper.c + helper.h) diff --git a/helper.c b/helper.c new file mode 100644 index 0000000..f21d2d2 --- /dev/null +++ b/helper.c @@ -0,0 +1,24 @@ +// +// Created by ary on 29.07.2026. +// + +#include "helper.h" +#include +#include +#include "structs.h" + +vec3 randUnitVector() { + double x1,x2,lengthSquared; + do { + x1 = (rand() / (double) RAND_MAX) * 2 - 1; //random zahl zwischen -1 und 1 + x2 = (rand() / (double) RAND_MAX) * 2 - 1; + lengthSquared = x1 * x1 + x2 * x2; + }while (lengthSquared >= 1); + + double weirdFactor = 2.0 * sqrt(1.0 - lengthSquared); + return (vec3){ + x1 * weirdFactor, + x2 * weirdFactor, + 1.0 - 2.0 * lengthSquared}; +} + diff --git a/helper.h b/helper.h new file mode 100644 index 0000000..3f516c2 --- /dev/null +++ b/helper.h @@ -0,0 +1,4 @@ +#pragma once +#include "structs.h" + +vec3 randUnitVector(); diff --git a/interface.c b/interface.c index 77106e1..96b9932 100644 --- a/interface.c +++ b/interface.c @@ -8,6 +8,7 @@ #include "vectorOp.h" #include "raytrace.h" #include +#include "helper.h" void displaySzene(sphere **objectList, int objectCount, camera cam1, int width, int height, int channels, unsigned char **image) { const vec3 worldUp = (vec3){0, 1, 0}; diff --git a/raytrace.c b/raytrace.c index 001fd37..179e1a5 100644 --- a/raytrace.c +++ b/raytrace.c @@ -3,71 +3,89 @@ #include "collision.h" #include "vectorOp.h" #define MAXSPHERES 100 +#include "helper.h" RGBA raytraceSphere(sphere **objectList, ray *lightray) { - RGBA pixel = (RGBA){0,0,0,1}; + RGBA pixel = (RGBA){0,0,0,0}; const int lightBounces = 5; sphere **spheresHitList = (sphere **)calloc( (lightBounces + 1),sizeof(sphere*) ); vec3 *spheresNormalList = (vec3 *)calloc( lightBounces + 1,sizeof(vec3) ); int hitLightIndex = -1; vec3 sphereNormal; + int raysPerPixel = 1; - sphere *nearestSphere = nullptr; - vec3 nearestCollisionPoint = {10000,10000,10000}; - for (int j = 0; j <= lightBounces; j++) { - nearestSphere = nullptr; - nearestCollisionPoint = (vec3){10000,10000,10000}; - for (int i = 0; i < 100 && objectList[i] != nullptr; i++) { - vec3 collisionPoint = collisionPointSphere(lightray, objectList[i]); - if (collisionPoint.x == -10000000) { + for (int k = 0; k < raysPerPixel; k++) { + RGBA tempPixel = (RGBA){1,1,1,1}; + sphere *nearestSphere = nullptr; + vec3 nearestCollisionPoint = {10000,10000,10000}; + for (int j = 0; j <= lightBounces; j++) { + nearestSphere = nullptr; + nearestCollisionPoint = (vec3){10000,10000,10000}; + for (int i = 0; i < 100 && objectList[i] != nullptr; i++) { + vec3 collisionPoint = collisionPointSphere(lightray, objectList[i]); + if (collisionPoint.x == -10000000) { - } - else{ - if (vec3Length(collisionPoint)< vec3Length(nearestCollisionPoint)) { - nearestCollisionPoint = collisionPoint; - nearestSphere = objectList[i]; } + else{ + if (vec3Length(vec3Subtract(collisionPoint, lightray->origin)) < vec3Length(vec3Subtract(nearestCollisionPoint, lightray->origin))) { + nearestCollisionPoint = collisionPoint; + nearestSphere = objectList[i]; + } + } + } + + + if (nearestSphere != nullptr) { + spheresHitList[j] = nearestSphere; + sphereNormal = vec3Scale(vec3Subtract(nearestCollisionPoint, nearestSphere->origin), 1/(nearestSphere->radius));////////////////////////////// optimize, schreibe divide vector funktion + spheresNormalList[j] = sphereNormal; + //diffus: + lightray->direction = vec3Add(sphereNormal, randUnitVector()); + //reflektion: + //lightray->direction = vec3Add(lightray->direction, vec3Scale(sphereNormal, 2)); + lightray->origin = nearestCollisionPoint; + } + else { + sphereNormal = (vec3){1,1,1}; } } - - if (nearestSphere != nullptr) { - spheresHitList[j] = nearestSphere; - sphereNormal = vec3Scale(vec3Subtract(nearestCollisionPoint, nearestSphere->origin), 1/(nearestSphere->radius));////////////////////////////// optimize, schreibe divide vector funktion - spheresNormalList[j] = sphereNormal; - lightray->direction = vec3Add(lightray->direction, vec3Scale(sphereNormal, 2)); - lightray->origin = nearestCollisionPoint; + int firstLightHitIndex = -1; + for (int i = 0; i <= lightBounces && spheresHitList[i] != nullptr; i++) { + if (spheresHitList[i]->isLight == 1) { + firstLightHitIndex = i; + break; + } } - else { - sphereNormal = (vec3){1,1,1}; + if (firstLightHitIndex == -1) { + tempPixel = (RGBA){0,0,0,1}; + } + else + { pixel = spheresHitList[firstLightHitIndex]->color; + for (int i = firstLightHitIndex - 1; i >= 0; i--) { + tempPixel.r = tempPixel.r * spheresHitList[i]->color.r; + tempPixel.g = tempPixel.g * spheresHitList[i]->color.g; + tempPixel.b = tempPixel.b * spheresHitList[i]->color.b; + tempPixel.a = tempPixel.a * spheresHitList[i]->color.a; + } + pixel.r += tempPixel.r; + pixel.g += tempPixel.g; + pixel.b += tempPixel.b; + pixel.a += tempPixel.a; + + //pixel.r = -vec3Product(sphereNormal, lightray->direction); + //pixel = (RGBA){1 - 0.5 *( sphereNormal.x + 1), 1 - 0.5 * (sphereNormal.y +1), 1 -0.5* (sphereNormal.z + 1),1}; } } - int firstLightHitIndex = -1; - for (int i = 0; i <= lightBounces && spheresHitList[i] != nullptr; i++) { - if (spheresHitList[i]->isLight == 1) { - firstLightHitIndex = i; - break; - } - } - if (firstLightHitIndex == -1) { - pixel = (RGBA){0,0,0,1}; - } - else - { pixel = spheresHitList[firstLightHitIndex]->color; - for (int i = firstLightHitIndex - 1; i >= 0; i--) { - pixel.r = pixel.r * spheresHitList[i]->color.r; - pixel.g = pixel.g * spheresHitList[i]->color.g; - pixel.b = pixel.b * spheresHitList[i]->color.b; - pixel.a = pixel.a * spheresHitList[i]->color.a; - } + //average pixelData + pixel.r = pixel.r / raysPerPixel; + pixel.g = pixel.g / raysPerPixel; + pixel.b = pixel.b / raysPerPixel; + pixel.a = pixel.a / raysPerPixel; - //pixel.r = -vec3Product(sphereNormal, lightray->direction); - //pixel = (RGBA){1 - 0.5 *( sphereNormal.x + 1), 1 - 0.5 * (sphereNormal.y +1), 1 -0.5* (sphereNormal.z + 1),1}; - } - free(spheresHitList); free(spheresNormalList); return pixel; diff --git a/test.png b/test.png index cae9d98..f94983b 100644 Binary files a/test.png and b/test.png differ