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 <util/Timer.hpp>
#include <util/geo.hpp>
#include <Renderer/Pipeline.hpp>
#include <Renderer/Shader.hpp>
@ -18,6 +19,8 @@
#include <UI/UI.hpp>
using namespace std::string_literals;
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);
uniform_buffer->upload(UniformData {
auto uni = UniformData{
.view = cam.view(),
.proj = p,
.time = time,
@ -346,7 +349,11 @@ void Renderer::draw() {
.viewport = glm::vec2(viewport.width, viewport.y),
.tess_factor = tess_factor,
.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->command_buffer.setViewport(0, viewport);

View File

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

View File

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

View File

@ -10,6 +10,7 @@ layout (set = 0, binding = 0) uniform Matrices {
mat4 proj;
float time;
vec3 cam_pos;
vec4 frustum[6];
vec2 viewport;
float tess_factor;
float tess_edge_size;
@ -23,5 +24,5 @@ void main() {
float r = length(light_pos-pos);
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;
float time;
vec3 cam_pos;
vec4 frustum[6];
vec2 viewport;
float tess_factor;
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);
}
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() {
if(gl_InvocationID == 0) {
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[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_TessLevelInner[0] = mix(gl_TessLevelOuter[0], gl_TessLevelOuter[3], 0.5);
gl_TessLevelInner[1] = mix(gl_TessLevelOuter[2], gl_TessLevelOuter[1], 0.5);
/*gl_TessLevelOuter[0] = tess_factor;
gl_TessLevelOuter[1] = tess_factor;
gl_TessLevelOuter[2] = tess_factor;
gl_TessLevelOuter[3] = tess_factor;
gl_TessLevelInner[0] = mix(gl_TessLevelOuter[0], gl_TessLevelOuter[3], 0.5);
gl_TessLevelInner[1] = mix(gl_TessLevelOuter[2], gl_TessLevelOuter[1], 0.5);*/
/* perform frustum culling */
if(frustum_culling()) {
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[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_TessLevelInner[0] = mix(gl_TessLevelOuter[0], gl_TessLevelOuter[3], 0.5);
gl_TessLevelInner[1] = mix(gl_TessLevelOuter[2], gl_TessLevelOuter[1], 0.5);
} else {
gl_TessLevelOuter[0] = 0.0;
gl_TessLevelOuter[1] = 0.0;
gl_TessLevelOuter[2] = 0.0;
gl_TessLevelOuter[3] = 0.0;
gl_TessLevelInner[0] = 0.0;
gl_TessLevelInner[1] = 0.0;
}
}
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;
float time;
vec3 cam_pos;
vec4 frustum[6];
vec2 viewport;
float tess_factor;
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 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;
gl_Position = proj * view * fpos;

Binary file not shown.

View File

@ -12,6 +12,7 @@ layout (set = 0, binding = 0) uniform Matrices {
mat4 proj;
float time;
vec3 cam_pos;
vec4 frustum[6];
vec2 viewport;
float tess_factor;
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;
}