Refactor
code ist jetzt schner aber ich habe durch einen pointer fehler in raytrace.c (nearestObject = ¤tObject //zeigt immer auf die selbne adresse) ein art negativ bild erzeugt
This commit is contained in:
+15
-16
@@ -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
@@ -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
@@ -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);
|
||||||
|
|||||||
+107
-118
@@ -2,124 +2,29 @@
|
|||||||
#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[]) {
|
||||||
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};
|
|
||||||
quad *quadHitList[lightBounces + 1] = {0};
|
|
||||||
vec3 spheresNormalList[lightBounces + 1] = {0};
|
|
||||||
*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};
|
|
||||||
|
|
||||||
|
|
||||||
for (int j = 0; j <= lightBounces; j++) {
|
|
||||||
nearestSphere = nullptr;
|
|
||||||
double nearestSphereDistance = 10000000;
|
|
||||||
nearestQuad = nullptr;
|
|
||||||
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;
|
int firstLightHitIndex = -1;
|
||||||
for (int i = 0; i <= lightBounces && spheresHitList[i] != nullptr; i++) {
|
RGBA rayColor = {1,1,1,1};
|
||||||
if (spheresHitList[i]->isLight == 1) {
|
for (int i = 0; i <= lightBounces; i++) {
|
||||||
|
if (isLightList[i] == 1) {
|
||||||
firstLightHitIndex = i;
|
firstLightHitIndex = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (firstLightHitIndex == -1) {
|
if (firstLightHitIndex == -1) {
|
||||||
tempPixel = (RGBA){0,0,0,1};
|
rayColor = (RGBA){0,0,0,1};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -128,30 +33,114 @@ RGBA raytraceSphere(sphere **sphereList, int sphereCount, quad **quadList, int q
|
|||||||
//pixel.b += spheresHitList[firstLightHitIndex]->color.b;
|
//pixel.b += spheresHitList[firstLightHitIndex]->color.b;
|
||||||
//pixel.a += spheresHitList[firstLightHitIndex]->color.a;
|
//pixel.a += spheresHitList[firstLightHitIndex]->color.a;
|
||||||
for (int i = firstLightHitIndex; i >= 0; i--) {
|
for (int i = firstLightHitIndex; i >= 0; i--) {
|
||||||
tempPixel.r = tempPixel.r * spheresHitList[i]->color.r;
|
rayColor.r = rayColor.r * colorList[i].r;
|
||||||
tempPixel.g = tempPixel.g * spheresHitList[i]->color.g;
|
rayColor.g = rayColor.g * colorList[i].g;
|
||||||
tempPixel.b = tempPixel.b * spheresHitList[i]->color.b;
|
rayColor.b = rayColor.b * colorList[i].b;
|
||||||
tempPixel.a = tempPixel.a * spheresHitList[i]->color.a;
|
//rayColor.a = rayColor.a * colorList[i].a;
|
||||||
}
|
}
|
||||||
pixel.r += tempPixel.r;
|
|
||||||
pixel.g += tempPixel.g;
|
|
||||||
pixel.b += tempPixel.b;
|
|
||||||
pixel.a += tempPixel.a;
|
|
||||||
|
|
||||||
//pixel.r = -vec3Product(sphereNormal, lightray->direction);
|
//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};
|
//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 = ¤tObject;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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};
|
||||||
|
int raysPerPixel = 2;
|
||||||
|
ray originalRay = *lightray;
|
||||||
|
|
||||||
|
for (int k = 0; k < raysPerPixel; k++) {
|
||||||
|
*lightray = originalRay;
|
||||||
|
|
||||||
|
RGBA tempPixel = raytrace(objectList, objectCount, lightray);
|
||||||
|
|
||||||
|
pixel.r += tempPixel.r;
|
||||||
|
pixel.g += tempPixel.g;
|
||||||
|
pixel.b += tempPixel.b;
|
||||||
|
//pixel.a += tempPixel.a;
|
||||||
}
|
}
|
||||||
|
|
||||||
//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
@@ -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 []);
|
||||||
|
|||||||
@@ -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;
|
||||||
Reference in New Issue
Block a user