From 48a4ada4f9aa1f6b02e7cab1f5819eaf287dbbbd Mon Sep 17 00:00:00 2001 From: Mikulas Florek Date: Fri, 20 Oct 2023 14:41:54 +0200 Subject: [PATCH] grid from https://bgolus.medium.com/the-best-darn-grid-shader-yet-727f9278b9d8 --- data/pipelines/grid.shd | 52 +++++++++++++++++++++++++++++++++++++++++ data/pipelines/main.lua | 11 +++++++++ 2 files changed, 63 insertions(+) create mode 100644 data/pipelines/grid.shd diff --git a/data/pipelines/grid.shd b/data/pipelines/grid.shd new file mode 100644 index 0000000000..40f5ad893c --- /dev/null +++ b/data/pipelines/grid.shd @@ -0,0 +1,52 @@ +include "pipelines/common.glsl" + +------------------ + +vertex_shader [[ + layout(std140, binding = 4) uniform Model { + mat4 u_model; + }; + + out vec4 v_lpos; + + void main() { + vec3 local_pos = vec3(gl_VertexID & 1, 0, gl_VertexID >> 1) * 1000 - 500; + local_pos.y = 0; + v_lpos = vec4(local_pos, 1); + vec4 p = vec4(local_pos - Global.camera_world_pos.xyz, 1); + gl_Position = Global.projection_no_jitter * Global.view * p; + } +]] + +--------------------- + +fragment_shader [[ + layout(location = 0) out vec4 o_color; + + // https://bgolus.medium.com/the-best-darn-grid-shader-yet-727f9278b9d8 + // https://gist.github.com/bgolus/d49651f52b1dcf82f70421ba922ed064 + float PristineGrid(vec2 uv, vec2 lineWidth) { + vec4 uvDDXY = vec4(dFdx(uv), dFdy(uv)); + vec2 uvDeriv = vec2(length(uvDDXY.xz), length(uvDDXY.yw)); + bvec2 invertLine = lessThan(lineWidth, vec2(0.5)); + vec2 targetWidth = mix(1.0 - lineWidth, lineWidth, invertLine); + vec2 drawWidth = clamp(targetWidth, uvDeriv, vec2(0.5)); + vec2 lineAA = uvDeriv * 1.5; + vec2 gridUV = abs(fract(uv) * 2.0 - 1.0); + gridUV = mix(gridUV, 1.0 - gridUV, invertLine); + vec2 grid2 = smoothstep(drawWidth + lineAA, drawWidth - lineAA, gridUV); + grid2 *= saturate(targetWidth / drawWidth); + grid2 = mix(grid2, targetWidth, saturate(uvDeriv * 2.0 - 1.0)); + grid2 = mix(1.0 - grid2, grid2, invertLine); + return mix(grid2.x, 1.0, grid2.y); + } + + in vec4 v_lpos; + + void main() { + vec2 uv = v_lpos.xz / v_lpos.w; + float grid = PristineGrid(uv, vec2(0.005)); + if (grid < 0.0) discard; + o_color = vec4(vec3(0.0), grid); + } +]] \ No newline at end of file diff --git a/data/pipelines/main.lua b/data/pipelines/main.lua index b4dbd475d2..23fa170dd5 100644 --- a/data/pipelines/main.lua +++ b/data/pipelines/main.lua @@ -7,6 +7,7 @@ local cubemap_sky = require "pipelines/cubemap_sky" local film_grain = require "pipelines/film_grain" local fxaa = require "pipelines/fxaa" +local grid_shader = preloadShader("pipelines/grid.shd") local lighting_shader = preloadShader("pipelines/lighting.shd") local field_debug_shader = preloadShader("pipelines/field_debug.shd") textured_quad_shader = preloadShader("pipelines/textured_quad.shd") @@ -31,6 +32,7 @@ local taa_history = -1 local render_grass = true local render_impostors = true local render_terrain = true +local enable_grid = true type GBuffer = { A : RenderBuffer, @@ -319,6 +321,12 @@ blur = function(buffer: RenderBuffer, w : number, h : number, rb_desc : RenderBu setRenderTargets() end +local function grid() + if enable_grid then + drawArray(0, 4, grid_shader, {}, transparent_state); + end +end + local function shadowPass() : RenderBuffer if not environmentCastShadows() then local rb = createRenderbuffer(shadowmap_1x1) @@ -572,6 +580,8 @@ main = function() if SCENE_VIEW ~= nil then local icon_ds = createRenderbuffer(icon_ds_desc) pass(view_params) + setRenderTargetsDS(res, gbuffer.DS) + grid() setRenderTargetsDS(res, icon_ds) clear(CLEAR_DEPTH, 0, 0, 0, 1, 0) renderGizmos() @@ -659,6 +669,7 @@ onGUI = function() _, render_impostors = ImGui.Checkbox("Impostors", render_impostors) _, render_terrain = ImGui.Checkbox("Terrain", render_terrain) _, enable_icons = ImGui.Checkbox("Icons", enable_icons) + _, enable_grid = ImGui.Checkbox("Grid", enable_grid) local changed, upsample = ImGui.DragFloat("Downsample", getRenderToDisplayRatio()) if changed then if upsample < 1 then upsample = 1 end