Skip to content

Commit

Permalink
Russian Roulette, Conditional Compilation
Browse files Browse the repository at this point in the history
  • Loading branch information
knightcrawler25 committed Dec 30, 2020
1 parent bf09f0b commit 77e70ce
Show file tree
Hide file tree
Showing 13 changed files with 140 additions and 28 deletions.
15 changes: 14 additions & 1 deletion src/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,9 +283,22 @@ void MainLoop(void* arg)

if (ImGui::CollapsingHeader("Render Settings"))
{
bool requiresReload = false;
Vec3* bgCol = &renderOptions.bgColor;

optionsChanged |= ImGui::SliderInt("Max Depth", &renderOptions.maxDepth, 1, 10);
optionsChanged |= ImGui::Checkbox("Use envmap", &renderOptions.useEnvMap);
requiresReload |= ImGui::Checkbox("Enable HDR", &renderOptions.useEnvMap);
optionsChanged |= ImGui::SliderFloat("HDR multiplier", &renderOptions.hdrMultiplier, 0.1f, 10.0f);
requiresReload |= ImGui::Checkbox("Enable RR", &renderOptions.enableRR);
requiresReload |= ImGui::SliderInt("RR Depth", &renderOptions.RRDepth, 1, 10);
requiresReload |= ImGui::Checkbox("Enable Constant BG", &renderOptions.useConstantBg);
optionsChanged |= ImGui::ColorEdit3("Background Color", (float*)bgCol, 0);

if (requiresReload)
{
scene->renderOptions = renderOptions;
InitRenderer();
}
}

if (ImGui::CollapsingHeader("Camera"))
Expand Down
2 changes: 1 addition & 1 deletion src/core/Program.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ namespace GLSLPT
glDeleteProgram(object);
object = 0;
printf("Error %s\n", msg.c_str());
throw std::runtime_error(msg);
throw std::runtime_error(msg.c_str());
}
}

Expand Down
7 changes: 4 additions & 3 deletions src/core/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,16 @@

#include "Config.h"
#include "Renderer.h"
#include "ShaderIncludes.h"
#include "Scene.h"

