Skip to content

Commit

Permalink
Calculate direct light in voxels with compute shader
Browse files Browse the repository at this point in the history
  • Loading branch information
AdamYuan committed Jun 13, 2018
1 parent 85d617b commit 786a58c
Show file tree
Hide file tree
Showing 20 changed files with 192 additions and 77 deletions.
4 changes: 2 additions & 2 deletions ConeTracer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include "ConeTracer.hpp"
#include "Config.hpp"
#include "Resources.hpp"
#include "Voxelize.hpp"
#include "Voxels.hpp"

void ConeTracer::Initialize()
{
Expand All @@ -27,7 +27,7 @@ void ConeTracer::Initialize()
trace_shader_.SetUVoxelGridRangeMax(kVoxelGridRangeMax);
}

void ConeTracer::Update(const GBuffer &gbuffer, const Voxelize &voxels)
void ConeTracer::Update(const GBuffer &gbuffer, const Voxels &voxels)
{
mygl3::FrameBufferBinder binder(fbo_);

Expand Down
4 changes: 2 additions & 2 deletions ConeTracer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include <mygl3/framebuffer.hpp>
#include <asserts/TraceShader.hpp>
#include "GBuffer.hpp"
#include "Voxelize.hpp"
#include "Voxels.hpp"

class ConeTracer
{
Expand All @@ -19,7 +19,7 @@ class ConeTracer
asserts::TraceShader trace_shader_;
public:
void Initialize();
void Update(const GBuffer &gbuffer, const Voxelize &voxels);
void Update(const GBuffer &gbuffer, const Voxels &voxels);
const mygl3::Texture2D &Get() const { return half_result_; }
};

Expand Down
4 changes: 2 additions & 2 deletions Config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@

#include <glm/glm.hpp>

constexpr int kWidth = 1440, kHeight = 900;
constexpr int kWidth = 1280, kHeight = 720;
constexpr int kHalfWidth = kWidth / 2, kHalfHeight = kHeight / 2;
constexpr double kMouseX = kWidth / 2.0, kMouseY = kHeight / 2.0;

constexpr unsigned kInvocationSize = 2;

constexpr int kShadowWidth = 2048, kShadowHeight = 2048;

constexpr float kVoxelWorldSize = 0.25f;
constexpr float kVoxelWorldSize = 0.125f;
extern const glm::vec3 kVoxelGridRangeMin, kVoxelGridRangeMax;
extern const glm::ivec3 kVoxelDimension;

Expand Down
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# VcTest
My voxel cone tracing test in the sponza scene. Tested on debian 9 with Nvidia Quadro M1200.
My voxel cone tracing test in the sponza scene. Tested on debian 9 with Nvidia Quadro M1200. Uses about 1130MB video memory (for 512x256x256 voxels)
## Dependencies
OpenGL(>=4.5), [glfw(3.2.1)](https://www.glfw.org/), [stb_image.h](https://github.com/nothings/stb), [gl3w](https://github.com/skaslev/gl3w), [tinyobjloader](https://github.com/syoyo/tinyobjloader)
## Build
Expand All @@ -14,7 +14,12 @@ make
* C: Toggle albedo
* V: Toggle voxel cone tracing
* E: Toggle showing edge
* X: Debug voxel
## Screenshots
![alt text](https://raw.githubusercontent.com/AdamYuan/VcTest/master/screenshots/1.png)
![alt text](https://raw.githubusercontent.com/AdamYuan/VcTest/master/screenshots/2.png)
![alt text](https://raw.githubusercontent.com/AdamYuan/VcTest/master/screenshots/3.png)
## References
* https://jose-villegas.github.io/post/deferred_voxel_shading/
* https://simonstechblog.blogspot.com/2013/01/implementing-voxel-cone-tracing.html
* https://www.seas.upenn.edu/~pcozzi/OpenGLInsights/OpenGLInsights-SparseVoxelization.pdf
21 changes: 12 additions & 9 deletions Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,14 @@ void Renderer::Initialize()

skybox_.Initialize();

voxelize_.Initialize();
voxelize_.Update(shadow_map_.Get());
voxelize_.GenerateMipmap();
voxelize_.Bounce();
voxelize_.GenerateMipmap();
voxels_.Initialize();

voxels_.Voxelize();
voxels_.DirectLight(shadow_map_.Get());
voxels_.GenerateMipmap();

voxels_.Bounce();
voxels_.GenerateMipmap();

gbuffer_.Initialize();

Expand Down Expand Up @@ -49,14 +52,14 @@ void Renderer::Render(bool debug_voxel, bool indirect_trace, bool show_albedo, b
glViewport(0, 0, kWidth, kHeight);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
voxelize_.Debug();
voxels_.Debug();
return;
}

gbuffer_.Update();

if(indirect_trace)
cone_tracer_.Update(gbuffer_, voxelize_);
cone_tracer_.Update(gbuffer_, voxels_);

glViewport(0, 0, kWidth, kHeight);
glDisable(GL_DEPTH_TEST);
Expand All @@ -69,8 +72,8 @@ void Renderer::Render(bool debug_voxel, bool indirect_trace, bool show_albedo, b
cone_tracer_.Get().Bind(3);
skybox_.Get().Bind(4);
shadow_map_.Get().Bind(5);
voxelize_.GetRadiance().Bind(6);
for(int i = 0; i < 6; ++i) voxelize_.GetMipmap()[i].Bind(i + 9u);
voxels_.GetRadiance().Bind(6);
for(int i = 0; i < 6; ++i) voxels_.GetMipmap()[i].Bind(i + 9u);

final_shader_.Use();

Expand Down
4 changes: 2 additions & 2 deletions Renderer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@
#include <mygl3/framebuffer.hpp>
#include "ShadowMap.hpp"
#include "Skybox.hpp"
#include "Voxelize.hpp"
#include "Voxels.hpp"
#include "GBuffer.hpp"
#include "ConeTracer.hpp"
#include <asserts/FinalShader.hpp>

class Renderer
{
private:
Voxelize voxelize_;
Voxels voxels_;
ShadowMap shadow_map_;
Skybox skybox_;
GBuffer gbuffer_;
Expand Down
55 changes: 38 additions & 17 deletions Voxelize.cpp → Voxels.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Created by adamyuan on 5/19/18.
//

#include "Voxelize.hpp"
#include "Voxels.hpp"

#include <glm/gtc/matrix_transform.hpp>
#include <vector>
Expand All @@ -11,7 +11,7 @@

#include <GLFW/glfw3.h>

void Voxelize::Initialize()
void Voxels::Initialize()
{
//calculate mipmap sizes
max_mipmap_level_ = mygl3::Texture3D::GetLevel3D(kVoxelDimension.x, kVoxelDimension.y, kVoxelDimension.z);
Expand All @@ -37,9 +37,6 @@ void Voxelize::Initialize()
debug_shader_.SetUProjection(res::cam_projection);

voxelize_shader_.Initialize();
voxelize_shader_.SetULightDir(kLightDir);
voxelize_shader_.SetULightMatrix(res::light_matrix);

voxelize_shader_.SetUVoxelGridRangeMin(kVoxelGridRangeMin);
voxelize_shader_.SetUVoxelGridRangeMax(kVoxelGridRangeMax);
voxelize_shader_.SetUVoxelWorldSize(kVoxelWorldSize);
Expand All @@ -48,9 +45,16 @@ void Voxelize::Initialize()

bounce_shader_.Initialize();
bounce_shader_.SetUVoxelDimension(kVoxelDimension);

direct_light_shader_.Initialize();
direct_light_shader_.SetUVoxelDimension(kVoxelDimension);
direct_light_shader_.SetUVoxelGridRangeMin(kVoxelGridRangeMin);
direct_light_shader_.SetUVoxelWorldSize(kVoxelWorldSize);
direct_light_shader_.SetULightDir(kLightDir);
direct_light_shader_.SetULightMatrix(res::light_matrix);
}

void Voxelize::Update(const mygl3::Texture2D &shadow_map)
void Voxels::Voxelize()
{
glDisable(GL_CULL_FACE); glDisable(GL_DEPTH_TEST);
glBindImageTexture(5, albedo_texture_.Get(), 0, GL_TRUE, 0, GL_WRITE_ONLY, GL_RGBA8);
Expand All @@ -59,15 +63,16 @@ void Voxelize::Update(const mygl3::Texture2D &shadow_map)

glClear(GL_COLOR_BUFFER_BIT);
glViewport(0, 0, 1000, 1000);

double start = glfwGetTime();
voxelize_shader_.Use();
shadow_map.Bind(1);

res::sponza_model.Render();
printf("Voxelize lasted: %lf sec\n", glfwGetTime() - start);
printf("Voxelize lasted: %lf ms\n", (glfwGetTime() - start) * 1000.0f);
glEnable(GL_CULL_FACE); glEnable(GL_DEPTH_TEST);
}

void Voxelize::GenerateMipmap()
void Voxels::GenerateMipmap()
{
double start = glfwGetTime();

Expand All @@ -92,28 +97,44 @@ void Voxelize::GenerateMipmap()
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
}

//voxel_texture_.GenerateMipmap();
printf("Mipmapping lasted: %lf sec\n", glfwGetTime() - start);
printf("Mipmapping lasted: %lf ms\n", (glfwGetTime() - start) * 1000.0f);
}

void Voxels::DirectLight(const mygl3::Texture2D &shadow_map)
{
double start = glfwGetTime();

direct_light_shader_.Use();

glBindImageTexture(0, radiance_texture_.Get(), 0, GL_TRUE, 0, GL_WRITE_ONLY, GL_RGBA16);
albedo_texture_.Bind(0);
normal_texture_.Bind(1);
shadow_map.Bind(2);

glDispatchCompute(compute_group_sizes_[0].x, compute_group_sizes_[0].y, compute_group_sizes_[0].z);
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);

printf("Direct light lasted: %lf ms\n", (glfwGetTime() - start) * 1000.0f);
}

void Voxelize::Bounce()
void Voxels::Bounce()
{
double start = glfwGetTime();

bounce_shader_.Use();

glBindImageTexture(0, radiance_texture_.Get(), 0, GL_TRUE, 0, GL_READ_WRITE, GL_RGBA16);
glBindImageTexture(0, radiance_texture_.Get(), 0, GL_TRUE, 0, GL_WRITE_ONLY, GL_RGBA16);
albedo_texture_.Bind(0);
normal_texture_.Bind(1);
for(GLuint f = 0; f < 6; ++f) mipmaps_[f].Bind(f + 2);

glDispatchCompute(compute_group_sizes_[0].x, compute_group_sizes_[0].y, compute_group_sizes_[0].z);
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);

printf("Calculate a diffuse bounce lasted: %lf sec\n", glfwGetTime() - start);
printf("Calculate a diffuse bounce lasted: %lf ms\n", (glfwGetTime() - start) * 1000.0f);
}

void Voxelize::initialize_textures()
void Voxels::initialize_textures()
{
auto *data = new GLubyte[kVoxelDimension.x * kVoxelDimension.y * kVoxelDimension.z * 4];
std::fill(data, data + kVoxelDimension.x * kVoxelDimension.y * kVoxelDimension.z * 4, 0);
Expand Down Expand Up @@ -157,7 +178,7 @@ void Voxelize::initialize_textures()
}
}

void Voxelize::initialize_debug_object()
void Voxels::initialize_debug_object()
{
std::vector<glm::vec3> vertices;
std::vector<unsigned> indices;
Expand Down Expand Up @@ -266,7 +287,7 @@ void Voxelize::initialize_debug_object()
debug_object_.SetAttributes(0, 3, 1, 3, 2, 3);
}

void Voxelize::Debug()
void Voxels::Debug()
{
glDisable(GL_CULL_FACE);
radiance_texture_.SetSizeFilter(GL_NEAREST, GL_NEAREST);
Expand Down
13 changes: 8 additions & 5 deletions Voxelize.hpp → Voxels.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
// Created by adamyuan on 5/19/18.
//

#ifndef VXGITEST_VOXELIZE_HPP
#define VXGITEST_VOXELIZE_HPP
#ifndef VXGITEST_VOXELS_HPP
#define VXGITEST_VOXELS_HPP

#include <vector>
#include <mygl3/vertexobject.hpp>
Expand All @@ -12,8 +12,9 @@
#include <asserts/VoxelMipmapShader.hpp>
#include <asserts/VoxelDebugShader.hpp>
#include <asserts/VoxelBounceShader.hpp>
#include <asserts/VoxelDirectLightShader.hpp>

class Voxelize
class Voxels
{
private:
mygl3::Texture3D radiance_texture_, normal_texture_, albedo_texture_, mipmaps_[6];
Expand All @@ -26,12 +27,14 @@ class Voxelize
mygl3::VertexObject<true> debug_object_;

asserts::VoxelBounceShader bounce_shader_;
asserts::VoxelDirectLightShader direct_light_shader_;
void initialize_textures();
void initialize_debug_object();
public:
void Initialize();
void Update(const mygl3::Texture2D &shadow_map);
void Voxelize();
void GenerateMipmap();
void DirectLight(const mygl3::Texture2D &shadow_map);
void Bounce();
void Debug();
const mygl3::Texture3D &GetAlbedo() const { return albedo_texture_; }
Expand All @@ -41,4 +44,4 @@ class Voxelize
};


#endif //VXGITEST_VOXELIZE_HPP
#endif //VXGITEST_VOXELS_HPP
69 changes: 69 additions & 0 deletions dep/asserts/VoxelDirectLightShader.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
//GENERATED BY GLSL_GEN
#ifndef VOXELDIRECTLIGHTSHADER_HPP
#define VOXELDIRECTLIGHTSHADER_HPP
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <fstream>
#include <GL/gl3w.h>
namespace asserts {
class VoxelDirectLightShader {
private:
GLuint program_{0};
public:
void Use() const { glUseProgram(program_); }
GLuint Get() const { return program_; }
VoxelDirectLightShader() = default;
~VoxelDirectLightShader(){ if(program_ != 0) glDeleteProgram(program_); }
VoxelDirectLightShader(const VoxelDirectLightShader &) = delete;
VoxelDirectLightShader& operator= (const VoxelDirectLightShader &) = delete;
private:
GLint unif_uVoxelDimension;
GLint unif_uLightMatrix;
GLint unif_uLightDir;
GLint unif_uVoxelGridRangeMin;
GLint unif_uVoxelWorldSize;
public:
void Initialize() {
GLuint shader;
program_ = glCreateProgram();
std::ifstream in; std::string str;
char log[100000]; int success;
in.open("shaders/voxel_direct_light.comp");
if(in.is_open()) {
std::getline(in, str, '\0');
in.close();
} else {
str.clear();
printf("[GLSLGEN ERROR] failed to load shaders/voxel_direct_light.comp\n");
}
const char *GL_COMPUTE_SHADER_src = str.c_str();
shader = glCreateShader(GL_COMPUTE_SHADER);
glShaderSource(shader, 1, &GL_COMPUTE_SHADER_src, nullptr);
glCompileShader(shader);
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if(!success) {
glGetShaderInfoLog(shader, 100000, nullptr, log);
printf("[GLSLGEN ERROR] compile error in shaders/voxel_direct_light.comp:\n%s\n", log);
}
glAttachShader(program_, shader);
glLinkProgram(program_);
glDeleteShader(shader);
unif_uVoxelDimension = glGetUniformLocation(program_, "uVoxelDimension");
unif_uLightMatrix = glGetUniformLocation(program_, "uLightMatrix");
unif_uLightDir = glGetUniformLocation(program_, "uLightDir");
unif_uVoxelGridRangeMin = glGetUniformLocation(program_, "uVoxelGridRangeMin");
unif_uVoxelWorldSize = glGetUniformLocation(program_, "uVoxelWorldSize");
}
void SetUVoxelDimension(const glm::ivec3 &v) { glProgramUniform3iv(program_, unif_uVoxelDimension, 1, glm::value_ptr(v)); }
GLint GetUVoxelDimensionLocation() const { return unif_uVoxelDimension; };
void SetULightMatrix(const glm::mat4 &v) { glProgramUniformMatrix4fv(program_, unif_uLightMatrix, 1, GL_FALSE, glm::value_ptr(v)); }
GLint GetULightMatrixLocation() const { return unif_uLightMatrix; };
void SetULightDir(const glm::vec3 &v) { glProgramUniform3fv(program_, unif_uLightDir, 1, glm::value_ptr(v)); }
GLint GetULightDirLocation() const { return unif_uLightDir; };
void SetUVoxelGridRangeMin(const glm::vec3 &v) { glProgramUniform3fv(program_, unif_uVoxelGridRangeMin, 1, glm::value_ptr(v)); }
GLint GetUVoxelGridRangeMinLocation() const { return unif_uVoxelGridRangeMin; };
void SetUVoxelWorldSize(GLfloat v) { glProgramUniform1f(program_, unif_uVoxelWorldSize, v); }
GLint GetUVoxelWorldSizeLocation() const { return unif_uVoxelWorldSize; };
};
}
#endif
Binary file modified screenshots/1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified screenshots/2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified screenshots/3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 786a58c

Please sign in to comment.