#include #include "structs.h" #include "collision.h" #include "vectorOp.h" #define MAXSPHERES 100 #include "helper.h" #include #define epsilon 1e-8 RGBA raytraceSphere(sphere **objectList, ray *lightray) { RGBA pixel = (RGBA){0,0,0,0}; #define lightBounces 3 //sphere **spheresHitList = (sphere **)calloc( (lightBounces + 1),sizeof(sphere*) ); //vec3 *spheresNormalList = (vec3 *)calloc( lightBounces + 1,sizeof(vec3) ); int hitLightIndex = -1; vec3 sphereNormal; int raysPerPixel = 20; ray originalRay = *lightray; for (int k = 0; k < raysPerPixel; k++) { sphere *spheresHitList[lightBounces + 1] = {0}; vec3 spheresNormalList[lightBounces + 1] = {0}; *lightray = originalRay; 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(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()); if (fabs(lightray->direction.x ) <= epsilon || fabs(lightray->direction.y ) <= epsilon || fabs(lightray->direction.z) <= epsilon) { lightray->direction = sphereNormal; } //reflektion: //lightray->direction = vec3Add(lightray->direction, vec3Scale(sphereNormal, 2)); lightray->origin = nearestCollisionPoint; } else { sphereNormal = (vec3){1,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) { tempPixel = (RGBA){0,0,0,1}; } else { pixel.r += spheresHitList[firstLightHitIndex]->color.r; pixel.g += spheresHitList[firstLightHitIndex]->color.g; pixel.b += spheresHitList[firstLightHitIndex]->color.b; pixel.a += spheresHitList[firstLightHitIndex]->color.a; 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}; } } //average pixelData pixel.r = pixel.r / raysPerPixel; pixel.g = pixel.g / raysPerPixel; pixel.b = pixel.b / raysPerPixel; pixel.a = pixel.a / raysPerPixel; //free(spheresHitList); //free(spheresNormalList); return pixel; }