namespace GLSLPT
{
Program *LoadShaders(const std::string& vertShaderFilename, const std::string& fragShaderFilename)
Program *LoadShaders(const ShaderInclude::ShaderSource& vertShaderObj, const ShaderInclude::ShaderSource& fragShaderObj)
{
std::vector<Shader> shaders;
shaders.push_back(Shader(vertShaderFilename, GL_VERTEX_SHADER));
shaders.push_back(Shader(fragShaderFilename, GL_FRAGMENT_SHADER));
shaders.push_back(Shader(vertShaderObj, GL_VERTEX_SHADER));
shaders.push_back(Shader(fragShaderObj, GL_FRAGMENT_SHADER));
return new Program(shaders);
}

Expand Down
11 changes: 10 additions & 1 deletion src/core/Renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,13 @@
#include "Quad.h"
#include "Program.h"
#include <Vec2.h>
#include <Vec3.h>

#include <vector>

namespace GLSLPT
{
Program *LoadShaders(const std::string &vertShaderFilename, const std::string &fragShaderFilename);
Program* LoadShaders(const ShaderInclude::ShaderSource& vertShaderObj, const ShaderInclude::ShaderSource& fragShaderObj);

struct RenderOptions
{
Expand All @@ -49,13 +50,21 @@ namespace GLSLPT
useEnvMap = false;
resolution = iVec2(1280, 720);
hdrMultiplier = 1.0f;
enableRR = true;
useConstantBg = false;
RRDepth = 2;
bgColor = Vec3(1.0f, 1.0f, 1.0f);
}
iVec2 resolution;
int maxDepth;
int tileWidth;
int tileHeight;
bool useEnvMap;
bool enableRR;
bool useConstantBg;
int RRDepth;
float hdrMultiplier;
Vec3 bgColor;
};

class Scene;
Expand Down
11 changes: 4 additions & 7 deletions src/core/Shader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,17 @@
*/

#include "Shader.h"
#include "ShaderIncludes.h"
#include <iostream>
#include <fstream>
#include <sstream>

namespace GLSLPT
{
Shader::Shader(const std::string& filePath, GLenum shaderType)
Shader::Shader(const ShaderInclude::ShaderSource& sourceObj, GLenum shaderType)
{
std::string source = GLSLPT::ShaderInclude::load(filePath);

object = glCreateShader(shaderType);
printf("Compiling Shader %s -> %d\n", filePath.c_str(), int(object));
const GLchar *src = (const GLchar *)source.c_str();
printf("Compiling Shader %s -> %d\n", sourceObj.path.c_str(), int(object));
const GLchar *src = (const GLchar *)sourceObj.src.c_str();
glShaderSource(object, 1, &src, 0);
glCompileShader(object);
GLint success = 0;
Expand All @@ -53,7 +50,7 @@ namespace GLSLPT
glGetShaderiv(object, GL_INFO_LOG_LENGTH, &logSize);
char *info = new char[logSize + 1];
glGetShaderInfoLog(object, logSize, NULL, info);
msg += filePath;
msg += sourceObj.path;
msg += "\n";
msg += info;
delete[] info;
Expand Down
3 changes: 2 additions & 1 deletion src/core/Shader.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#pragma once

#include <string>
#include "ShaderIncludes.h"
#include "Config.h"

namespace GLSLPT
Expand All @@ -39,7 +40,7 @@ namespace GLSLPT
private:
GLuint object;
public:
Shader(const std::string& filePath, GLuint shaderType);
Shader(const ShaderInclude::ShaderSource& sourceObj, GLuint shaderType);
GLuint getObject() const;
};
}
17 changes: 13 additions & 4 deletions src/core/ShaderIncludes.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,15 @@ namespace GLSLPT
class ShaderInclude
{
public:

struct ShaderSource
{
std::string src;
std::string path;
};

// Return the source code of the complete shader
static std::string load(std::string path, std::string includeIndentifier = "#include")
static ShaderSource load(std::string path, std::string includeIndentifier = "#include")
{
includeIndentifier += ' ';
static bool isRecursiveCall = false;
Expand All @@ -79,7 +86,7 @@ namespace GLSLPT
if (!file.is_open())
{
std::cerr << "ERROR: could not open the shader at: " << path << "\n" << std::endl;
return fullSourceCode;
return ShaderSource{ fullSourceCode, path };
}

std::string lineBuffer;
Expand All @@ -99,7 +106,7 @@ namespace GLSLPT
// By using recursion, the new include file can be extracted
// and inserted at this location in the shader source code
isRecursiveCall = true;
fullSourceCode += load(lineBuffer);
fullSourceCode += load(lineBuffer).src;

// Do not add this line to the shader source code, as the include
// path would generate a compilation issue in the final source code
Expand All @@ -116,9 +123,11 @@ namespace GLSLPT

file.close();

return fullSourceCode;
return ShaderSource{ fullSourceCode, path };;
}



private:
static void getFilePath(const std::string& fullPath, std::string& pathWithoutFileName)
{
Expand Down
51 changes: 46 additions & 5 deletions src/core/TiledRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,49 @@ namespace GLSLPT
// Shaders
//----------------------------------------------------------

pathTraceShader = LoadShaders(shadersDirectory + "common/vertex.glsl", shadersDirectory + "tiled.glsl");
pathTraceShaderLowRes = LoadShaders(shadersDirectory + "common/vertex.glsl", shadersDirectory + "progressive.glsl");
accumShader = LoadShaders(shadersDirectory + "common/vertex.glsl", shadersDirectory + "accumulation.glsl");
tileOutputShader = LoadShaders(shadersDirectory + "common/vertex.glsl", shadersDirectory + "tileOutput.glsl");
outputShader = LoadShaders(shadersDirectory + "common/vertex.glsl", shadersDirectory + "output.glsl");
ShaderInclude::ShaderSource vertexShaderSrcObj = ShaderInclude::load(shadersDirectory + "common/vertex.glsl");
ShaderInclude::ShaderSource pathTraceShaderSrcObj = ShaderInclude::load(shadersDirectory + "tiled.glsl");
ShaderInclude::ShaderSource pathTraceShaderLowResSrcObj = ShaderInclude::load(shadersDirectory + "progressive.glsl");
ShaderInclude::ShaderSource accumShaderSrcObj = ShaderInclude::load(shadersDirectory + "accumulation.glsl");
ShaderInclude::ShaderSource tileOutputShaderSrcObj = ShaderInclude::load(shadersDirectory + "tileOutput.glsl");
ShaderInclude::ShaderSource outputShaderSrcObj = ShaderInclude::load(shadersDirectory + "output.glsl");

// Add preprocessor defines for conditional compilation
std::string defines = "";
if (scene->renderOptions.useEnvMap && scene->hdrData != nullptr)
defines += "#define ENVMAP\n";
if (!scene->lights.empty())
defines += "#define LIGHTS\n";
if (scene->renderOptions.enableRR)
{
defines += "#define RR\n";
defines += "#define RR_DEPTH " + std::to_string(scene->renderOptions.RRDepth) + "\n";
}
if (scene->renderOptions.useConstantBg)
defines += "#define CONSTANT_BG\n";

if (defines.size() > 0)
{
size_t idx = pathTraceShaderSrcObj.src.find("#version");
if (idx != -1)
idx = pathTraceShaderSrcObj.src.find("\n", idx);
else
idx = 0;
pathTraceShaderSrcObj.src.insert(idx + 1, defines);

idx = pathTraceShaderLowResSrcObj.src.find("#version");
if (idx != -1)
idx = pathTraceShaderLowResSrcObj.src.find("\n", idx);
else
idx = 0;
pathTraceShaderLowResSrcObj.src.insert(idx + 1, defines);
}

pathTraceShader = LoadShaders(vertexShaderSrcObj, pathTraceShaderSrcObj);
pathTraceShaderLowRes = LoadShaders(vertexShaderSrcObj, pathTraceShaderLowResSrcObj);
accumShader = LoadShaders(vertexShaderSrcObj, accumShaderSrcObj);
tileOutputShader = LoadShaders(vertexShaderSrcObj, tileOutputShaderSrcObj);
outputShader = LoadShaders(vertexShaderSrcObj, outputShaderSrcObj);

printf("Debug sizes : %d %d - %d %d\n", tileWidth, tileHeight, screenSize.x, screenSize.y);
//----------------------------------------------------------
Expand Down Expand Up @@ -414,6 +452,7 @@ namespace GLSLPT
glUniform1i(glGetUniformLocation(shaderObject, "maxDepth"), scene->renderOptions.maxDepth);
glUniform1i(glGetUniformLocation(shaderObject, "tileX"), tileX);
glUniform1i(glGetUniformLocation(shaderObject, "tileY"), tileY);
glUniform3f(glGetUniformLocation(shaderObject, "bgColor"), scene->renderOptions.bgColor.x, scene->renderOptions.bgColor.y, scene->renderOptions.bgColor.z);
pathTraceShader->StopUsing();

pathTraceShaderLowRes->Use();
Expand All @@ -428,6 +467,8 @@ namespace GLSLPT
glUniform1i(glGetUniformLocation(shaderObject, "useEnvMap"), scene->hdrData == nullptr ? false : scene->renderOptions.useEnvMap);
glUniform1f(glGetUniformLocation(shaderObject, "hdrMultiplier"), scene->renderOptions.hdrMultiplier);
glUniform1i(glGetUniformLocation(shaderObject, "maxDepth"), scene->camera->isMoving || scene->instancesModified ? 2: scene->renderOptions.maxDepth);
glUniform3f(glGetUniformLocation(shaderObject, "camera.position"), scene->camera->position.x, scene->camera->position.y, scene->camera->position.z);
glUniform3f(glGetUniformLocation(shaderObject, "bgColor"), scene->renderOptions.bgColor.x, scene->renderOptions.bgColor.y, scene->renderOptions.bgColor.z);
pathTraceShaderLowRes->StopUsing();

outputShader->Use();
Expand Down
8 changes: 8 additions & 0 deletions src/loaders/Loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ namespace GLSLPT
if (strstr(line, "Renderer"))
{
char envMap[200] = "None";
char enableRR[10] = "None";

while (fgets(line, kMaxLineLength, file))
{
Expand All @@ -226,13 +227,20 @@ namespace GLSLPT
sscanf(line, " maxDepth %i", &renderOptions.maxDepth);
sscanf(line, " tileWidth %i", &renderOptions.tileWidth);
sscanf(line, " tileHeight %i", &renderOptions.tileHeight);
sscanf(line, " enableRR %s", enableRR);
sscanf(line, " RRDepth %i", &renderOptions.RRDepth);
}

if (strcmp(envMap, "None") != 0)
{
scene->AddHDR(path + envMap);
renderOptions.useEnvMap = true;
}

if (strcmp(enableRR, "False") == 0)
renderOptions.enableRR = false;
else if (strcmp(enableRR, "True") == 0)
renderOptions.enableRR = true;
}


Expand Down
2 changes: 2 additions & 0 deletions src/shaders/common/closest_hit.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ float ClosestHit(Ray r, inout State state, inout LightSampleRec lightSampleRec)
float t = INFINITY;
float d;

#ifdef LIGHTS
// Intersect Emitters
for (int i = 0; i < numOfLights; i++)
{
Expand Down Expand Up @@ -81,6 +82,7 @@ float ClosestHit(Ray r, inout State state, inout LightSampleRec lightSampleRec)
}
}
}
#endif

int stack[64];
int ptr = 0;
Expand Down
34 changes: 29 additions & 5 deletions src/shaders/common/pathtrace.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,8 @@ vec3 DirectLight(in Ray r, in State state)
vec3 surfacePos = state.fhp + state.ffnormal * EPS;

// Environment Light
if (useEnvMap)
#ifdef ENVMAP
#ifndef CONSTANT_BG
{
vec3 color;
vec4 dirPdf = EnvSample(color);
Expand All @@ -165,9 +166,11 @@ vec3 DirectLight(in Ray r, in State state)
}
}
}
#endif
#endif

