Skip to content
This repository has been archived by the owner on Oct 3, 2022. It is now read-only.

Commit

Permalink
WIP refractions
Browse files Browse the repository at this point in the history
Refactor path tracing code into a new class
  • Loading branch information
jonathonracz committed Mar 5, 2018
1 parent cf2f2e0 commit e95e18c
Show file tree
Hide file tree
Showing 9 changed files with 115 additions and 43 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
xcuserdata
.idea
2 changes: 2 additions & 0 deletions jtracer.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
28D27E1B200A7079003D055E /* JTCGRender.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = JTCGRender.mm; sourceTree = "<group>"; };
28D27E1D200AD081003D055E /* JTTrace.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JTTrace.h; sourceTree = "<group>"; };
28D27E1E200D6974003D055E /* JTRay.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JTRay.h; sourceTree = "<group>"; };
B45291C48DD11DD635616B89 /* JTPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JTPath.h; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -174,6 +175,7 @@
282B906D200EBC9400889ED9 /* JTSphereList.h */,
28D27E1D200AD081003D055E /* JTTrace.h */,
28C648821FFF247700454706 /* JTTypes.h */,
B45291C48DD11DD635616B89 /* JTPath.h */,
);
path = Trace;
sourceTree = "<group>";
Expand Down
4 changes: 2 additions & 2 deletions jtracer/JTRenderState.mm
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ - (id)init {


_uniformsInternal->spheres[0].materialParams.albedo = make_float3(1.0f, 0.0f, 0.0f);
_uniformsInternal->spheres[0].materialParams.roughness = 1.0f;
_uniformsInternal->spheres[0].materialParams.roughness = 0.0f;
_uniformsInternal->spheres[0].materialParams.reflectivity = 1.0f;

_uniformsInternal->spheres[1].materialParams.albedo = make_float3(0.0f, 1.0f, 0.0f);
_uniformsInternal->spheres[1].materialParams.roughness = 0.5f;
_uniformsInternal->spheres[1].materialParams.roughness = 0.25f;
_uniformsInternal->spheres[1].materialParams.reflectivity = 0.5f;

_uniformsInternal->spheres[2].materialParams.albedo = make_float3(0.0f, 0.0f, 1.0f);
Expand Down
11 changes: 10 additions & 1 deletion jtracer/Trace/JTBSDF.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,16 @@ struct Parameters
float3 albedo = make_float3(1.0f, 1.0f, 1.0f);
float roughness = 1.0f;
float reflectivity = 0.5f;
float ior = 1.1f;
float transparency = 0.0f;
};

