Introduced frustum culling, learned how to correctly spell frustum

This commit is contained in:
connellpaxton 2024-02-06 08:26:24 -05:00
parent 7fd68abcf9
commit eeb923067f
12 changed files with 64 additions and 18 deletions

View File

@ -8,6 +8,7 @@
#include <Memory/Memory.hpp> #include <Memory/Memory.hpp>
#include <util/Timer.hpp> #include <util/Timer.hpp>
#include <util/geo.hpp>
#include <Renderer/Pipeline.hpp> #include <Renderer/Pipeline.hpp>
#include <Renderer/Shader.hpp> #include <Renderer/Shader.hpp>
@ -18,6 +19,8 @@
#include <UI/UI.hpp> #include <UI/UI.hpp>
using namespace std::string_literals; using namespace std::string_literals;
Renderer::Renderer(Window& win) : win(win) { Renderer::Renderer(Window& win) : win(win) {
@ -338,7 +341,7 @@ void Renderer::draw() {
const auto p = glm::perspective(glm::radians(90.0f), static_cast<float>(sz.width) / static_cast<float>(sz.height), 0.01f, 2000.0f); const auto p = glm::perspective(glm::radians(90.0f), static_cast<float>(sz.width) / static_cast<float>(sz.height), 0.01f, 2000.0f);
uniform_buffer->upload(UniformData { auto uni = UniformData{
.view = cam.view(), .view = cam.view(),
.proj = p, .proj = p,
.time = time, .time = time,
@ -346,7 +349,11 @@ void Renderer::draw() {
.viewport = glm::vec2(viewport.width, viewport.y), .viewport = glm::vec2(viewport.width, viewport.y),
.tess_factor = tess_factor, .tess_factor = tess_factor,
.tess_edge_size = tess_edge_size, .tess_edge_size = tess_edge_size,
}); };
std::memcpy(uni.frustum, frustum(p * uni.view).data(), sizeof(uni.frustum));
uniform_buffer->upload(uni);
command_buffer->bind(*terrain_pipeline); command_buffer->bind(*terrain_pipeline);
command_buffer->command_buffer.setViewport(0, viewport); command_buffer->command_buffer.setViewport(0, viewport);

View File

@ -18,6 +18,7 @@ struct UniformData {
float pad2; float pad2;
glm::vec3 cam_pos; glm::vec3 cam_pos;
float pad3; float pad3;
glm::vec4 frustum[6];
glm::vec2 viewport; glm::vec2 viewport;
float tess_factor; float tess_factor;
float tess_edge_size; float tess_edge_size;

View File

@ -27,7 +27,7 @@ struct Texture {
.binding = binding, .binding = binding,
.descriptorType = vk::DescriptorType::eCombinedImageSampler, .descriptorType = vk::DescriptorType::eCombinedImageSampler,
.descriptorCount = 1, .descriptorCount = 1,
.stageFlags = vk::ShaderStageFlagBits::eFragment | vk::ShaderStageFlagBits::eTessellationEvaluation, .stageFlags = vk::ShaderStageFlagBits::eFragment | vk::ShaderStageFlagBits::eTessellationControl | vk::ShaderStageFlagBits::eTessellationEvaluation,
.pImmutableSamplers = nullptr, .pImmutableSamplers = nullptr,
}; };
} }

View File

@ -10,6 +10,7 @@ layout (set = 0, binding = 0) uniform Matrices {
mat4 proj; mat4 proj;
float time; float time;
vec3 cam_pos; vec3 cam_pos;
vec4 frustum[6];
vec2 viewport; vec2 viewport;
float tess_factor; float tess_factor;
float tess_edge_size; float tess_edge_size;
@ -23,5 +24,5 @@ void main() {
float r = length(light_pos-pos); float r = length(light_pos-pos);
float t = clamp(dot(L, norm), 0.0, 1.0) * 20.0/(r*r); float t = clamp(dot(L, norm), 0.0, 1.0) * 20.0/(r*r);
FragColor = vec4(norm * texture(tex, texCoord).xyz + t, 1.0); FragColor = vec4(1.0);
} }

Binary file not shown.

View File

@ -6,6 +6,7 @@ layout (set = 0, binding = 0) uniform Matrices {
mat4 proj; mat4 proj;
float time; float time;
vec3 cam_pos; vec3 cam_pos;
vec4 frustum[6];
vec2 viewport; vec2 viewport;
float tess_factor; float tess_factor;
float tess_edge_size; float tess_edge_size;
@ -45,22 +46,39 @@ float screen_space_tess(vec4 p0, vec4 p1) {
return clamp(distance(clip0, clip1) / tess_edge_size * tess_factor, 1.0, 64.0); return clamp(distance(clip0, clip1) / tess_edge_size * tess_factor, 1.0, 64.0);
} }
bool frustum_culling() {
/* square root of patch size */
const float r = 8.0f;
/* ensure this is consistent with tese shader */
vec4 fpos = gl_in[gl_InvocationID].gl_Position;
fpos.y += 15.0 * textureLod(heightmap, texCoord[0], 0.0).r;
for(int i = 0; i < 6; i++) {
if(dot(fpos, frustum[i]) + r < 0.0)
return false;
}
return true;
}
void main() { void main() {
if(gl_InvocationID == 0) { if(gl_InvocationID == 0) {
/* perform frustum culling */
if(frustum_culling()) {
gl_TessLevelOuter[0] = screen_space_tess(gl_in[3].gl_Position, gl_in[0].gl_Position); gl_TessLevelOuter[0] = screen_space_tess(gl_in[3].gl_Position, gl_in[0].gl_Position);
gl_TessLevelOuter[1] = screen_space_tess(gl_in[0].gl_Position, gl_in[1].gl_Position); gl_TessLevelOuter[1] = screen_space_tess(gl_in[0].gl_Position, gl_in[1].gl_Position);
gl_TessLevelOuter[2] = screen_space_tess(gl_in[1].gl_Position, gl_in[2].gl_Position); gl_TessLevelOuter[2] = screen_space_tess(gl_in[1].gl_Position, gl_in[2].gl_Position);
gl_TessLevelOuter[3] = screen_space_tess(gl_in[2].gl_Position, gl_in[3].gl_Position); gl_TessLevelOuter[3] = screen_space_tess(gl_in[2].gl_Position, gl_in[3].gl_Position);
gl_TessLevelInner[0] = mix(gl_TessLevelOuter[0], gl_TessLevelOuter[3], 0.5); gl_TessLevelInner[0] = mix(gl_TessLevelOuter[0], gl_TessLevelOuter[3], 0.5);
gl_TessLevelInner[1] = mix(gl_TessLevelOuter[2], gl_TessLevelOuter[1], 0.5); gl_TessLevelInner[1] = mix(gl_TessLevelOuter[2], gl_TessLevelOuter[1], 0.5);
} else {
/*gl_TessLevelOuter[0] = tess_factor; gl_TessLevelOuter[0] = 0.0;
gl_TessLevelOuter[1] = tess_factor; gl_TessLevelOuter[1] = 0.0;
gl_TessLevelOuter[2] = tess_factor; gl_TessLevelOuter[2] = 0.0;
gl_TessLevelOuter[3] = tess_factor; gl_TessLevelOuter[3] = 0.0;
gl_TessLevelInner[0] = mix(gl_TessLevelOuter[0], gl_TessLevelOuter[3], 0.5); gl_TessLevelInner[0] = 0.0;
gl_TessLevelInner[1] = mix(gl_TessLevelOuter[2], gl_TessLevelOuter[1], 0.5);*/ gl_TessLevelInner[1] = 0.0;
}
} }
gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position; gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;

Binary file not shown.

View File

@ -5,6 +5,7 @@ layout (set = 0, binding = 0) uniform Matrices {
mat4 proj; mat4 proj;
float time; float time;
vec3 cam_pos; vec3 cam_pos;
vec4 frustum[6];
vec2 viewport; vec2 viewport;
float tess_factor; float tess_factor;
float tess_edge_size; float tess_edge_size;
@ -40,7 +41,7 @@ void main() {
vec4 pos2 = mix(gl_in[3].gl_Position, gl_in[2].gl_Position, gl_TessCoord.x); vec4 pos2 = mix(gl_in[3].gl_Position, gl_in[2].gl_Position, gl_TessCoord.x);
vec4 fpos = mix(pos1, pos2, gl_TessCoord.y); vec4 fpos = mix(pos1, pos2, gl_TessCoord.y);
fpos.y += 15.0 * texture(heightmap, _texCoord).r; //+ cos(fpos.x*fpos.y); fpos.y += 15.0 * texture(heightmap, _texCoord).r;
_pos = fpos.xyz; _pos = fpos.xyz;
gl_Position = proj * view * fpos; gl_Position = proj * view * fpos;

Binary file not shown.

View File

@ -12,6 +12,7 @@ layout (set = 0, binding = 0) uniform Matrices {
mat4 proj; mat4 proj;
float time; float time;
vec3 cam_pos; vec3 cam_pos;
vec4 frustum[6];
vec2 viewport; vec2 viewport;
float tess_factor; float tess_factor;
float tess_edge_size; float tess_edge_size;

Binary file not shown.

17
util/geo.hpp Normal file
View File

@ -0,0 +1,17 @@
#pragma once
#include <glm/glm.hpp>
#include <array>
/* extracts frustum from projection matrix */
static std::array<glm::vec4, 6> frustum(const glm::mat4& mat) {
/* Left, Right, Top, Bottom, Back, Front */
std::array<glm::vec4, 6> ret;
for (size_t i = 0; i < 3; i++)
for (size_t j = 0; j < 4; j++)
ret[i * 2][j] = mat[j].w + mat[j][i],
ret[i * 2 + 1][j] = mat[j].w - mat[j][i];
return ret;
}