Files
CPU-Raytracer/raytrace.c
T

101 lines
3.9 KiB
C

#include <stdlib.h>
#include "structs.h"
#include "collision.h"
#include "vectorOp.h"
#define MAXSPHERES 100
#include "helper.h"
RGBA raytraceSphere(sphere **objectList, ray *lightray) {
RGBA pixel = (RGBA){0,0,0,0};
#define lightBounces 1
//sphere **spheresHitList = (sphere **)calloc( (lightBounces + 1),sizeof(sphere*) );
//vec3 *spheresNormalList = (vec3 *)calloc( lightBounces + 1,sizeof(vec3) );
int hitLightIndex = -1;
vec3 sphereNormal;
int raysPerPixel = 50;
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());
//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;
}