// Analytic Lights
if (numOfLights > 0)
#ifdef LIGHTS
{
LightSampleRec lightSampleRec;
Light light;
Expand Down Expand Up @@ -204,8 +207,8 @@ vec3 DirectLight(in Ray r, in State state)

L += powerHeuristic(lightPdf, bsdfPdf) * f * abs(dot(state.ffnormal, lightDir)) * lightSampleRec.emission / lightPdf;
}

}
#endif

return L;
}
Expand All @@ -228,7 +231,10 @@ vec3 PathTrace(Ray r)

if (t == INFINITY)
{
if (useEnvMap)
#ifdef CONSTANT_BG
radiance += bgColor * throughput;
#else
#ifdef ENVMAP
{
float misWeight = 1.0f;
vec2 uv = vec2((PI + atan(r.direction.z, r.direction.x)) * (1.0 / TWO_PI), acos(r.direction.y) * (1.0 / PI));
Expand All @@ -240,6 +246,8 @@ vec3 PathTrace(Ray r)
}
radiance += misWeight * texture(hdrTex, uv).xyz * throughput * hdrMultiplier;
}
#endif
#endif
return radiance;
}

Expand All @@ -248,12 +256,13 @@ vec3 PathTrace(Ray r)

radiance += state.mat.emission * throughput;

#ifdef LIGHTS
if (state.isEmitter)
{
radiance += EmitterSample(r, state, lightSampleRec, bsdfSampleRec) * throughput;
break;
}

#endif
radiance += DirectLight(r, state) * throughput;

bsdfSampleRec.bsdfDir = DisneySample(r, state);
Expand All @@ -263,6 +272,21 @@ vec3 PathTrace(Ray r)
throughput *= DisneyEval(r, state, bsdfSampleRec.bsdfDir) * abs(dot(state.ffnormal, bsdfSampleRec.bsdfDir)) / bsdfSampleRec.pdf;
else
break;

#ifdef RR
// Russian roulette
if (depth >= RR_DEPTH)
{
float q = max(max(throughput.x, max(throughput.y, throughput.z)), 0.001);
if (rand() > q)
break;

throughput *= 1.0 / q;
}
#endif




r.direction = bsdfSampleRec.bsdfDir;
r.origin = state.fhp + r.direction * EPS;
Expand Down
Loading

0 comments on commit 77e70ce

Please sign in to comment.