Merge the functionality of the bloom upscale shader into the final post processing shader.

Increases performance by ~300 µs per frame.
Fixes #97
This commit is contained in:
IntegratedQuantum 2023-11-08 11:19:33 +01:00
parent 0152b1363a
commit 026e855eaa
7 changed files with 27 additions and 43 deletions

View File

@ -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);
}

View File

@ -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);
}

View File

@ -10,6 +10,8 @@ uniform float zNear;
uniform float zFar; uniform float zFar;
uniform vec2 tanXY; uniform vec2 tanXY;
layout(binding = 5) uniform sampler2D bloomColor;
struct Fog { struct Fog {
vec3 color; vec3 color;
float density; float density;
@ -51,6 +53,7 @@ vec3 applyFrontfaceFog(float fogDistance, vec3 fogColor, vec3 inColor) {
void main() { void main() {
fragColor = texture(color, texCoords); fragColor = texture(color, texCoords);
fragColor += texture(bloomColor, texCoords);
float densityAdjustment = sqrt(dot(tanXY*(texCoords*2 - 1), tanXY*(texCoords*2 - 1)) + 1); 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); float fogDistance = calculateFogDistance(texelFetch(depthTexture, ivec2(gl_FragCoord.xy), 0).r, fog.density*densityAdjustment);
fragColor.rgb = applyFrontfaceFog(fogDistance, fog.color, fragColor.rgb); fragColor.rgb = applyFrontfaceFog(fogDistance, fog.color, fragColor.rgb);

View File

@ -1533,7 +1533,7 @@ pub const Texture = struct {
const self = Texture.init(); const self = Texture.init();
const image = try Image.readFromFile(main.threadAllocator, path); const image = try Image.readFromFile(main.threadAllocator, path);
defer image.deinit(main.threadAllocator); defer image.deinit(main.threadAllocator);
try self.generate(image); self.generate(image);
return self; return self;
} }
@ -1551,7 +1551,7 @@ pub const Texture = struct {
} }
/// (Re-)Generates the GPU buffer. /// (Re-)Generates the GPU buffer.
pub fn generate(self: Texture, image: Image) !void { pub fn generate(self: Texture, image: Image) void {
self.bind(); 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); 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, .height = 2,
.imageData = &defaultImageData, .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, width: u31,
height: u31, height: u31,
imageData: []Color, imageData: []Color,

View File

@ -23,7 +23,6 @@ pub const Samples = enum(u8) {
bloom_extract_downsample, bloom_extract_downsample,
bloom_first_pass, bloom_first_pass,
bloom_second_pass, bloom_second_pass,
bloom_upscale,
final_copy, final_copy,
gui, gui,
}; };
@ -39,7 +38,6 @@ const names = [_][]const u8 {
"Bloom - Extract color and downsample", "Bloom - Extract color and downsample",
"Bloom - First Pass", "Bloom - First Pass",
"Bloom - Second Pass", "Bloom - Second Pass",
"Bloom - Upscale",
"Copy to screen", "Copy to screen",
"GUI Rendering", "GUI Rendering",
}; };

View File

@ -121,7 +121,7 @@ pub const BaseItem = struct {
self.texture = try graphics.generateBlockTexture(blockType); self.texture = try graphics.generateBlockTexture(blockType);
} else { } else {
self.texture = graphics.Texture.init(); self.texture = graphics.Texture.init();
try self.texture.?.generate(self.image); self.texture.?.generate(self.image);
} }
} }
return self.texture.?; return self.texture.?;
@ -998,7 +998,7 @@ pub const Tool = struct {
fn getTexture(self: *Tool) !graphics.Texture { fn getTexture(self: *Tool) !graphics.Texture {
if(self.texture == null) { if(self.texture == null) {
self.texture = graphics.Texture.init(); self.texture = graphics.Texture.init();
try self.texture.?.generate(self.image); self.texture.?.generate(self.image);
} }
return self.texture.?; return self.texture.?;
} }

View File

@ -271,6 +271,8 @@ pub fn renderWorld(world: *World, ambientLight: Vec3f, skyColor: Vec3f, playerPo
if(settings.bloom) { if(settings.bloom) {
Bloom.render(lastWidth, lastHeight, playerBlock); Bloom.render(lastWidth, lastHeight, playerBlock);
} else {
Bloom.bindReplacementImage();
} }
gpu_performance_measuring.startQuery(.final_copy); gpu_performance_measuring.startQuery(.final_copy);
worldFrameBuffer.bindTexture(c.GL_TEXTURE3); worldFrameBuffer.bindTexture(c.GL_TEXTURE3);
@ -314,12 +316,12 @@ pub fn renderWorld(world: *World, ambientLight: Vec3f, skyColor: Vec3f, playerPo
const Bloom = struct { const Bloom = struct {
var buffer1: graphics.FrameBuffer = undefined; var buffer1: graphics.FrameBuffer = undefined;
var buffer2: graphics.FrameBuffer = undefined; var buffer2: graphics.FrameBuffer = undefined;
var emptyBuffer: graphics.Texture = undefined;
var width: u31 = std.math.maxInt(u31); var width: u31 = std.math.maxInt(u31);
var height: u31 = std.math.maxInt(u31); var height: u31 = std.math.maxInt(u31);
var firstPassShader: graphics.Shader = undefined; var firstPassShader: graphics.Shader = undefined;
var secondPassShader: graphics.Shader = undefined; var secondPassShader: graphics.Shader = undefined;
var colorExtractAndDownsampleShader: graphics.Shader = undefined; var colorExtractAndDownsampleShader: graphics.Shader = undefined;
var upscaleShader: graphics.Shader = undefined;
var colorExtractUniforms: struct { var colorExtractUniforms: struct {
depthTexture: c_int, depthTexture: c_int,
zNear: c_int, zNear: c_int,
@ -332,10 +334,11 @@ const Bloom = struct {
pub fn init() !void { pub fn init() !void {
buffer1.init(false, c.GL_LINEAR, c.GL_CLAMP_TO_EDGE); buffer1.init(false, c.GL_LINEAR, c.GL_CLAMP_TO_EDGE);
buffer2.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"); 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"); 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); 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 { pub fn deinit() void {
@ -343,7 +346,6 @@ const Bloom = struct {
buffer2.deinit(); buffer2.deinit();
firstPassShader.deinit(); firstPassShader.deinit();
secondPassShader.deinit(); secondPassShader.deinit();
upscaleShader.deinit();
} }
fn extractImageDataAndDownsample(playerBlock: blocks.Block) void { fn extractImageDataAndDownsample(playerBlock: blocks.Block) void {
@ -383,15 +385,7 @@ const Bloom = struct {
c.glDrawArrays(c.GL_TRIANGLE_STRIP, 0, 4); c.glDrawArrays(c.GL_TRIANGLE_STRIP, 0, 4);
} }
fn upscale() void { fn render(currentWidth: u31, currentHeight: u31, playerBlock: blocks.Block) 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 {
if(width != currentWidth or height != currentHeight) { if(width != currentWidth or height != currentHeight) {
width = currentWidth; width = currentWidth;
height = currentHeight; height = currentHeight;
@ -413,11 +407,9 @@ const Bloom = struct {
gpu_performance_measuring.stopQuery(); gpu_performance_measuring.stopQuery();
gpu_performance_measuring.startQuery(.bloom_second_pass); gpu_performance_measuring.startQuery(.bloom_second_pass);
secondPass(); secondPass();
gpu_performance_measuring.stopQuery();
gpu_performance_measuring.startQuery(.bloom_upscale);
c.glViewport(0, 0, width, height); c.glViewport(0, 0, width, height);
c.glBlendFunc(c.GL_ONE, c.GL_ONE); buffer1.bindTexture(c.GL_TEXTURE5);
upscale();
c.glDepthMask(c.GL_TRUE); c.glDepthMask(c.GL_TRUE);
c.glEnable(c.GL_DEPTH_TEST); 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); c.glBlendFunc(c.GL_SRC_ALPHA, c.GL_ONE_MINUS_SRC_ALPHA);
gpu_performance_measuring.stopQuery(); gpu_performance_measuring.stopQuery();
} }
fn bindReplacementImage() void {
emptyBuffer.bindTo(5);
}
}; };
pub const MenuBackGround = struct { pub const MenuBackGround = struct {