code ist jetzt schner aber ich habe durch einen pointer fehler in raytrace.c (nearestObject = &currentObject //zeigt immer auf die selbne adresse)
ein art negativ bild erzeugt
This commit is contained in:
any
2026-08-26 00:12:44 +02:00
parent 91bb170b23
commit 491eca3513
7 changed files with 149 additions and 153 deletions
+15 -16
View File
@@ -39,25 +39,24 @@ void exampleSphere( int width, int height, int channels, unsigned char **image)
vec3 sphereOrigin = (vec3){0,-1.5,5}; vec3 sphereOrigin = (vec3){0,-1.5,5};
double sphereRadius = 1.0; double sphereRadius = 1.0;
int objectCount = 7; int objectCount = 7;
sphere obj1 = (sphere){sphereOrigin, sphereRadius,(RGBA){1,0.5,1,1},0}; object objectList[objectCount];
sphere **objectList = (sphere **) calloc(objectCount+1, sizeof(sphere*));; sphere obj1 = (sphere){sphereOrigin, sphereRadius,(RGBA){1,0.5,1,1}};
objectList[0] = &obj1; objectList[0] = (object){0, &obj1, 0};
sphere obj2 = (sphere){vec3Add(sphereOrigin, (vec3){3,0,0}), sphereRadius, (RGBA){1,1,0.5,1},0}; sphere obj2 = (sphere){vec3Add(sphereOrigin, (vec3){3,0,0}), sphereRadius, (RGBA){1,1,0.5,1}};
objectList[1] = &obj2; objectList[1] = (object){0, &obj2, 0};
sphere obj3 = (sphere){vec3Add(sphereOrigin, (vec3){-2,1,0}), sphereRadius, (RGBA){1,1,1,1},0}; sphere obj3 = (sphere){vec3Add(sphereOrigin, (vec3){-2,1,0}), sphereRadius, (RGBA){1,1,1,1}};
objectList[2] = &obj3; objectList[2] = (object){0, &obj3, 0};
sphere obj4 = (sphere){vec3Add(sphereOrigin, (vec3){1,1,3}), sphereRadius, (RGBA){0.5,1,1,1},0}; sphere obj4 = (sphere){vec3Add(sphereOrigin, (vec3){1,1,3}), sphereRadius, (RGBA){0.5,1,1,1}};
objectList[3] = &obj4; objectList[3] = (object){0, &obj4, 0};
sphere light1 = (sphere){(vec3){1,1,4.5}, sphereRadius, (RGBA){1,1,1,1},1}; sphere light1 = (sphere){(vec3){1,1,4.5}, sphereRadius, (RGBA){1,1,1,1}};
objectList[4] = &light1; objectList[4] = (object){0, &light1, 1};
sphere obj5 = (sphere){(vec3){0, -6, 6.5}, 5, (RGBA){1,0.2,0.6,1},0}; sphere obj5 = (sphere){(vec3){0, -6, 6.5}, 5, (RGBA){1,0.2,0.6,1}};
objectList[5] = &obj5; objectList[5] = (object){0, &obj5, 0};
sphere light2 = (sphere){(vec3){1,-2,4}, sphereRadius, (RGBA){1,1,1,1},1}; sphere light2 = (sphere){(vec3){1,-2,4}, sphereRadius, (RGBA){1,1,1,1}};
objectList[6] = &light2; objectList[6] = (object){0, &light2, 1};
displaySzene(objectList, objectCount, cam1, width, height, channels, image); displaySzene(objectList, objectCount, cam1, width, height, channels, image);
free(objectList);
} }
+2 -2
View File
@@ -10,7 +10,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "helper.h" #include "helper.h"
void displaySzene(sphere **objectList, int objectCount, camera cam1, int width, int height, int channels, unsigned char **image) { void displaySzene(object objectList[], int objectCount, camera cam1, int width, int height, int channels, unsigned char **image) {
const vec3 worldUp = (vec3){0, 1, 0}; const vec3 worldUp = (vec3){0, 1, 0};
vec3 screenX = vec3Cross(worldUp, cam1.direction); vec3 screenX = vec3Cross(worldUp, cam1.direction);
vec3 screenY = vec3Cross(screenX, cam1.direction); vec3 screenY = vec3Cross(screenX, cam1.direction);
@@ -43,7 +43,7 @@ void displaySzene(sphere **objectList, int objectCount, camera cam1, int width,
lightRay->direction = vec3Normalize(vec3Subtract(*pixelOrigin, cam1.origin)); lightRay->direction = vec3Normalize(vec3Subtract(*pixelOrigin, cam1.origin));
pixelColor = raytraceSphere(objectList, lightRay); pixelColor = getPixelColor(objectList,objectCount, lightRay);
free(pixelOrigin); free(pixelOrigin);
free(lightRay); free(lightRay);
+1 -1
View File
@@ -1,4 +1,4 @@
#pragma once #pragma once
#include "structs.h" #include "structs.h"
void displaySzene(sphere **objectList, int objectCount, camera cam1, int width, int height, int channels, unsigned char **image); void displaySzene(object objectList[], int objectCount, camera cam1, int width, int height, int channels, unsigned char **image);
+119 -130
View File
@@ -2,156 +2,145 @@
#include "structs.h" #include "structs.h"
#include "collision.h" #include "collision.h"
#include "vectorOp.h" #include "vectorOp.h"
#define MAXSPHERES 100 #define MAXOBJECTS 100
#define BADPOINT (vec3){-10000000,-10000000,-10000000}
#include "helper.h" #include "helper.h"
#include <math.h> #include <math.h>
#define epsilon 1e-8 #define epsilon 1e-8
#define lightBounces 3
enum objectType {
SPHERETYPE,
QUADTYPE
};
RGBA raytraceSphere(sphere **sphereList, int sphereCount, quad **quadList, int quadCount, ray *lightray) { RGBA getRayColor(RGBA colorList[], bool isLightList[]) {
int firstLightHitIndex = -1;
RGBA rayColor = {1,1,1,1};
for (int i = 0; i <= lightBounces; i++) {
if (isLightList[i] == 1) {
firstLightHitIndex = i;
break;
}
}
if (firstLightHitIndex == -1) {
rayColor = (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; i >= 0; i--) {
rayColor.r = rayColor.r * colorList[i].r;
rayColor.g = rayColor.g * colorList[i].g;
rayColor.b = rayColor.b * colorList[i].b;
//rayColor.a = rayColor.a * colorList[i].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};
return rayColor;
}
}
RGBA raytrace(object objectList[], int objectCount, ray *lightray) {
RGBA objectColorList[lightBounces + 1] = {0};
object objectHitList[lightBounces + 1] = {0};
bool isLightList[lightBounces + 1] = {false};
for (int j = 0; j <= lightBounces; j++) {
object currentObject;
object *nearestObject = nullptr;
double nearestObjectDistance = 10000000;
vec3 nearestCollisionPoint = (vec3){10000,10000,10000};
double nearestCollisionPointDistance = 10000000;
for (int i = 0; i < objectCount; i++) {
currentObject = objectList[i];
vec3 collisionPoint;
switch (currentObject.objectType) {
case SPHERETYPE:
collisionPoint = collisionPointSphere(lightray, (sphere*)(objectList[i].objectPointer));
break;
case QUADTYPE:
collisionPoint = collisionQuad(lightray, (quad*)(objectList[i].objectPointer));
break;
}
double collisionPointDistance = 1000000;
if (collisionPoint.x != BADPOINT.x) {
collisionPointDistance = vec3Length(vec3Subtract(collisionPoint, lightray->origin));
if (collisionPointDistance < nearestCollisionPointDistance) {
nearestCollisionPoint = collisionPoint;
nearestCollisionPointDistance = collisionPointDistance;
nearestObject = &currentObject;
}
}
}
vec3 objectNormal = BADPOINT;
if (nearestObject != nullptr) {
switch (nearestObject->objectType) {
case SPHERETYPE:
sphere *nearestSphere = (sphere*)(nearestObject->objectPointer);
objectColorList[j] = nearestSphere->color;
objectNormal = vec3Scale(vec3Subtract(nearestCollisionPoint, nearestSphere->origin), 1/(nearestSphere->radius));////////////////////////////// optimize, schreibe divide vector funktion
break;
case QUADTYPE:
quad *nearestQuad = (quad*)(nearestObject->objectPointer);
objectColorList[j] = nearestQuad->color;
objectNormal = nearestQuad->normal;
break;
}
objectHitList[j] = *nearestObject;
isLightList[j] = nearestObject->isLight;
//diffus:
lightray->direction = vec3Normalize(vec3Add(objectNormal, randUnitVector())); //maybe kann man sich durch umstrukturierung das normalisieren einsparen
if (fabs(lightray->direction.x ) <= epsilon || fabs(lightray->direction.y ) <= epsilon || fabs(lightray->direction.z) <= epsilon) {
lightray->direction = objectNormal;
}
//reflektion:
//lightray->direction = vec3Add(lightray->direction, vec3Scale(sphereNormal, 2));
lightray->origin = nearestCollisionPoint;
}
}
return getRayColor(objectColorList, isLightList);
}
RGBA getPixelColor(object objectList[], int objectCount, ray *lightray) {
RGBA pixel = (RGBA){0,0,0,0}; RGBA pixel = (RGBA){0,0,0,0};
#define lightBounces 3 int raysPerPixel = 2;
//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; ray originalRay = *lightray;
for (int k = 0; k < raysPerPixel; k++) { for (int k = 0; k < raysPerPixel; k++) {
sphere *spheresHitList[lightBounces + 1] = {0};
quad *quadHitList[lightBounces + 1] = {0};
vec3 spheresNormalList[lightBounces + 1] = {0};
*lightray = originalRay; *lightray = originalRay;
RGBA tempPixel = (RGBA){1,1,1,1};
sphere *nearestSphere = nullptr;
quad *nearestQuad = nullptr;
vec3 nearestCollisionPoint = {10000,10000,10000};
RGBA objectColorList[lightBounces + 1] = {0};
RGBA tempPixel = raytrace(objectList, objectCount, lightray);
for (int j = 0; j <= lightBounces; j++) { pixel.r += tempPixel.r;
nearestSphere = nullptr; pixel.g += tempPixel.g;
double nearestSphereDistance = 10000000; pixel.b += tempPixel.b;
nearestQuad = nullptr; //pixel.a += tempPixel.a;
double nearestQuadDistance = 10000000;
nearestCollisionPoint = (vec3){10000,10000,10000};
for (int i = 0; i < sphereCount; i++) {
vec3 collisionPoint = collisionPointSphere(lightray, sphereList[i]);
double collisionPointDistance = 1000000;
if (collisionPoint.x == -10000000) {
}
else{
collisionPointDistance = vec3Length(vec3Subtract(collisionPoint, lightray->origin));
if (collisionPointDistance < vec3Length(vec3Subtract(nearestCollisionPoint, lightray->origin))) {
nearestCollisionPoint = collisionPoint;
nearestSphere = sphereList[i];
nearestSphereDistance = collisionPointDistance;
}
}
}
for (int i = 0; i < quadCount; i++) {
vec3 collisionPoint = collisionQuad(lightray, quadList[i]);
double collisionPointDistance = 1000000;
if (collisionPoint.x == -10000000) {
}
else{
collisionPointDistance = vec3Length(vec3Subtract(collisionPoint, lightray->origin));
if (collisionPointDistance < vec3Length(vec3Subtract(nearestCollisionPoint, lightray->origin))) {
nearestCollisionPoint = collisionPoint;
nearestQuad = quadList[i];
nearestQuadDistance = collisionPointDistance;
}
}
}
if (nearestQuadDistance > nearestSphereDistance) {
if (nearestSphere != nullptr) {
objectColorList[j] = nearestSphere->color;
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};
}
}
else {
if (nearestQuad != nullptr) {
objectColorList[j] = nearestQuad->color;
quadHitList[j] = nearestQuad;
//diffus:
lightray->direction = vec3Add(nearestQuad->normal, randUnitVector());
if (fabs(lightray->direction.x ) <= epsilon || fabs(lightray->direction.y ) <= epsilon || fabs(lightray->direction.z) <= epsilon) {
lightray->direction = nearestQuad->normal;
}
//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; 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 //average pixelData
pixel.r = pixel.r / raysPerPixel; pixel.r = pixel.r / raysPerPixel;
pixel.g = pixel.g / raysPerPixel; pixel.g = pixel.g / raysPerPixel;
pixel.b = pixel.b / raysPerPixel; pixel.b = pixel.b / raysPerPixel;
pixel.a = pixel.a / raysPerPixel; //pixel.a = pixel.a / raysPerPixel;
//free(spheresHitList); //free(spheresHitList);
//free(spheresNormalList); //free(spheresNormalList);
return pixel; return pixel;
} }
+5 -1
View File
@@ -1,4 +1,8 @@
#pragma once #pragma once
#include "structs.h" #include "structs.h"
RGBA raytraceSphere(sphere **, ray *); RGBA getPixelColor(object [], int, ray *);
RGBA raytrace(object [], int, ray *);
RGBA getRayColor(RGBA [], bool []);
+6 -2
View File
@@ -32,7 +32,6 @@ struct sphere {
vec3 origin; vec3 origin;
double radius; double radius;
RGBA color; RGBA color;
int isLight;
}; typedef struct sphere sphere; }; typedef struct sphere sphere;
struct plane { struct plane {
@@ -46,5 +45,10 @@ struct quad {
vec3 v2; vec3 v2;
vec3 normal; vec3 normal;
RGBA color; RGBA color;
int isLight;
}; typedef struct quad quad; }; typedef struct quad quad;
struct object {
int objectType; // 0 = sphere, 1 = Quad
void *objectPointer;
bool isLight;
}; typedef struct object object;
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 MiB

After

Width:  |  Height:  |  Size: 260 KiB