Skip to content

Commit

Permalink
Use tight bounds for occlusion culling, use single pass downsampler f…
Browse files Browse the repository at this point in the history
…or small mip computation.
  • Loading branch information
himanshugoel2797 committed Sep 4, 2020
1 parent 905487f commit d557e9a
Show file tree
Hide file tree
Showing 39 changed files with 1,075 additions and 747 deletions.
8 changes: 7 additions & 1 deletion CMakeSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,13 @@
"buildCommandArgs": "",
"ctestCommandArgs": "",
"inheritEnvironments": [ "clang_cl_x64_x64" ],
"variables": []
"variables": [
{
"name": "CMAKE_EXE_LINKER_FLAGS",
"value": "/machine:x64 /PROFILE",
"type": "STRING"
}
]
},
{
"name": "WSL-GCC-Release",
Expand Down
Binary file added dec.bin
Binary file not shown.
7 changes: 6 additions & 1 deletion imgui.ini
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ Size=400,400
Collapsed=0

[Window][Dear ImGui Metrics]
Pos=60,60
Pos=1,1
Size=345,239
Collapsed=0

[Window][Camera Info]
Pos=-11,262
Size=352,65
Collapsed=0

Binary file added in.bin
Binary file not shown.
14 changes: 11 additions & 3 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

#include "voxel/PerlinNoise.h"

#include "imgui/imgui.h"

#include <chrono>
#include <fstream>
#include <iostream>
Expand All @@ -30,13 +32,11 @@ class TestScene : public PVSG::SceneBase

PVV::ChunkPalette palette;
PVV::ChunkManager manager;
PVV::ChunkJobManager jobManager;


void Initialize() override
{
PVSG::SceneBase::Initialize();

jobManager.Initialize();
palette.Initialize();
for (int i = 255; i >= 0; i--)
palette.Register(glm::vec4(0, i / 255.0, 0, 1));
Expand All @@ -53,6 +53,14 @@ class TestScene : public PVSG::SceneBase
void Render(double time) override
{
manager.Render(PVSG::SceneBase::camera_buffer.GetBuffer(), time);

auto tmp = camera.GetParameters()->eyePos;

ImGui::Begin("Camera Info");
ImGui::Text("Camera Position: %f, %f, %f\n", tmp.x, tmp.y, tmp.z);
tmp = camera.GetParameters()->eyeDir;
ImGui::Text("Camera Direction: %f, %f, %f\n", tmp.x, tmp.y, tmp.z);
ImGui::End();
}
};

Expand Down
Binary file added out.bin
Binary file not shown.
1 change: 1 addition & 0 deletions shaders/hiz/downsample.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,4 @@ void main(){

imageStore(outBuffer, px, bounds);
}

100 changes: 100 additions & 0 deletions shaders/hiz/downsample_last.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#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;
uniform layout(binding = 2, rg32f) restrict writeonly image2D outBuffer_4;
uniform layout(binding = 3, rg32f) restrict writeonly image2D outBuffer_2;
uniform layout(binding = 4, rg32f) restrict writeonly image2D outBuffer_1;

shared vec2 ds[8 * 8];

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

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

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));

ds[gl_LocalInvocationIndex] = bounds.xy;

imageStore(outBuffer, px, bounds);
memoryBarrierShared();

if(px.x >= 4)
return;
if(px.y >= 4)
return;

a0 = ds[gl_LocalInvocationID.y * 8 * 2 + gl_LocalInvocationID.x * 2];
a1 = ds[gl_LocalInvocationID.y * 8 * 2 + gl_LocalInvocationID.x * 2 + 1];
a2 = ds[(gl_LocalInvocationID.y + 1) * 8 * 2 + gl_LocalInvocationID.x * 2];
a3 = ds[(gl_LocalInvocationID.y + 1) * 8 * 2 + gl_LocalInvocationID.x * 2 + 1];

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));

ds[gl_LocalInvocationIndex] = bounds.xy;
imageStore(outBuffer_4, ivec2(gl_WorkGroupID.xy * 0.5f + gl_LocalInvocationID.xy), bounds);

memoryBarrierShared();

if(px.x >= 2)
return;
if(px.y >= 2)
return;

a0 = ds[gl_LocalInvocationID.y * 8 * 2 + gl_LocalInvocationID.x * 2];
a1 = ds[gl_LocalInvocationID.y * 8 * 2 + gl_LocalInvocationID.x * 2 + 1];
a2 = ds[(gl_LocalInvocationID.y + 1) * 8 * 2 + gl_LocalInvocationID.x * 2];
a3 = ds[(gl_LocalInvocationID.y + 1) * 8 * 2 + gl_LocalInvocationID.x * 2 + 1];

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));