inline float3 scatter(JT_THREAD PRNG& random, JT_THREAD const Parameters& params, JT_THREAD const float3& incident, JT_THREAD const float3& normal)
{
bool isReflection = random.generateNormalNotIncluding1() > params.transparency;

float3 scattered = make_float3(0.0f, 0.0f, 0.0f);

float3 reflection = Math::reflect(incident, normal);
float3 diffuse = random.generateInUnitSphere();
// Make sure the diffuse ray is actually a reflection - i.e. leaving the
Expand All @@ -35,7 +41,10 @@ inline float3 scatter(JT_THREAD PRNG& random, JT_THREAD const Parameters& params

// TODO: This may be better off as a slerp so there isn't a lopsided
// resolution between the center and edges of the interpolation...
float3 scattered = Math::lerp(reflection, diffuse, params.roughness);
scattered = Math::lerp(reflection, diffuse, params.roughness);

assert(!equal(scattered, make_float3(0.0f, 0.0f, 0.0f)));

return scattered;
}

Expand Down
73 changes: 73 additions & 0 deletions jtracer/Trace/JTPath.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//
// JTPath.h
// jtracer
//
// Created by Jonathon Racz on 1/19/18.
// Copyright © 2018 jonathonracz. All rights reserved.
//

#pragma once

#include "JTTypes.h"
#include "JTRay.h"
#include "JTBackgroundGradient.h"

namespace jt
{

class Path
{
public:
Path(JT_THREAD PRNG& _random, JT_THREAD const BackgroundGradient& _background, JT_THREAD const SphereList& _sphereList) :
random(_random), background(_background), sphereList(_sphereList)
{
}

float3 trace(JT_THREAD Ray ray)
{
Sphere::HitRecord hitRecord;

uint64 numBounces = 0;
float3 colorAccumulator = make_float3(0.0f, 0.0f, 0.0f);
float reflection = 1.0f;
float currentIOR = 1.0f;

float3 finalRayColor = make_float3(0.0f, 0.0f, 0.0f);
bool finalColorComputed = false;

do
{
bool didHit = sphereList.hitTest(ray, hitRecord, 0.001f);
if (didHit && reflection > 0.0f)
{
numBounces++;
colorAccumulator += hitRecord.materialParams.albedo;
reflection *= hitRecord.materialParams.reflectivity; // TODO: Fresnel-based reflection
float3 incident = normalize(ray.directionAtOrigin());
float3 scattered = BSDF::scatter(random, hitRecord.materialParams, incident, hitRecord.normal);
float3 target = hitRecord.p + (hitRecord.normal * 0.5f) + scattered;
ray = Ray(hitRecord.p, target - hitRecord.p);
}
else
{
float3 lightColor = background.color(ray);
if (numBounces > 0)
finalRayColor = lightColor * (colorAccumulator / numBounces) * reflection;
else
finalRayColor = lightColor;

finalColorComputed = true;
}
}
while (!finalColorComputed);

return finalRayColor;
}

private:
JT_THREAD PRNG& random;
JT_THREAD const BackgroundGradient& background;
JT_THREAD const SphereList& sphereList;
};

}
13 changes: 11 additions & 2 deletions jtracer/Trace/JTRandom.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ class PRNG
{
}

~PRNG() = default;

uint32 generate()
{
uint32 t = (x ^ (x >> 2));
Expand All @@ -47,6 +45,17 @@ class PRNG
return generate() / static_cast<float>(JT_UINT32_MAX);
}

float generateNormalNotIncluding1()
{
float ret;
// Algorithmically gross (theoretically unbounded), but it will do...
do
{
ret = generateNormal();
} while (ret == 1.0f);
return ret;
}

float3 generateInUnitSphere()
{
return (2.0f * normalize(make_float3(generateNormal(), generateNormal(), generateNormal()))) - 1;
Expand Down
2 changes: 1 addition & 1 deletion jtracer/Trace/JTSphere.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class Sphere
public:
struct HitRecord
{
float t;
float t = INFINITY;
float3 p;
float3 normal;
BSDF::Parameters materialParams;
Expand Down
41 changes: 6 additions & 35 deletions jtracer/Trace/JTTrace.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "JTRandom.h"
#include "JTBackgroundGradient.h"
#include "JTBSDF.h"
#include "JTPath.h"

namespace jt
{
Expand All @@ -31,49 +32,19 @@ float4 runTrace(JT_CONSTANT const Uniforms& uniforms, uint2 pos, uint2 dimension
// Create a sphere world.
Camera camera;
SphereList world(uniforms.spheres, sizeof(uniforms.spheres) / sizeof(uniforms.spheres[0]));
BackgroundGradient gradient { make_float3(0.5f, 0.7f, 1.0f), make_float3(1.0f, 1.0f, 1.0f) };
const BackgroundGradient gradient { make_float3(0.5f, 0.7f, 1.0f), make_float3(1.0f, 1.0f, 1.0f) };
Path path(random, gradient, world);

// Perform Path trace with a fallback to drawing the background.
float3 pixelColor = make_float3(0.0f, 0.0f, 0.0f);
size_t samplesPerPixel = 128;
for (size_t i = 0; i < samplesPerPixel; ++i) {
for (size_t i = 0; i < samplesPerPixel; ++i)
{
float u = (pos.x + (random.generateNormal() - 0.5f)) / static_cast<float>(dimensions.x);
float v = (pos.y + (random.generateNormal() - 0.5f)) / static_cast<float>(dimensions.y);
Ray ray = camera.makeRay(u, v);
Sphere::HitRecord hitRecord;
bool finalColorComputed = false;
float3 finalRayColor = make_float3(0.0f, 0.0f, 0.0f);
float3 rayColorAccumulator = make_float3(0.0f, 0.0f, 0.0f);
uint64 numBounces = 0;
float reflection = 1.0f;
do
{
bool didHit = world.hitTest(ray, hitRecord, 0.001f);
if (didHit && reflection > 0.0f)
{
numBounces++;
rayColorAccumulator += hitRecord.materialParams.albedo;
reflection *= hitRecord.materialParams.reflectivity; // TODO: Fresnel-based reflection
float3 incident = normalize(ray.directionAtOrigin());
float3 normal = normalize(hitRecord.normal); // Sometimes the floating point error is a bit off and freaks out asserts...
float3 scattered = BSDF::scatter(random, hitRecord.materialParams, incident, normal);
float3 target = hitRecord.p + scattered;
ray = Ray(hitRecord.p, target - hitRecord.p);
}
else
{
float3 lightColor = gradient.color(ray);
if (numBounces > 0)
finalRayColor = lightColor * (rayColorAccumulator / numBounces) * reflection;
else
finalRayColor = lightColor;

finalColorComputed = true;
}
}
while (!finalColorComputed);

pixelColor += finalRayColor;
pixelColor += path.trace(ray);
}

pixelColor /= samplesPerPixel;
Expand Down
11 changes: 9 additions & 2 deletions jtracer/Trace/JTTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,16 @@ namespace jt
}

template<typename T>
inline T reflect(T i, T n)
inline T reflect(T incident, T normal)
{
return i - (2 * dot(n, i) * n);
return incident - (2 * dot(normal, incident) * normal);
}

template<typename T>
inline T refract(T incident, T normal, float ior0, float ior1)
{
// TODO: Write own refract function
return refract(incident, normal, ior0 / ior1);
}

/** Lerp from x to y. */
Expand Down

0 comments on commit e95e18c

Please sign in to comment.