From 026e855eaa880003ed8e5e264225ca5b45b2d7ae Mon Sep 17 00:00:00 2001 From: IntegratedQuantum Date: Wed, 8 Nov 2023 11:19:33 +0100 Subject: [PATCH] Merge the functionality of the bloom upscale shader into the final post processing shader. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Increases performance by ~300 µs per frame. Fixes #97 --- assets/cubyz/shaders/bloom/upscale.fs | 11 -------- assets/cubyz/shaders/bloom/upscale.vs | 10 ------- assets/cubyz/shaders/deferred_render_pass.fs | 3 ++ src/graphics.zig | 12 ++++++-- src/gui/windows/gpu_performance_measuring.zig | 2 -- src/items.zig | 4 +-- src/renderer.zig | 28 ++++++++----------- 7 files changed, 27 insertions(+), 43 deletions(-) delete mode 100644 assets/cubyz/shaders/bloom/upscale.fs delete mode 100644 assets/cubyz/shaders/bloom/upscale.vs diff --git a/assets/cubyz/shaders/bloom/upscale.fs b/assets/cubyz/shaders/bloom/upscale.fs deleted file mode 100644 index be3dea87..00000000 --- a/assets/cubyz/shaders/bloom/upscale.fs +++ /dev/null @@ -1,11 +0,0 @@ -#version 430 - -layout(location=0) out vec4 fragColor; - -in vec2 texCoords; - -layout(binding = 3) uniform sampler2D color; - -void main() { - fragColor = vec4(texture(color, texCoords).rgb, 0); -} \ No newline at end of file diff --git a/assets/cubyz/shaders/bloom/upscale.vs b/assets/cubyz/shaders/bloom/upscale.vs deleted file mode 100644 index ef5ed408..00000000 --- a/assets/cubyz/shaders/bloom/upscale.vs +++ /dev/null @@ -1,10 +0,0 @@ -#version 430 - -layout (location=0) in vec2 inTexCoords; - -out vec2 texCoords; - -void main() { - texCoords = inTexCoords; - gl_Position = vec4(inTexCoords*2 - vec2(1, 1), 0, 1); -} \ No newline at end of file diff --git a/assets/cubyz/shaders/deferred_render_pass.fs b/assets/cubyz/shaders/deferred_render_pass.fs index 9657dfc6..edd38cf5 100644 --- a/assets/cubyz/shaders/deferred_render_pass.fs +++ b/assets/cubyz/shaders/deferred_render_pass.fs @@ -10,6 +10,8 @@ uniform float zNear; uniform float zFar; uniform vec2 tanXY; +layout(binding = 5) uniform sampler2D bloomColor; + struct Fog { vec3 color; float density; @@ -51,6 +53,7 @@ vec3 applyFrontfaceFog(float fogDistance, vec3 fogColor, vec3 inColor) { void main() { fragColor = texture(color, texCoords); + fragColor += texture(bloomColor, texCoords); float densityAdjustment = sqrt(dot(tanXY*(texCoords*2 - 1), tanXY*(texCoords*2 - 1)) + 1); float fogDistance = calculateFogDistance(texelFetch(depthTexture, ivec2(gl_FragCoord.xy), 0).r, fog.density*densityAdjustment); fragColor.rgb = applyFrontfaceFog(fogDistance, fog.color, fragColor.rgb); diff --git a/src/graphics.zig b/src/graphics.zig index da60e527..096d0008 100644 --- a/src/graphics.zig +++ b/src/graphics.zig @@ -1533,7 +1533,7 @@ pub const Texture = struct { const self = Texture.init(); const image = try Image.readFromFile(main.threadAllocator, path); defer image.deinit(main.threadAllocator); - try self.generate(image); + self.generate(image); return self; } @@ -1551,7 +1551,7 @@ pub const Texture = struct { } /// (Re-)Generates the GPU buffer. - pub fn generate(self: Texture, image: Image) !void { + pub fn generate(self: Texture, image: Image) void { self.bind(); c.glTexImage2D(c.GL_TEXTURE_2D, 0, c.GL_RGBA8, image.width, image.height, 0, c.GL_RGBA, c.GL_UNSIGNED_BYTE, image.imageData.ptr); @@ -1669,6 +1669,14 @@ pub const Image = struct { .height = 2, .imageData = &defaultImageData, }; + var emptyImageData = [1]Color { + Color{.r=0, .g=0, .b=0, .a=0}, + }; + pub const emptyImage = Image { + .width = 1, + .height = 1, + .imageData = &emptyImageData, + }; width: u31, height: u31, imageData: []Color, diff --git a/src/gui/windows/gpu_performance_measuring.zig b/src/gui/windows/gpu_performance_measuring.zig index 9f0176d4..d27505e0 100644 --- a/src/gui/windows/gpu_performance_measuring.zig +++ b/src/gui/windows/gpu_performance_measuring.zig @@ -23,7 +23,6 @@ pub const Samples = enum(u8) { bloom_extract_downsample, bloom_first_pass, bloom_second_pass, - bloom_upscale, final_copy, gui, }; @@ -39,7 +38,6 @@ const names = [_][]const u8 { "Bloom - Extract color and downsample", "Bloom - First Pass", "Bloom - Second Pass", - "Bloom - Upscale", "Copy to screen", "GUI Rendering", }; diff --git a/src/items.zig b/src/items.zig index 84c45bfb..1a286843 100644 --- a/src/items.zig +++ b/src/items.zig @@ -121,7 +121,7 @@ pub const BaseItem = struct { self.texture = try graphics.generateBlockTexture(blockType); } else { self.texture = graphics.Texture.init(); - try self.texture.?.generate(self.image); + self.texture.?.generate(self.image); } } return self.texture.?; @@ -998,7 +998,7 @@ pub const Tool = struct { fn getTexture(self: *Tool) !graphics.Texture { if(self.texture == null) { self.texture = graphics.Texture.init(); - try self.texture.?.generate(self.image); + self.texture.?.generate(self.image); } return self.texture.?; } diff --git a/src/renderer.zig b/src/renderer.zig index ac14cec4..1184b28d 100644 --- a/src/renderer.zig +++ b/src/renderer.zig @@ -271,6 +271,8 @@ pub fn renderWorld(world: *World, ambientLight: Vec3f, skyColor: Vec3f, playerPo if(settings.bloom) { Bloom.render(lastWidth, lastHeight, playerBlock); + } else { + Bloom.bindReplacementImage(); } gpu_performance_measuring.startQuery(.final_copy); worldFrameBuffer.bindTexture(c.GL_TEXTURE3); @@ -314,12 +316,12 @@ pub fn renderWorld(world: *World, ambientLight: Vec3f, skyColor: Vec3f, playerPo const Bloom = struct { var buffer1: graphics.FrameBuffer = undefined; var buffer2: graphics.FrameBuffer = undefined; + var emptyBuffer: graphics.Texture = undefined; var width: u31 = std.math.maxInt(u31); var height: u31 = std.math.maxInt(u31); var firstPassShader: graphics.Shader = undefined; var secondPassShader: graphics.Shader = undefined; var colorExtractAndDownsampleShader: graphics.Shader = undefined; - var upscaleShader: graphics.Shader = undefined; var colorExtractUniforms: struct { depthTexture: c_int, zNear: c_int, @@ -332,10 +334,11 @@ const Bloom = struct { pub fn init() !void { buffer1.init(false, c.GL_LINEAR, c.GL_CLAMP_TO_EDGE); buffer2.init(false, c.GL_LINEAR, c.GL_CLAMP_TO_EDGE); + emptyBuffer = graphics.Texture.init(); + emptyBuffer.generate(graphics.Image.emptyImage); firstPassShader = try graphics.Shader.init("assets/cubyz/shaders/bloom/first_pass.vs", "assets/cubyz/shaders/bloom/first_pass.fs"); secondPassShader = try graphics.Shader.init("assets/cubyz/shaders/bloom/second_pass.vs", "assets/cubyz/shaders/bloom/second_pass.fs"); colorExtractAndDownsampleShader = try graphics.Shader.initAndGetUniforms("assets/cubyz/shaders/bloom/color_extractor_downsample.vs", "assets/cubyz/shaders/bloom/color_extractor_downsample.fs", &colorExtractUniforms); - upscaleShader = try graphics.Shader.init("assets/cubyz/shaders/bloom/upscale.vs", "assets/cubyz/shaders/bloom/upscale.fs"); } pub fn deinit() void { @@ -343,7 +346,6 @@ const Bloom = struct { buffer2.deinit(); firstPassShader.deinit(); secondPassShader.deinit(); - upscaleShader.deinit(); } fn extractImageDataAndDownsample(playerBlock: blocks.Block) void { @@ -383,15 +385,7 @@ const Bloom = struct { c.glDrawArrays(c.GL_TRIANGLE_STRIP, 0, 4); } - fn upscale() void { - upscaleShader.bind(); - buffer1.bindTexture(c.GL_TEXTURE3); - worldFrameBuffer.bind(); - c.glBindVertexArray(graphics.draw.rectVAO); - c.glDrawArrays(c.GL_TRIANGLE_STRIP, 0, 4); - } - - pub fn render(currentWidth: u31, currentHeight: u31, playerBlock: blocks.Block) void { + fn render(currentWidth: u31, currentHeight: u31, playerBlock: blocks.Block) void { if(width != currentWidth or height != currentHeight) { width = currentWidth; height = currentHeight; @@ -413,11 +407,9 @@ const Bloom = struct { gpu_performance_measuring.stopQuery(); gpu_performance_measuring.startQuery(.bloom_second_pass); secondPass(); - gpu_performance_measuring.stopQuery(); - gpu_performance_measuring.startQuery(.bloom_upscale); + c.glViewport(0, 0, width, height); - c.glBlendFunc(c.GL_ONE, c.GL_ONE); - upscale(); + buffer1.bindTexture(c.GL_TEXTURE5); c.glDepthMask(c.GL_TRUE); c.glEnable(c.GL_DEPTH_TEST); @@ -425,6 +417,10 @@ const Bloom = struct { c.glBlendFunc(c.GL_SRC_ALPHA, c.GL_ONE_MINUS_SRC_ALPHA); gpu_performance_measuring.stopQuery(); } + + fn bindReplacementImage() void { + emptyBuffer.bindTo(5); + } }; pub const MenuBackGround = struct {