Skip to content

Commit

Permalink
Bug fixes, add gpu driven culling pipeline.
Browse files Browse the repository at this point in the history
  • Loading branch information
himanshugoel2797 committed Aug 30, 2020
1 parent 030d4f2 commit 905487f
Show file tree
Hide file tree
Showing 41 changed files with 1,712 additions and 679 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
*.pch

# Libraries
*.lib
*.a
*.la
*.lo
Expand Down Expand Up @@ -128,3 +127,4 @@ build/*
*.zip
/.vs
/out/build
test_builds/
6 changes: 4 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ add_executable(ProtoVoxel main.cpp ${SRC_FILES})
set_property(TARGET ProtoVoxel PROPERTY CXX_STANDARD 17)
set_property(TARGET ProtoVoxel PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)

set_target_properties(ProtoVoxel PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})

target_compile_options(ProtoVoxel PRIVATE -mavx2 -mbmi)
#target_link_directories(ProtoVoxel PRIVATE ${CMAKE_SOURCE_DIR}/glfw/lib-mingw-w64)
target_link_libraries(ProtoVoxel glfw glad imgui pthread OpenGL::GL ${CMAKE_DL_LIBS})
target_link_directories(ProtoVoxel PRIVATE ${CMAKE_SOURCE_DIR}/glfw/lib-vc2019)
target_link_libraries(ProtoVoxel glfw glad imgui OpenGL::GL ${CMAKE_DL_LIBS})
target_compile_definitions(ProtoVoxel PRIVATE DEBUG)
target_compile_definitions(ProtoVoxel PRIVATE _USE_MATH_DEFINES)
target_include_directories(ProtoVoxel PRIVATE ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/glfw/include)
Expand Down
15 changes: 15 additions & 0 deletions CMakeSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,21 @@
"ctestCommandArgs": "",
"inheritEnvironments": [ "clang_cl_x64_x64" ],
"variables": []
},
{
"name": "WSL-GCC-Release",
"generator": "Ninja",
"configurationType": "RelWithDebInfo",
"buildRoot": "${projectDir}\\out\\build\\${name}",
"installRoot": "${projectDir}\\out\\install\\${name}",
"cmakeExecutable": "/usr/bin/cmake",
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": "",
"inheritEnvironments": [ "linux_x64" ],
"wslPath": "${defaultWSLPath}",
"addressSanitizerRuntimeFlags": "detect_leaks=0",
"variables": []
}
]
}
Binary file added glfw/lib-vc2019/glfw.lib
Binary file not shown.
Binary file added glfw/lib-vc2019/glfw3dll.lib
Binary file not shown.
4 changes: 2 additions & 2 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@ class TestScene : public PVSG::SceneBase

void Update(double time) override
{
manager.Update(camera.GetParameters()->eyePos, PVSG::SceneBase::camera_buffer.GetBuffer());
manager.Update(camera.GetParameters()->eyePos, camera.GetParameters()->vp, PVSG::SceneBase::camera_buffer.GetBuffer());
PVSG::SceneBase::Update(time);
}

void Render(double time) override
{
manager.Render(time);
manager.Render(PVSG::SceneBase::camera_buffer.GetBuffer(), time);
}
};

Expand Down
37 changes: 37 additions & 0 deletions shaders/hiz/convert.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#version 460

layout (local_size_x = 8, local_size_y = 8) in;

// Values that stay constant for the whole mesh.
layout(std140, binding = 0) uniform GlobalParams_t {
mat4 proj;
mat4 view;
mat4 vp;
mat4 ivp;
mat4 prev_proj;
mat4 prev_view;
mat4 prev_vp;
mat4 prev_ivp;
vec4 prev_eyePos;
vec4 prev_eyeUp;
vec4 prev_eyeDir;
vec4 eyePos;
vec4 eyeUp;
vec4 eyeDir;
vec4 eyeRight;
} GlobalParams;

uniform layout(binding = 0) sampler2D depthBuffer;
uniform layout(binding = 0, rg32f) restrict writeonly image2D mipBuffer;

void main(){
ivec2 px = ivec2(gl_GlobalInvocationID.xy);
vec4 a0 = texelFetch(depthBuffer, px, 0);

ivec2 sz = imageSize(mipBuffer);

vec4 opos = vec4(2.0f * (px / vec2(sz)) - 1.0f, a0.r, 1);
vec4 reproj = opos;

imageStore(mipBuffer, ivec2(sz * (reproj.xy * 0.5f + 0.5f)), vec4(reproj.z));
}
38 changes: 38 additions & 0 deletions shaders/hiz/convert_reproj.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#version 460

layout (local_size_x = 8, local_size_y = 8) in;

// Values that stay constant for the whole mesh.
layout(std140, binding = 0) uniform GlobalParams_t {
mat4 proj;
mat4 view;
mat4 vp;
mat4 ivp;
mat4 prev_proj;
mat4 prev_view;
mat4 prev_vp;
mat4 prev_ivp;
vec4 prev_eyePos;
vec4 prev_eyeUp;
vec4 prev_eyeDir;
vec4 eyePos;
vec4 eyeUp;
vec4 eyeDir;
vec4 eyeRight;
} GlobalParams;

uniform layout(binding = 0) sampler2D depthBuffer;
uniform layout(binding = 0, rg32f) restrict writeonly image2D mipBuffer;

void main(){
ivec2 px = ivec2(gl_GlobalInvocationID.xy);
vec4 a0 = texelFetch(depthBuffer, px, 0);

ivec2 sz = imageSize(mipBuffer);

vec4 opos = vec4(2.0f * (px / vec2(sz)) - 1.0f, a0.r, 1);
vec4 reproj = GlobalParams.vp * GlobalParams.prev_ivp * opos;
reproj /= reproj.w;

imageStore(mipBuffer, ivec2(sz * (reproj.xy * 0.5f + 0.5f)), vec4(reproj.z));
}
40 changes: 40 additions & 0 deletions shaders/hiz/downsample.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#version 460

layout (local_size_x = 8, local_size_y = 8) in;

// Values that stay constant for the whole mesh.
layout(std140, binding = 0) uniform GlobalParams_t {
mat4 proj;
mat4 view;
mat4 vp;
mat4 ivp;
mat4 prev_proj;
mat4 prev_view;
mat4 prev_vp;
mat4 prev_ivp;
vec4 prev_eyePos;
vec4 prev_eyeUp;
vec4 prev_eyeDir;
vec4 eyePos;
vec4 eyeUp;
vec4 eyeDir;
vec4 eyeRight;
} GlobalParams;

uniform layout(binding = 0, rg32f) restrict readonly image2D inBuffer;
uniform layout(binding = 1, rg32f) restrict writeonly image2D outBuffer;

void main(){
ivec2 px = ivec2(gl_GlobalInvocationID.xy);

vec4 a0 = imageLoad(inBuffer, px * 2 + ivec2(0, 0));
vec4 a1 = imageLoad(inBuffer, px * 2 + ivec2(0, 1));
vec4 a2 = imageLoad(inBuffer, px * 2 + ivec2(1, 0));
vec4 a3 = imageLoad(inBuffer, px * 2 + ivec2(1, 1));

vec4 bounds;
bounds.x = min(min(a0.x, a1.x), min(a2.x, a3.x));
bounds.y = max(max(a0.y, a1.y), max(a2.y, a3.y));

imageStore(outBuffer, px, bounds);
}
164 changes: 164 additions & 0 deletions shaders/splatting/bucket.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
//ComputeShader
#version 460

layout (local_size_x = 1024, local_size_y = 1) in;

// Values that stay constant for the whole mesh.
layout(std140, binding = 0) uniform GlobalParams_t {
mat4 proj;
mat4 view;
mat4 vp;
mat4 ivp;
mat4 prev_proj;
mat4 prev_view;
mat4 prev_vp;
mat4 prev_ivp;
vec4 prev_eyePos;
vec4 prev_eyeUp;
vec4 prev_eyeDir;
vec4 eyePos;
vec4 eyeUp;
vec4 eyeDir;
vec4 eyeRight;
} GlobalParams;

layout(std430, binding = 0) readonly restrict buffer ChunkOffsets_t {
ivec4 v[];
} ChunkOffsets;

layout(std430, binding = 4) writeonly restrict buffer OutChunkOffsets_t {
ivec4 v[];
} out_chunkoffs;

layout(std430, binding = 5) writeonly restrict buffer SplatChunkOffsets_t {
ivec4 v[];
} splat_chunkoffs;

layout(std430, binding = 7) writeonly restrict buffer RejectChunkOffsets_t {
ivec4 v[];
} reject_chunkoffs;

struct draw_cmd_t {
uint count;
uint instanceCount;
uint baseVertex;
uint baseInstance;
};

layout(std430, binding = 1) readonly restrict buffer InDrawCalls_t{
uint cnt;
uint pd0;
uint pd1;
uint pd2;
draw_cmd_t cmds[];
} in_draws;

layout(std430, binding = 2) restrict coherent buffer OutDrawCalls_t{
uint cnt;
uint pd0;
uint pd1;
uint pd2;
draw_cmd_t cmds[];
} out_draws;

layout(std430, binding = 3) restrict coherent buffer Splats_t{
uint cnt;
uint pd0;
uint pd1;
uint pd2;
draw_cmd_t cmds[];
} splats;

layout(std430, binding = 6) restrict coherent buffer Rejects_t{
uint cnt;
uint pd0;
uint pd1;
uint pd2;
draw_cmd_t cmds[];
} rejects;

uniform layout(binding = 0) sampler2D hiz_map;

vec4 offsets[8] = vec4[] (
vec4(15, 31, 15, 0),
vec4(15, 31, -15, 0),
vec4(15, -31, 15, 0),
vec4(15, -31, -15, 0),
vec4(-15, 31, 15, 0),
vec4(-15, 31, -15, 0),
vec4(-15, -31, 15, 0),
vec4(-15, -31, -15, 0)
);

void main(){
uint DrawID = gl_GlobalInvocationID.x;
if (DrawID >= in_draws.cnt)
return;

vec3 UV = vec3(ChunkOffsets.v[DrawID].x + 15, ChunkOffsets.v[DrawID].y + 31, ChunkOffsets.v[DrawID].z + 15);
vec4 bbox;
bbox = GlobalParams.vp * (vec4(UV, 1) + offsets[0]);
bbox /= bbox.w;

vec3 max_comps = bbox.xyz;
vec3 min_comps = bbox.xyz;

for (int i = 1; i < 8; i++){
bbox = GlobalParams.vp * (vec4(UV, 1) + offsets[i]);
bbox /= bbox.w;

max_comps = max(bbox.xyz, max_comps);
min_comps = min(bbox.xyz, min_comps);
}

max_comps.xy = max_comps.xy * 0.5f + 0.5f;
min_comps.xy = min_comps.xy * 0.5f + 0.5f;

//Chunk is outside the frustum, don't draw
max_comps.xy = clamp(max_comps.xy, vec2(0), vec2(1));
min_comps.xy = clamp(min_comps.xy, vec2(0), vec2(1));

vec2 dvec0 = (max_comps.xy - min_comps.xy) * 1024.0f; //Convert to pixels
float max_rad = max(dvec0.x, dvec0.y);

//Choose a mipmap level to test against
float lod = ceil( log2 ( max_rad ));
vec4 samples;
samples.x = textureLod(hiz_map, vec2(min_comps.x, min_comps.y), lod).x;
samples.y = textureLod(hiz_map, vec2(min_comps.x, max_comps.y), lod).x;
samples.z = textureLod(hiz_map, vec2(max_comps.x, max_comps.y), lod).x;
samples.w = textureLod(hiz_map, vec2(max_comps.x, min_comps.y), lod).x;
float sampledDepth = min(min(samples.x, samples.y), min(samples.z, samples.w));
//min=farthest point, max=nearest point

if (max_rad == 0) //Out of view
return;

if (sampledDepth >= max_comps.z) //If the chunk is fully behind the sampled depth, don't render it
{
uint idx = atomicAdd(rejects.cnt, 1);
rejects.cmds[idx].count = in_draws.cmds[DrawID].count;
rejects.cmds[idx].instanceCount = in_draws.cmds[DrawID].instanceCount;
rejects.cmds[idx].baseVertex = in_draws.cmds[DrawID].baseVertex;
rejects.cmds[idx].baseInstance = in_draws.cmds[DrawID].baseInstance;
reject_chunkoffs.v[idx] = ChunkOffsets.v[DrawID];
} else if (max_rad <= 60)
{
//Splat voxels via compute
uint idx = atomicAdd(splats.cnt, 1);
splats.cmds[idx].count = in_draws.cmds[DrawID].count;
splats.cmds[idx].instanceCount = in_draws.cmds[DrawID].instanceCount;
splats.cmds[idx].baseVertex = in_draws.cmds[DrawID].baseVertex;
splats.cmds[idx].baseInstance = in_draws.cmds[DrawID].baseInstance;
splat_chunkoffs.v[idx] = ChunkOffsets.v[DrawID];
}else
{
//Splat voxels via raster
uint idx = atomicAdd(out_draws.cnt, 1);
out_draws.cmds[idx].count = in_draws.cmds[DrawID].count;
out_draws.cmds[idx].instanceCount = in_draws.cmds[DrawID].instanceCount;
out_draws.cmds[idx].baseVertex = in_draws.cmds[DrawID].baseVertex;
out_draws.cmds[idx].baseInstance = in_draws.cmds[DrawID].baseInstance;
out_chunkoffs.v[idx] = ChunkOffsets.v[DrawID];
}
}
Loading

0 comments on commit 905487f

Please sign in to comment.