Skip to content

Commit

Permalink
Merge pull request vkoskiv#55 from VKoskiv/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
vkoskiv committed Jan 30, 2020
2 parents b00fb90 + a707dab commit 83305dc
Show file tree
Hide file tree
Showing 27 changed files with 124 additions and 81 deletions.
6 changes: 6 additions & 0 deletions C-Ray.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@
9058A51222231E9F00193385 /* learn.c in Sources */ = {isa = PBXBuildFile; fileRef = 9058A50F22231E9E00193385 /* learn.c */; };
9058A51522231EB100193385 /* Tinn.c in Sources */ = {isa = PBXBuildFile; fileRef = 9058A51422231EB100193385 /* Tinn.c */; };
907CD47A2240DFFF003947B0 /* multiplatform.c in Sources */ = {isa = PBXBuildFile; fileRef = 907CD4792240DFFF003947B0 /* multiplatform.c */; };
90908A6F23E0707E0081377B /* assert.c in Sources */ = {isa = PBXBuildFile; fileRef = 90908A6E23E0707E0081377B /* assert.c */; };
90908A7023E0707E0081377B /* assert.c in Sources */ = {isa = PBXBuildFile; fileRef = 90908A6E23E0707E0081377B /* assert.c */; };
9095392523C15A7B0017037C /* c-ray.c in Sources */ = {isa = PBXBuildFile; fileRef = 9095392423C15A7B0017037C /* c-ray.c */; };
9095392623C15A7B0017037C /* c-ray.c in Sources */ = {isa = PBXBuildFile; fileRef = 9095392423C15A7B0017037C /* c-ray.c */; };
9095392923C15AAB0017037C /* networking.c in Sources */ = {isa = PBXBuildFile; fileRef = 9095392823C15AAB0017037C /* networking.c */; };
Expand Down Expand Up @@ -178,6 +180,7 @@
9058A51422231EB100193385 /* Tinn.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Tinn.c; sourceTree = "<group>"; };
907CD4782240DFFF003947B0 /* multiplatform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = multiplatform.h; sourceTree = "<group>"; };
907CD4792240DFFF003947B0 /* multiplatform.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = multiplatform.c; sourceTree = "<group>"; };
90908A6E23E0707E0081377B /* assert.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = assert.c; sourceTree = "<group>"; };
9095392323C15A7B0017037C /* c-ray.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "c-ray.h"; sourceTree = "<group>"; };
9095392423C15A7B0017037C /* c-ray.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "c-ray.c"; sourceTree = "<group>"; };
9095392723C15AAB0017037C /* networking.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = networking.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -351,6 +354,7 @@
90FB15CA22596E79008D6AAA /* gitsha1.c.in */,
90FB15C922596E79008D6AAA /* gitsha1.h */,
90204C7823A07F2C00B01EEF /* assert.h */,
90908A6E23E0707E0081377B /* assert.c */,
9095392723C15AAB0017037C /* networking.h */,
9095392823C15AAB0017037C /* networking.c */,
);
Expand Down Expand Up @@ -497,6 +501,7 @@
905842EB236651FC009D92F1 /* texture.c in Sources */,
905842EC236651FC009D92F1 /* objloader.c in Sources */,
905842ED236651FC009D92F1 /* lightRay.c in Sources */,
90908A7023E0707E0081377B /* assert.c in Sources */,
905842EE236651FC009D92F1 /* pcg_basic.c in Sources */,
905842EF236651FC009D92F1 /* gitsha1.c in Sources */,
905842F0236651FC009D92F1 /* learn.c in Sources */,
Expand Down Expand Up @@ -545,6 +550,7 @@
90FB15CE225C6D85008D6AAA /* texture.c in Sources */,
90CA851D2252C90C00BA7702 /* objloader.c in Sources */,
900BA131220B4603005B8EE7 /* lightRay.c in Sources */,
90908A6F23E0707E0081377B /* assert.c in Sources */,
90369CCC222E012F008D215B /* pcg_basic.c in Sources */,
90FB15CB22596E79008D6AAA /* gitsha1.c in Sources */,
9058A51222231E9F00193385 /* learn.c in Sources */,
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2019 Valtteri Koskivuori
Copyright (c) 2015, Valtteri Koskivuori

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
10 changes: 2 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,10 @@
<img src="https://i.imgur.com/fPBuCTG.png" width="256">
</p>

## Rendering with SDL installed
## Example render (2500 samples, 2560x1600, 512 max bounces, 1h 22min)

<p align="center">
<img src="https://media.giphy.com/media/8cT6Dbo7kCi3rRj5Fr/giphy.gif" width="512">
</p>