ds[gl_LocalInvocationIndex] = bounds.xy;
imageStore(outBuffer_2, ivec2(gl_WorkGroupID.xy * 0.25f + gl_LocalInvocationID.xy), bounds);
memoryBarrierShared();

if(px.x >= 1)
return;
if(px.y >= 1)
return;

a0 = ds[0];
a1 = ds[1];
a2 = ds[8 * 2];
a3 = ds[8 * 2 + 1];

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));

ds[gl_LocalInvocationIndex] = bounds.xy;
imageStore(outBuffer_1, ivec2(0), bounds);
memoryBarrierShared();
}
88 changes: 45 additions & 43 deletions shaders/splatting/bucket.glsl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//ComputeShader
#version 460

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

// Values that stay constant for the whole mesh.
layout(std140, binding = 0) uniform GlobalParams_t {
Expand All @@ -22,54 +22,41 @@ layout(std140, binding = 0) uniform GlobalParams_t {
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;
ivec4 pos;
ivec4 min_bnd;
ivec4 max_bnd;
};

layout(std430, binding = 1) readonly restrict buffer InDrawCalls_t{
layout(std430, binding = 0) 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{
layout(std430, binding = 1) 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{
layout(std430, binding = 2) 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{
layout(std430, binding = 3) restrict coherent buffer Rejects_t{
uint cnt;
uint pd0;
uint pd1;
Expand All @@ -79,27 +66,37 @@ layout(std430, binding = 6) restrict coherent buffer Rejects_t{

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);
rejects.pd1 = rejects.pd2 = 1;
out_draws.pd0 = out_draws.pd1 = out_draws.pd2 = 1;
splats.pd1 = 1;

vec3 min_bnd = in_draws.cmds[DrawID].min_bnd.xyz;
vec3 max_bnd = in_draws.cmds[DrawID].max_bnd.xyz;
vec3 bnd_diff = max_bnd - min_bnd;
float bnd_sz = min(min(bnd_diff.x, bnd_diff.y), bnd_diff.z);

vec4 offsets[8] = vec4[] (
vec4(max_bnd.x, max_bnd.y, max_bnd.z, 0),
vec4(max_bnd.x, max_bnd.y, min_bnd.z, 0),
vec4(max_bnd.x, min_bnd.y, max_bnd.z, 0),
vec4(max_bnd.x, min_bnd.y, min_bnd.z, 0),
vec4(min_bnd.x, max_bnd.y, max_bnd.z, 0),
vec4(min_bnd.x, max_bnd.y, min_bnd.z, 0),
vec4(min_bnd.x, min_bnd.y, max_bnd.z, 0),
vec4(min_bnd.x, min_bnd.y, min_bnd.z, 0)
);

vec3 UV = vec3(in_draws.cmds[DrawID].pos.x, in_draws.cmds[DrawID].pos.y, in_draws.cmds[DrawID].pos.z);
vec4 bbox;
bbox = GlobalParams.vp * (vec4(UV, 1) + offsets[0]);
bbox /= bbox.w;

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

Expand Down Expand Up @@ -137,28 +134,33 @@ void main(){
if (sampledDepth >= max_comps.z) //If the chunk is fully behind the sampled depth, don't render it
{
uint idx = atomicAdd(rejects.cnt, 1);
atomicMax(rejects.pd0, int(idx + 63) / 64);
rejects.cmds[idx].count = in_draws.cmds[DrawID].count;
rejects.cmds[idx].instanceCount = in_draws.cmds[DrawID].instanceCount;
rejects.cmds[idx].instanceCount = 1;
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)
rejects.cmds[idx].baseInstance = 0;
rejects.cmds[idx].pos = in_draws.cmds[DrawID].pos;
rejects.cmds[idx].min_bnd = in_draws.cmds[DrawID].min_bnd;
rejects.cmds[idx].max_bnd = in_draws.cmds[DrawID].max_bnd;
rejects.cmds[idx].pos = in_draws.cmds[DrawID].pos;
} else if (max_rad <= 2 * bnd_sz)
{
//Splat voxels via compute
uint idx = atomicAdd(splats.cnt, 1);
atomicMax(splats.pd0, int(in_draws.cmds[DrawID].count + 255) / 256 );
splats.cmds[idx].count = in_draws.cmds[DrawID].count;
splats.cmds[idx].instanceCount = in_draws.cmds[DrawID].instanceCount;
splats.cmds[idx].instanceCount = 1;
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];
splats.cmds[idx].baseInstance = 0;
splats.cmds[idx].pos = in_draws.cmds[DrawID].pos;
}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].instanceCount = 1;
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];
out_draws.cmds[idx].baseInstance = 0;
out_draws.cmds[idx].pos = in_draws.cmds[DrawID].pos;
}
}
Loading

0 comments on commit d557e9a

Please sign in to comment.