From f35041749301a173ceb82ade4b4d73b5464dc5e7 Mon Sep 17 00:00:00 2001 From: Martin Gerhardy Date: Sun, 1 Dec 2024 09:55:00 +0100 Subject: [PATCH 1/2] RENDERER: added planegrid renderer https://dev.to/javiersalcedopuyo/simple-infinite-grid-shader-5fah --- src/modules/render/CMakeLists.txt | 1 + src/modules/render/GridRenderer.cpp | 38 +++++++++++---- src/modules/render/GridRenderer.h | 4 ++ src/modules/render/shaders/planeconstant.glsl | 22 +++++++++ src/modules/render/shaders/planegrid.frag | 48 +++++++++++++++++++ src/modules/render/shaders/planegrid.vert | 32 +++++++++++++ 6 files changed, 137 insertions(+), 8 deletions(-) create mode 100644 src/modules/render/shaders/planeconstant.glsl create mode 100644 src/modules/render/shaders/planegrid.frag create mode 100644 src/modules/render/shaders/planegrid.vert diff --git a/src/modules/render/CMakeLists.txt b/src/modules/render/CMakeLists.txt index 42901648c1..d1f86e2f63 100644 --- a/src/modules/render/CMakeLists.txt +++ b/src/modules/render/CMakeLists.txt @@ -10,6 +10,7 @@ set(SHADERS combine2 convolution texture + planegrid ) set(SRCS_SHADERS) foreach (SHADER ${SHADERS}) diff --git a/src/modules/render/GridRenderer.cpp b/src/modules/render/GridRenderer.cpp index 29d533b514..e50c3fba3c 100644 --- a/src/modules/render/GridRenderer.cpp +++ b/src/modules/render/GridRenderer.cpp @@ -3,6 +3,7 @@ */ #include "GridRenderer.h" +#include "PlanegridShader.h" #include "core/Color.h" #include "core/GLM.h" #include "core/GLMConst.h" @@ -11,12 +12,17 @@ #include "math/AABB.h" #include "math/Plane.h" #include "video/Camera.h" +#include "video/RendererInterface.h" #include "video/ScopedState.h" +#include "video/Shader.h" +#include "video/Types.h" +#include "video/gl/GLTypes.h" namespace render { GridRenderer::GridRenderer(bool renderAABB, bool renderGrid, bool renderPlane) - : _renderAABB(renderAABB), _renderGrid(renderGrid), _renderPlane(renderPlane) { + : _planeShader(shader::PlanegridShader::getInstance()), _renderAABB(renderAABB), _renderGrid(renderGrid), + _renderPlane(renderPlane) { } bool GridRenderer::init() { @@ -25,6 +31,13 @@ bool GridRenderer::init() { return false; } + if (!_planeShader.setup()) { + Log::error("Failed to setup color shader"); + return false; + } + core_assert_always(_uniformBlock.create(_uniformBlockData)); + core_assert_always(_planeShader.setUniformblock(_uniformBlock.getUniformblockUniformBuffer())); + return true; } @@ -189,13 +202,20 @@ void GridRenderer::renderPlane(const video::Camera &camera) { if (!_renderPlane) { return; } - if (_dirtyPlane) { - createPlane(); - _dirtyPlane = false; - } - _shapeRenderer.hide(_plane, false); - _shapeRenderer.render(_plane, camera); - _shapeRenderer.hide(_plane, true); + video::ScopedShader scopedShader(_planeShader); + _uniformBlockData.cameraPos = camera.eye(); + _uniformBlockData.proj = camera.projectionMatrix(); + _uniformBlockData.view = camera.viewMatrix(); + core_assert_always(_uniformBlock.update(_uniformBlockData)); + core_assert_always(_planeShader.setUniformblock(_uniformBlock.getUniformblockUniformBuffer())); + + video::bindVertexArray(video::InvalidId); + core_assert(video::boundVertexArray() == video::InvalidId); + video::unbindBuffer(video::BufferType::IndexBuffer); + core_assert(video::boundBuffer(video::BufferType::IndexBuffer) == video::InvalidId); + video::unbindBuffer(video::BufferType::ArrayBuffer); + core_assert(video::boundBuffer(video::BufferType::ArrayBuffer) == video::InvalidId); + video::drawArrays(video::Primitive::TriangleStrip, 4); } void GridRenderer::renderForwardArrow(const video::Camera &camera) { @@ -217,6 +237,8 @@ void GridRenderer::shutdown() { _plane = -1; _shapeRenderer.shutdown(); _shapeBuilder.shutdown(); + _planeShader.shutdown(); + _uniformBlock.shutdown(); } } // namespace render diff --git a/src/modules/render/GridRenderer.h b/src/modules/render/GridRenderer.h index 10767c41e6..1e7a2acbf8 100644 --- a/src/modules/render/GridRenderer.h +++ b/src/modules/render/GridRenderer.h @@ -4,6 +4,7 @@ #pragma once +#include "PlanegridShader.h" #include "core/Log.h" #include "render/ShapeRenderer.h" #include "video/ShapeBuilder.h" @@ -26,6 +27,9 @@ class GridRenderer { protected: video::ShapeBuilder _shapeBuilder; render::ShapeRenderer _shapeRenderer; + shader::PlanegridShader &_planeShader; + alignas(16) mutable shader::PlanegridData::UniformblockData _uniformBlockData; + mutable shader::PlanegridData _uniformBlock; math::AABB _aabb; int32_t _aabbMeshIndex = -1; diff --git a/src/modules/render/shaders/planeconstant.glsl b/src/modules/render/shaders/planeconstant.glsl new file mode 100644 index 0000000000..5a47fd23be --- /dev/null +++ b/src/modules/render/shaders/planeconstant.glsl @@ -0,0 +1,22 @@ +const float grid_size = 100.0; +const float cell_size = 1.0; +const float half_cell_size = cell_size * 0.5; +const float cell_line_thickness = 0.005; + +const float subcell_size = 0.1; +const float half_subcell_size = subcell_size * 0.5; +const float subcell_line_thickness = 0.001; + +const vec4 cell_color = vec4(0.75, 0.75, 0.75, 0.5); +const vec4 subcell_color = vec4(0.5, 0.5, 0.5, 0.5); + +const float height_to_fade_distance_ratio = 25.0; +const float min_fade_distance = grid_size * 0.05; +const float max_fade_distance = grid_size * 0.5; + +const vec4 positions[4] = vec4[4]( + vec4(-0.5, 0.0, 0.5, 1.0), + vec4( 0.5, 0.0, 0.5, 1.0), + vec4(-0.5, 0.0, -0.5, 1.0), + vec4( 0.5, 0.0, -0.5, 1.0) +); diff --git a/src/modules/render/shaders/planegrid.frag b/src/modules/render/shaders/planegrid.frag new file mode 100644 index 0000000000..0742745f45 --- /dev/null +++ b/src/modules/render/shaders/planegrid.frag @@ -0,0 +1,48 @@ +// https://dev.to/javiersalcedopuyo/simple-infinite-grid-shader-5fah + +#extension GL_ARB_shading_language_420pack : enable + +in VertexOut { + vec4 position; + vec3 camera_pos; + vec2 coords; +} v_in; + +out vec4 o_color; + +#include "planeconstant.glsl" + +// Fragment shader +void main() { + // Offset coordinates for grid alignment + vec2 cell_coords = mod(v_in.coords + half_cell_size, cell_size); + vec2 subcell_coords = mod(v_in.coords + half_subcell_size, subcell_size); + + // Distance to edges + vec2 distance_to_cell = abs(cell_coords - half_cell_size); + vec2 distance_to_subcell = abs(subcell_coords - half_subcell_size); + + // Line thickness adjustment + vec2 d = fwidth(v_in.coords); + float adjusted_cell_line_thickness = 0.5 * (cell_line_thickness + d.x); + float adjusted_subcell_line_thickness = 0.5 * (subcell_line_thickness + d.x); + + vec4 color = vec4(0.0); + if (any(lessThan(distance_to_subcell, vec2(adjusted_subcell_line_thickness)))) { + color = subcell_color; + } + if (any(lessThan(distance_to_cell, vec2(adjusted_cell_line_thickness)))) { + color = cell_color; + } + + // Fade out effect + float opacity_falloff; + { + float distance_to_camera = length(v_in.coords - v_in.camera_pos.xz); + float fade_distance = abs(v_in.camera_pos.y) * height_to_fade_distance_ratio; + fade_distance = clamp(fade_distance, min_fade_distance, max_fade_distance); + opacity_falloff = smoothstep(1.0, 0.0, distance_to_camera / fade_distance); + } + + o_color = color * opacity_falloff; +} diff --git a/src/modules/render/shaders/planegrid.vert b/src/modules/render/shaders/planegrid.vert new file mode 100644 index 0000000000..1d43dcd382 --- /dev/null +++ b/src/modules/render/shaders/planegrid.vert @@ -0,0 +1,32 @@ +// https://dev.to/javiersalcedopuyo/simple-infinite-grid-shader-5fah +#extension GL_ARB_shading_language_420pack : enable + +layout(std140, binding = 0) uniform u_uniformblock { + vec3 camera_pos; + mat4 view; + mat4 proj; +}; + +#include "planeconstant.glsl" + +// Vertex input and output +layout(location = 0) in uint a_vertex_id; + +out VertexOut { + vec4 position; + vec3 camera_pos; + vec2 coords; +} v_out; + +// Vertex shader +void main() { + vec4 world_pos = positions[a_vertex_id]; + world_pos.xyz *= grid_size; + world_pos.xz += camera_pos.xz; // Make the quad follows the camera for "infinity" + + v_out.position = proj * view * world_pos; + v_out.camera_pos = camera_pos; + v_out.coords = world_pos.xz; + + gl_Position = v_out.position; +} From ef52a93485f66a7cd864bcea66e633ab6cbdc358 Mon Sep 17 00:00:00 2001 From: Martin Gerhardy Date: Sun, 1 Dec 2024 19:26:46 +0100 Subject: [PATCH 2/2] render --- src/modules/render/GridRenderer.cpp | 17 ++++--- src/modules/render/GridRenderer.h | 4 ++ src/modules/render/shaders/planeconstant.glsl | 22 --------- src/modules/render/shaders/planegrid.frag | 47 ++++++++++++------- src/modules/render/shaders/planegrid.vert | 31 ++++++------ 5 files changed, 61 insertions(+), 60 deletions(-) delete mode 100644 src/modules/render/shaders/planeconstant.glsl diff --git a/src/modules/render/GridRenderer.cpp b/src/modules/render/GridRenderer.cpp index e50c3fba3c..d674d12c8a 100644 --- a/src/modules/render/GridRenderer.cpp +++ b/src/modules/render/GridRenderer.cpp @@ -11,7 +11,9 @@ #include "core/Trace.h" #include "math/AABB.h" #include "math/Plane.h" +#include "video/Buffer.h" #include "video/Camera.h" +#include "video/Renderer.h" #include "video/RendererInterface.h" #include "video/ScopedState.h" #include "video/Shader.h" @@ -37,6 +39,7 @@ bool GridRenderer::init() { } core_assert_always(_uniformBlock.create(_uniformBlockData)); core_assert_always(_planeShader.setUniformblock(_uniformBlock.getUniformblockUniformBuffer())); + _planeVAO = video::genVertexArray(); return true; } @@ -202,20 +205,21 @@ void GridRenderer::renderPlane(const video::Camera &camera) { if (!_renderPlane) { return; } + + video::ScopedState facecull(video::State::CullFace, false); + video::ScopedState depthdepth(video::State::DepthTest, true); video::ScopedShader scopedShader(_planeShader); + video::bindVertexArray(_planeVAO); + _uniformBlockData.cameraPos = camera.eye(); _uniformBlockData.proj = camera.projectionMatrix(); _uniformBlockData.view = camera.viewMatrix(); + // video::bindBuffer(video::BufferType::UniformBuffer, _uniformBlock.getUniformblockUniformBuffer().handle()); core_assert_always(_uniformBlock.update(_uniformBlockData)); core_assert_always(_planeShader.setUniformblock(_uniformBlock.getUniformblockUniformBuffer())); - video::bindVertexArray(video::InvalidId); - core_assert(video::boundVertexArray() == video::InvalidId); - video::unbindBuffer(video::BufferType::IndexBuffer); - core_assert(video::boundBuffer(video::BufferType::IndexBuffer) == video::InvalidId); - video::unbindBuffer(video::BufferType::ArrayBuffer); - core_assert(video::boundBuffer(video::BufferType::ArrayBuffer) == video::InvalidId); video::drawArrays(video::Primitive::TriangleStrip, 4); + video::bindVertexArray(video::InvalidId); } void GridRenderer::renderForwardArrow(const video::Camera &camera) { @@ -239,6 +243,7 @@ void GridRenderer::shutdown() { _shapeBuilder.shutdown(); _planeShader.shutdown(); _uniformBlock.shutdown(); + video::deleteVertexArray(_planeVAO); } } // namespace render diff --git a/src/modules/render/GridRenderer.h b/src/modules/render/GridRenderer.h index 1e7a2acbf8..a99956d5cd 100644 --- a/src/modules/render/GridRenderer.h +++ b/src/modules/render/GridRenderer.h @@ -9,6 +9,7 @@ #include "render/ShapeRenderer.h" #include "video/ShapeBuilder.h" #include "math/AABB.h" +#include "video/gl/GLTypes.h" namespace video { class Video; @@ -27,9 +28,12 @@ class GridRenderer { protected: video::ShapeBuilder _shapeBuilder; render::ShapeRenderer _shapeRenderer; + shader::PlanegridShader &_planeShader; alignas(16) mutable shader::PlanegridData::UniformblockData _uniformBlockData; mutable shader::PlanegridData _uniformBlock; + video::Id _planeVAO = video::InvalidId; + math::AABB _aabb; int32_t _aabbMeshIndex = -1; diff --git a/src/modules/render/shaders/planeconstant.glsl b/src/modules/render/shaders/planeconstant.glsl deleted file mode 100644 index 5a47fd23be..0000000000 --- a/src/modules/render/shaders/planeconstant.glsl +++ /dev/null @@ -1,22 +0,0 @@ -const float grid_size = 100.0; -const float cell_size = 1.0; -const float half_cell_size = cell_size * 0.5; -const float cell_line_thickness = 0.005; - -const float subcell_size = 0.1; -const float half_subcell_size = subcell_size * 0.5; -const float subcell_line_thickness = 0.001; - -const vec4 cell_color = vec4(0.75, 0.75, 0.75, 0.5); -const vec4 subcell_color = vec4(0.5, 0.5, 0.5, 0.5); - -const float height_to_fade_distance_ratio = 25.0; -const float min_fade_distance = grid_size * 0.05; -const float max_fade_distance = grid_size * 0.5; - -const vec4 positions[4] = vec4[4]( - vec4(-0.5, 0.0, 0.5, 1.0), - vec4( 0.5, 0.0, 0.5, 1.0), - vec4(-0.5, 0.0, -0.5, 1.0), - vec4( 0.5, 0.0, -0.5, 1.0) -); diff --git a/src/modules/render/shaders/planegrid.frag b/src/modules/render/shaders/planegrid.frag index 0742745f45..bd22d6596e 100644 --- a/src/modules/render/shaders/planegrid.frag +++ b/src/modules/render/shaders/planegrid.frag @@ -1,29 +1,39 @@ // https://dev.to/javiersalcedopuyo/simple-infinite-grid-shader-5fah -#extension GL_ARB_shading_language_420pack : enable - -in VertexOut { - vec4 position; - vec3 camera_pos; - vec2 coords; -} v_in; +$in vec4 v_position; +flat $in vec3 v_camera_pos; +$in vec2 v_coords; out vec4 o_color; -#include "planeconstant.glsl" +const float grid_size = 100.0; +const float cell_size = 1.0; +const float half_cell_size = cell_size * 0.5; +const float cell_line_thickness = 0.005; + +const float subcell_size = 0.1; +const float half_subcell_size = subcell_size * 0.5; +const float subcell_line_thickness = 0.001; + +const vec4 cell_color = vec4(0.5, 0.5, 0.5, 1.0); +const vec4 subcell_color = vec4(0.75, 0.75, 0.75, 1.0); + +const float height_to_fade_distance_ratio = 25.0; +const float min_fade_distance = grid_size * 0.05; +const float max_fade_distance = grid_size * 0.5; // Fragment shader void main() { // Offset coordinates for grid alignment - vec2 cell_coords = mod(v_in.coords + half_cell_size, cell_size); - vec2 subcell_coords = mod(v_in.coords + half_subcell_size, subcell_size); + vec2 cell_coords = mod(v_coords + half_cell_size, cell_size); + vec2 subcell_coords = mod(v_coords + half_subcell_size, subcell_size); // Distance to edges vec2 distance_to_cell = abs(cell_coords - half_cell_size); vec2 distance_to_subcell = abs(subcell_coords - half_subcell_size); // Line thickness adjustment - vec2 d = fwidth(v_in.coords); + vec2 d = fwidth(v_coords); float adjusted_cell_line_thickness = 0.5 * (cell_line_thickness + d.x); float adjusted_subcell_line_thickness = 0.5 * (subcell_line_thickness + d.x); @@ -35,14 +45,19 @@ void main() { color = cell_color; } - // Fade out effect + // Fade out around the camera to hide visual artifacts float opacity_falloff; { - float distance_to_camera = length(v_in.coords - v_in.camera_pos.xz); - float fade_distance = abs(v_in.camera_pos.y) * height_to_fade_distance_ratio; - fade_distance = clamp(fade_distance, min_fade_distance, max_fade_distance); + float distance_to_camera = length(v_coords - v_camera_pos.xz); + // Adjust the fade distance relative to the camera height + float fade_distance = abs(v_camera_pos.y) * height_to_fade_distance_ratio; + { + fade_distance = max(fade_distance, min_fade_distance); + fade_distance = min(fade_distance, max_fade_distance); + } opacity_falloff = smoothstep(1.0, 0.0, distance_to_camera / fade_distance); } - o_color = color * opacity_falloff; + color.a *= opacity_falloff; + o_color = color; } diff --git a/src/modules/render/shaders/planegrid.vert b/src/modules/render/shaders/planegrid.vert index 1d43dcd382..6fa5f68416 100644 --- a/src/modules/render/shaders/planegrid.vert +++ b/src/modules/render/shaders/planegrid.vert @@ -1,32 +1,31 @@ // https://dev.to/javiersalcedopuyo/simple-infinite-grid-shader-5fah -#extension GL_ARB_shading_language_420pack : enable -layout(std140, binding = 0) uniform u_uniformblock { +layout(std140) uniform u_uniformblock { vec3 camera_pos; mat4 view; mat4 proj; }; -#include "planeconstant.glsl" +const vec4 positions[4] = vec4[4]( + vec4(-0.5, 0.0, 0.5, 1.0), + vec4( 0.5, 0.0, 0.5, 1.0), + vec4(-0.5, 0.0, -0.5, 1.0), + vec4( 0.5, 0.0, -0.5, 1.0) +); -// Vertex input and output -layout(location = 0) in uint a_vertex_id; - -out VertexOut { - vec4 position; - vec3 camera_pos; - vec2 coords; -} v_out; +$out vec4 v_position; +flat $out vec3 v_camera_pos; +$out vec2 v_coords; // Vertex shader void main() { - vec4 world_pos = positions[a_vertex_id]; + vec4 world_pos = positions[gl_VertexID]; world_pos.xyz *= grid_size; world_pos.xz += camera_pos.xz; // Make the quad follows the camera for "infinity" - v_out.position = proj * view * world_pos; - v_out.camera_pos = camera_pos; - v_out.coords = world_pos.xz; + v_position = proj * view * world_pos; + v_camera_pos = camera_pos; + v_coords = world_pos.xz; - gl_Position = v_out.position; + gl_Position = v_position; }