## Example render (2000 samples, 1920x1080, 50 bounces, 1h 55min)

<p align="center">
<img src="https://teensyimg.com/images/PLxxP7lRVE.png" width="768">
<img src="https://teensyimg.com/images/qv0JtPxJ7c.png" width="768">
</p>

## Status
Expand Down
22 changes: 11 additions & 11 deletions src/acceleration/bbox.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@

#include "../datatypes/vertexbuffer.h"
#include "../datatypes/poly.h"
#include "../utils/assert.h"

/**
Get the longest axis of an axis-aligned bounding box
@param bbox Bounding box to compute longest axis for
@return Longest axis as an enum
*/
enum bboxAxis getLongestAxis(struct boundingBox *bbox) {
enum bboxAxis getLongestAxis(const struct boundingBox *bbox) {
float x = fabs(bbox->start.x - bbox->end.x);
float y = fabs(bbox->start.y - bbox->end.y);
float z = fabs(bbox->start.z - bbox->end.z);
Expand All @@ -33,7 +34,9 @@ enum bboxAxis getLongestAxis(struct boundingBox *bbox) {
@param count Amount of polygons indices given
@return Axis-aligned bounding box
*/
struct boundingBox *computeBoundingBox(int *polys, int count) {
struct boundingBox *computeBoundingBox(const int *polys, const int count) {
ASSERT(polys);
ASSERT(count > 0);
struct boundingBox *bbox = calloc(1, sizeof(struct boundingBox));
struct vector minPoint = vecWithPos(FLT_MAX, FLT_MAX, FLT_MAX);
struct vector maxPoint = vecWithPos(-FLT_MAX, -FLT_MAX, -FLT_MAX);
Expand Down Expand Up @@ -67,14 +70,11 @@ struct boundingBox *computeBoundingBox(int *polys, int count) {
@param t Current max t value for the ray
@return true if intersected, false otherwise
*/
bool rayIntersectWithAABB(struct boundingBox *box, struct lightRay *ray, float *t) {
bool rayIntersectWithAABB(const struct boundingBox *box, const struct lightRay *ray, float *t) {
//If a mesh has no polygons, it won't have a root bbox either.
if (!box) return false;

struct vector dirfrac;
dirfrac.x = 1.0 / ray->direction.x;
dirfrac.y = 1.0 / ray->direction.y;
dirfrac.z = 1.0 / ray->direction.z;
struct vector dirfrac = vecWithPos(1.0f / ray->direction.x, 1.0f / ray->direction.y, 1.0f / ray->direction.z);

float t1 = (box->start.x - ray->start.x)*dirfrac.x;
float t2 = (box-> end.x - ray->start.x)*dirfrac.x;
Expand Down Expand Up @@ -102,9 +102,9 @@ bool rayIntersectWithAABB(struct boundingBox *box, struct lightRay *ray, float *
return true;
}

float findSurfaceArea(struct boundingBox box) {
float width = box.end.x - box.start.x;
float height = box.end.y - box.start.y;
float length = box.end.z - box.start.z;
float findSurfaceArea(const struct boundingBox *box) {
float width = box->end.x - box->start.x;
float height = box->end.y - box->start.y;
float length = box->end.z - box->start.z;
return 2 * (length * width) + 2 * (length * height) + 2 * (width * height);
}
8 changes: 4 additions & 4 deletions src/acceleration/bbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,18 @@ struct boundingBox {
/// Computes a bounding box for a given array of polygons
/// @param polys Array of polygons to process
/// @param count Amount of polygons given
struct boundingBox *computeBoundingBox(int *polys, int count);
struct boundingBox *computeBoundingBox(const int *polys, const int count);

/// Compute the longest axis of a given bounding box
/// @param bbox Bounding box to process
enum bboxAxis getLongestAxis(struct boundingBox *bbox);
enum bboxAxis getLongestAxis(const struct boundingBox *bbox);

/// Checks for an intersection between a given ray and bounding box
/// @param box Bounding box to check intersection against
/// @param ray Ray to intersect
/// @param t Distance the intersection occurred at along the ray
bool rayIntersectWithAABB(struct boundingBox *box, struct lightRay *ray, float *t);
bool rayIntersectWithAABB(const struct boundingBox *box, const struct lightRay *ray, float *t);

/// Compute the surface area of a given bounding box
/// @param box Bounding box to compute surface area for
float findSurfaceArea(struct boundingBox box);
float findSurfaceArea(const struct boundingBox *box);
19 changes: 9 additions & 10 deletions src/acceleration/kdtree.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,10 @@ struct kdTreeNode *getNewNode() {
return node;
}

struct kdTreeNode *buildTree(int *polygons, int polyCount, int depth) {
struct kdTreeNode *buildTree(int *polygons, const int polyCount) {
struct kdTreeNode *node = getNewNode();
node->polygons = polygons;
node->polyCount = polyCount;
node->depth = depth;

if (polyCount == 0)
return node;
Expand All @@ -82,7 +81,7 @@ struct kdTreeNode *buildTree(int *polygons, int polyCount, int depth) {
}

node->bbox = computeBoundingBox(node->polygons, node->polyCount);
float currentSAHCost = node->polyCount * findSurfaceArea(*node->bbox);
float currentSAHCost = node->polyCount * findSurfaceArea(node->bbox);

struct vector midPoint = node->bbox->midPoint;

Expand Down Expand Up @@ -123,8 +122,8 @@ struct kdTreeNode *buildTree(int *polygons, int polyCount, int depth) {
struct boundingBox *leftBBox = computeBoundingBox(leftPolys.array, (int)leftPolys.used);
struct boundingBox *rightBBox = computeBoundingBox(rightPolys.array, (int)rightPolys.used);

float leftSAHCost = leftPolys.used * findSurfaceArea(*leftBBox);
float rightSAHCost = rightPolys.used * findSurfaceArea(*rightBBox);
float leftSAHCost = leftPolys.used * findSurfaceArea(leftBBox);
float rightSAHCost = rightPolys.used * findSurfaceArea(rightBBox);

free(leftBBox);
free(rightBBox);
Expand All @@ -137,15 +136,15 @@ struct kdTreeNode *buildTree(int *polygons, int polyCount, int depth) {
if (rightPolys.used > 0 && !rightFreed) freeArray(&rightPolys);
} else {
//Keep going
node->left = buildTree(leftPolys.array, (int)leftPolys.used, depth + 1);
node->right = buildTree(rightPolys.array, (int)rightPolys.used, depth + 1);
node->left = buildTree(leftPolys.array, (int)leftPolys.used);
node->right = buildTree(rightPolys.array, (int)rightPolys.used);
}

return node;
}

//Recurse through tree and count orphan nodes with no polygons
int checkTree(struct kdTreeNode *node) {
int checkTree(const struct kdTreeNode *node) {
int orphans = 0;
if (node) {
if (node->polyCount == 0) {
Expand All @@ -161,7 +160,7 @@ int checkTree(struct kdTreeNode *node) {
return orphans;
}

int countNodes(struct kdTreeNode *node) {
int countNodes(const struct kdTreeNode *node) {
int nodes = 0;
if (node) {
if (node->left) {
Expand All @@ -175,7 +174,7 @@ int countNodes(struct kdTreeNode *node) {
return nodes;
}

bool rayIntersectsWithNode(struct kdTreeNode *node, struct lightRay *ray, struct hitRecord *isect) {
bool rayIntersectsWithNode(const struct kdTreeNode *node, const struct lightRay *ray, struct hitRecord *isect) {
if (!node) return false;
//A bit of a hack, but it does work...!
float fakeIsect = 20000.0;
Expand Down
9 changes: 4 additions & 5 deletions src/acceleration/kdtree.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,28 +17,27 @@ struct kdTreeNode {
struct kdTreeNode *right;//Pointer to right child
int *polygons; //indices to polygons within the bounding box
int polyCount; //Amount of polygons
int depth;
};

/// Builds a KD-tree for a given array of polygons and returns a pointer to the root node
/// @param polygons Array of polygons to process
/// @param polyCount Amount of polygons given
/// @param depth Current depth for recursive calls
struct kdTreeNode *buildTree(int *polygons, int polyCount, int depth);
struct kdTreeNode *buildTree(int *polygons, const int polyCount);

/// Traverses a given KD-tree to find an intersection between a ray and a polygon in that tree. Hopefully really fast.
/// @param node Root node to start traversing from
/// @param ray Ray to check intersection against
/// @param isect Intersection information is saved to this struct
bool rayIntersectsWithNode(struct kdTreeNode *node, struct lightRay *ray, struct hitRecord *isect);
bool rayIntersectsWithNode(const struct kdTreeNode *node, const struct lightRay *ray, struct hitRecord *isect);

/// Count total nodes in a given tree
/// @param node root node of a tree to evaluate
int countNodes(struct kdTreeNode *node);
int countNodes(const struct kdTreeNode *node);

/// Check the health of a given tree
/// @param node root node of a tree to evaluate
int checkTree(struct kdTreeNode *node);
int checkTree(const struct kdTreeNode *node);

/// Free a given tree
/// @param node Root node of a tree to free
Expand Down
4 changes: 4 additions & 0 deletions src/c-ray.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ void crInitTerminal() {
initTerminal();
}

void crRestoreTerminal() {
restoreTerminal();
}

void crInitSDL() {
#ifdef UI_ENABLED
ASSERT(!grenderer->mainDisplay->window);
Expand Down
1 change: 1 addition & 0 deletions src/c-ray.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ char *crGetVersion(void); //The current semantic version
char *crGitHash(int chars); //The current git hash of the build

void crInitTerminal(void); //Disable output buffering and configure Windows terminals
void crRestoreTerminal(void);

struct renderInfo;
struct texture;
Expand Down
10 changes: 5 additions & 5 deletions src/datatypes/material.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ struct vector randomOnUnitSphere(pcg32_random_t *rng) {
return vecNormalize(vec);
}

bool emissiveBSDF(struct hitRecord *isect, struct lightRay *ray, struct color *attenuation, struct lightRay *scattered, pcg32_random_t *rng) {
bool emissiveBSDF(struct hitRecord *isect, const struct lightRay *ray, struct color *attenuation, struct lightRay *scattered, pcg32_random_t *rng) {
(void)isect;
(void)ray;
(void)attenuation;
Expand All @@ -229,7 +229,7 @@ bool emissiveBSDF(struct hitRecord *isect, struct lightRay *ray, struct color *a
return false;
}

bool weightedBSDF(struct hitRecord *isect, struct lightRay *ray, struct color *attenuation, struct lightRay *scattered, pcg32_random_t *rng) {
bool weightedBSDF(struct hitRecord *isect, const struct lightRay *ray, struct color *attenuation, struct lightRay *scattered, pcg32_random_t *rng) {
(void)isect;
(void)ray;
(void)attenuation;
Expand All @@ -248,7 +248,7 @@ struct color diffuseColor(struct hitRecord *isect) {
return isect->end.hasTexture ? colorForUV(isect) : isect->end.diffuse;
}

bool lambertianBSDF(struct hitRecord *isect, struct lightRay *ray, struct color *attenuation, struct lightRay *scattered, pcg32_random_t *rng) {
bool lambertianBSDF(struct hitRecord *isect, const struct lightRay *ray, struct color *attenuation, struct lightRay *scattered, pcg32_random_t *rng) {
(void)ray;
struct vector temp = vecAdd(isect->hitPoint, isect->surfaceNormal);
struct vector rand = randomInUnitSphere(rng);
Expand All @@ -258,7 +258,7 @@ bool lambertianBSDF(struct hitRecord *isect, struct lightRay *ray, struct color
return true;
}

bool metallicBSDF(struct hitRecord *isect, struct lightRay *ray, struct color *attenuation, struct lightRay *scattered, pcg32_random_t *rng) {
bool metallicBSDF(struct hitRecord *isect, const struct lightRay *ray, struct color *attenuation, struct lightRay *scattered, pcg32_random_t *rng) {
(void)ray;
struct vector normalizedDir = vecNormalize(isect->incident.direction);
struct vector reflected = reflectVec(&normalizedDir, &isect->surfaceNormal);
Expand Down Expand Up @@ -296,7 +296,7 @@ float shlick(float cosine, float IOR) {
}

// Only works on spheres for now. Reflections work but refractions don't
bool dialectricBSDF(struct hitRecord *isect, struct lightRay *ray, struct color *attenuation, struct lightRay *scattered, pcg32_random_t *rng) {
bool dialectricBSDF(struct hitRecord *isect, const struct lightRay *ray, struct color *attenuation, struct lightRay *scattered, pcg32_random_t *rng) {
(void)ray;
struct vector outwardNormal;
struct vector reflected = reflectVec(&isect->incident.direction, &isect->surfaceNormal);
Expand Down
10 changes: 5 additions & 5 deletions src/datatypes/material.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ struct material {

enum bsdfType type;
//isect record, ray, attenuation color, scattered ray, rng
bool (*bsdf)(struct hitRecord*, struct lightRay*, struct color*, struct lightRay*, pcg32_random_t*);
bool (*bsdf)(struct hitRecord*, const struct lightRay*, struct color*, struct lightRay*, pcg32_random_t*);
};

//temporary newMaterial func
Expand All @@ -113,10 +113,10 @@ struct material emptyMaterial(void);
struct material defaultMaterial(void);
struct material warningMaterial(void);

bool emissiveBSDF(struct hitRecord *isect, struct lightRay *ray, struct color *attenuation, struct lightRay *scattered, pcg32_random_t *rng);
bool lambertianBSDF(struct hitRecord *isect, struct lightRay *ray, struct color *attenuation, struct lightRay *scattered, pcg32_random_t *rng);
bool metallicBSDF(struct hitRecord *isect, struct lightRay *ray, struct color *attenuation, struct lightRay *scattered, pcg32_random_t *rng);
bool dialectricBSDF(struct hitRecord *isect, struct lightRay *ray, struct color *attenuation, struct lightRay *scattered, pcg32_random_t *rng);
bool emissiveBSDF(struct hitRecord *isect, const struct lightRay *ray, struct color *attenuation, struct lightRay *scattered, pcg32_random_t *rng);
bool lambertianBSDF(struct hitRecord *isect, const struct lightRay *ray, struct color *attenuation, struct lightRay *scattered, pcg32_random_t *rng);
bool metallicBSDF(struct hitRecord *isect, const struct lightRay *ray, struct color *attenuation, struct lightRay *scattered, pcg32_random_t *rng);
bool dialectricBSDF(struct hitRecord *isect, const struct lightRay *ray, struct color *attenuation, struct lightRay *scattered, pcg32_random_t *rng);

void assignBSDF(struct material *mat);

Expand Down
2 changes: 1 addition & 1 deletion src/datatypes/poly.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
struct poly *polygonArray;
int polyCount;

bool rayIntersectsWithPolygon(struct lightRay *ray, struct poly *poly, float *result, struct vector *normal, struct coord *uv) {
bool rayIntersectsWithPolygon(const struct lightRay *ray, const struct poly *poly, float *result, struct vector *normal, struct coord *uv) {
float orientation, inverseOrientation;
struct vector edge1 = vecSub(vertexArray[poly->vertexIndex[2]], vertexArray[poly->vertexIndex[0]]);
struct vector edge2 = vecSub(vertexArray[poly->vertexIndex[1]], vertexArray[poly->vertexIndex[0]]);
Expand Down
2 changes: 1 addition & 1 deletion src/datatypes/poly.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@ struct coord;

//Calculates intersection between a light ray and a polygon object. Returns true if intersection has happened.
//result will be set to distance of intersect point, normal will be set to intersect normal, uv is the barycentric coord of that point
bool rayIntersectsWithPolygon(struct lightRay *ray, struct poly *poly, float *result, struct vector *normal, struct coord *uv);
bool rayIntersectsWithPolygon(const struct lightRay *ray, const struct poly *poly, float *result, struct vector *normal, struct coord *uv);
2 changes: 1 addition & 1 deletion src/datatypes/scene.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ void computeKDTrees(struct mesh *meshes, int meshCount) {
for (int j = 0; j < meshes[i].polyCount; j++) {
indices[j] = meshes[i].firstPolyIndex + j;
}
meshes[i].tree = buildTree(indices, meshes[i].polyCount, 0);
meshes[i].tree = buildTree(indices, meshes[i].polyCount);

// Optional tree checking
/*int orphans = checkTree(meshes[i].tree);
Expand Down
4 changes: 2 additions & 2 deletions src/datatypes/sphere.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ struct sphere newLightSphere(struct vector pos, float radius, struct color color
}

//Calculates intersection with a sphere and a light ray
bool intersect(struct lightRay *ray, struct sphere *sphere, float *t) {
bool intersect(const struct lightRay *ray, const struct sphere *sphere, float *t) {
bool intersects = false;

//Vector dot product of the direction
Expand Down Expand Up @@ -72,7 +72,7 @@ bool intersect(struct lightRay *ray, struct sphere *sphere, float *t) {
return intersects;
}

bool rayIntersectsWithSphere(struct sphere *sphere, struct lightRay *ray, struct hitRecord *isect) {
bool rayIntersectsWithSphere(const struct lightRay *ray, const struct sphere *sphere, struct hitRecord *isect) {
//Pass the distance value to rayIntersectsWithSphere, where it's set
if (intersect(ray, sphere, &isect->distance)) {
isect->type = hitTypeSphere;
Expand Down
2 changes: 1 addition & 1 deletion src/datatypes/sphere.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ struct sphere newLightSphere(struct vector pos, float radius, struct color color
struct sphere defaultSphere(void);

//Calculates intersection between a light ray and a sphere
bool rayIntersectsWithSphere(struct sphere *sphere, struct lightRay *ray, struct hitRecord *isect);
bool rayIntersectsWithSphere(const struct lightRay *ray, const struct sphere *sphere, struct hitRecord *isect);
Loading

0 comments on commit 83305dc

Please sign in to comment.