Skip to content

Commit

Permalink
Fog with ARB_fragment_shader_interlock: quick and dirty prototype
Browse files Browse the repository at this point in the history
a prototype of #817
  • Loading branch information
IntegratedQuantum committed Dec 6, 2024
1 parent c495e84 commit b856815
Show file tree
Hide file tree
Showing 7 changed files with 81 additions and 13 deletions.
4 changes: 2 additions & 2 deletions assets/cubyz/shaders/bloom/color_extractor_downsample.fs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ float calculateFogDistance(float depthBufferValue, float fogDensity) {
}

vec3 applyFrontfaceFog(float fogDistance, vec3 fogColor, vec3 inColor) {
float fogFactor = exp(fogDistance);
float fogFactor = exp(-fogDistance);
inColor *= fogFactor;
inColor += fogColor;
inColor -= fogColor*fogFactor;
Expand All @@ -54,7 +54,7 @@ vec3 applyFrontfaceFog(float fogDistance, vec3 fogColor, vec3 inColor) {
vec3 fetch(ivec2 pos) {
vec4 rgba = texelFetch(color, pos, 0);
float densityAdjustment = sqrt(dot(tanXY*(normalizedTexCoords*2 - 1), tanXY*(normalizedTexCoords*2 - 1)) + 1);
float fogDistance = calculateFogDistance(texelFetch(depthTexture, pos, 0).r, fog.density*densityAdjustment);
float fogDistance = texelFetch(depthTexture, pos, 0).r*fog.density*densityAdjustment;
vec3 fogColor = fog.color;
rgba.rgb = applyFrontfaceFog(fogDistance, fog.color, rgba.rgb);
return rgba.rgb/rgba.a;
Expand Down
22 changes: 15 additions & 7 deletions assets/cubyz/shaders/chunks/transparent_fragment.fs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#version 430

#extension GL_ARB_fragment_shader_interlock : require
layout(sample_interlock_ordered) in;
layout(early_fragment_tests) in;

in vec3 mvVertexPos;
in vec3 direction;
in vec3 light;
Expand All @@ -16,7 +20,7 @@ uniform samplerCube reflectionMap;
uniform float reflectionMapSize;
uniform float contrast;

layout(binding = 5) uniform sampler2D depthTexture;
layout(binding = 5, r16f) coherent uniform image2D depthTexture;

layout (location = 0, index = 0) out vec4 fragColor;
layout (location = 0, index = 1) out vec4 blendColor;
Expand Down Expand Up @@ -91,9 +95,9 @@ void applyFrontfaceFog(float fogDistance, vec3 fogColor) {
}

void applyBackfaceFog(float fogDistance, vec3 fogColor) {
float fogFactor = exp(-fogDistance);
fragColor.rgb = fragColor.rgb*fogFactor + fogColor*(1 - fogFactor);
fragColor.a *= fogFactor;
//float fogFactor = exp(-fogDistance);
//fragColor.rgb = fragColor.rgb*fogFactor + fogColor*(1 - fogFactor);
//fragColor.a *= fogFactor;
}

vec4 fixedCubeMapLookup(vec3 v) { // Taken from http://the-witness.net/news/2012/02/seamless-cube-map-filtering/
Expand All @@ -106,13 +110,17 @@ vec4 fixedCubeMapLookup(vec3 v) { // Taken from http://the-witness.net/news/2012
}

void main() {
beginInvocationInterlockARB();
float prevDepth = imageLoad(depthTexture, ivec2(gl_FragCoord.xy)).r;
imageStore(depthTexture, ivec2(gl_FragCoord.xy), vec4(abs(mvVertexPos.y), 0, 0, 0));
endInvocationInterlockARB();
float animatedTextureIndex = animatedTexture[textureIndex];
vec3 textureCoords = vec3(uv, animatedTextureIndex);
float normalVariation = lightVariation(normal);
float densityAdjustment = sqrt(dot(mvVertexPos, mvVertexPos))/abs(mvVertexPos.y);
float dist = zFromDepth(texelFetch(depthTexture, ivec2(gl_FragCoord.xy), 0).r);
float fogDistance = calculateFogDistance(dist, fogData[int(animatedTextureIndex)].fogDensity*densityAdjustment);
float airFogDistance = calculateFogDistance(dist, fog.density*densityAdjustment);
float dist = abs(mvVertexPos.y) - prevDepth;//zFromDepth(texelFetch(depthTexture1, ivec2(gl_FragCoord.xy), 0).r);
float fogDistance = dist*fogData[int(animatedTextureIndex)].fogDensity*densityAdjustment;
float airFogDistance = dist*fog.density*densityAdjustment;
vec3 fogColor = unpackColor(fogData[int(animatedTextureIndex)].fogColor);
vec3 pixelLight = max(light*normalVariation, texture(emissionSampler, textureCoords).r*4);
vec4 textureColor = texture(texture_sampler, textureCoords)*vec4(pixelLight, 1);
Expand Down
4 changes: 2 additions & 2 deletions assets/cubyz/shaders/deferred_render_pass.fs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ float calculateFogDistance(float depthBufferValue, float fogDensity) {
}

vec3 applyFrontfaceFog(float fogDistance, vec3 fogColor, vec3 inColor) {
float fogFactor = exp(fogDistance);
float fogFactor = exp(-fogDistance);
inColor *= fogFactor;
inColor += fogColor;
inColor -= fogColor*fogFactor;
Expand All @@ -54,7 +54,7 @@ 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(texture(depthTexture, texCoords).r, fog.density*densityAdjustment);
float fogDistance = texture(depthTexture, texCoords).r*fog.density*densityAdjustment;
fragColor.rgb = applyFrontfaceFog(fogDistance, fog.color, fragColor.rgb);
float maxColor = max(1.0, max(fragColor.r, max(fragColor.g, fragColor.b)));
fragColor.rgb = fragColor.rgb/maxColor;
Expand Down
16 changes: 16 additions & 0 deletions assets/cubyz/shaders/depth_copy.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#version 430
out vec4 fragColor;
in vec2 texCoords;

uniform float zNear;
uniform float zFar;

layout(binding = 5) uniform sampler2D depthBuffer;

float zFromDepth(float depthBufferValue) {
return zNear*zFar/(depthBufferValue*(zNear - zFar) + zFar);
}

void main() {
fragColor.r = zFromDepth(texture(depthBuffer, texCoords).r);
}
10 changes: 10 additions & 0 deletions assets/cubyz/shaders/depth_copy.vs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#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);
}
4 changes: 4 additions & 0 deletions src/graphics.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1565,6 +1565,10 @@ pub const FrameBuffer = struct { // MARK: FrameBuffer
c.glBindTexture(c.GL_TEXTURE_2D, self.texture);
}

pub fn bindImage(self: *const FrameBuffer, binding: u5, format: c_uint) void {
c.glBindImageTexture(binding, self.texture, 0, c.GL_FALSE, 0, c.GL_READ_WRITE, format);
}

pub fn bindDepthTexture(self: *const FrameBuffer, target: c_uint) void {
std.debug.assert(self.hasDepthTexture);
c.glActiveTexture(target);
Expand Down
34 changes: 32 additions & 2 deletions src/renderer.zig
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ var deferredUniforms: struct {
zNear: c_int,
zFar: c_int,
} = undefined;
var depthCopyShader: graphics.Shader = undefined;
var depthCopyUniforms: struct {
zNear: c_int,
zFar: c_int,
} = undefined;
var fakeReflectionShader: graphics.Shader = undefined;
var fakeReflectionUniforms: struct {
normalVector: c_int,
Expand All @@ -60,8 +65,11 @@ var reflectionCubeMap: graphics.CubeMapTexture = undefined;
pub fn init() void {
deferredRenderPassShader = Shader.initAndGetUniforms("assets/cubyz/shaders/deferred_render_pass.vs", "assets/cubyz/shaders/deferred_render_pass.fs", "", &deferredUniforms);
fakeReflectionShader = Shader.initAndGetUniforms("assets/cubyz/shaders/fake_reflection.vs", "assets/cubyz/shaders/fake_reflection.fs", "", &fakeReflectionUniforms);
depthCopyShader = Shader.initAndGetUniforms("assets/cubyz/shaders/depth_copy.vs", "assets/cubyz/shaders/depth_copy.fs", "", &depthCopyUniforms);
worldFrameBuffer.init(true, c.GL_NEAREST, c.GL_CLAMP_TO_EDGE);
worldFrameBuffer.updateSize(Window.width, Window.height, c.GL_RGB16F);
transparentDepthFrameBuffer.init(false, c.GL_NEAREST, c.GL_CLAMP_TO_EDGE);
transparentDepthFrameBuffer.updateSize(Window.width, Window.height, c.GL_R16F);
Bloom.init();
MeshSelection.init();
MenuBackGround.init() catch |err| {
Expand All @@ -78,6 +86,7 @@ pub fn deinit() void {
deferredRenderPassShader.deinit();
fakeReflectionShader.deinit();
worldFrameBuffer.deinit();
transparentDepthFrameBuffer.deinit();
Bloom.deinit();
MeshSelection.deinit();
MenuBackGround.deinit();
Expand Down Expand Up @@ -108,6 +117,7 @@ fn initReflectionCubeMap() void {
}

var worldFrameBuffer: graphics.FrameBuffer = undefined;
var transparentDepthFrameBuffer: graphics.FrameBuffer = undefined;

var lastWidth: u31 = 0;
var lastHeight: u31 = 0;
Expand All @@ -119,6 +129,8 @@ pub fn updateViewport(width: u31, height: u31, fov: f32) void {
game.projectionMatrix = Mat4f.perspective(std.math.degreesToRadians(fov), @as(f32, @floatFromInt(lastWidth))/@as(f32, @floatFromInt(lastHeight)), zNear, zFar);
worldFrameBuffer.updateSize(lastWidth, lastHeight, c.GL_RGB16F);
worldFrameBuffer.unbind();
transparentDepthFrameBuffer.updateSize(lastWidth, lastHeight, c.GL_R16F);
transparentDepthFrameBuffer.unbind();
}

pub fn render(playerPosition: Vec3d) void {
Expand Down Expand Up @@ -221,9 +233,27 @@ pub fn renderWorld(world: *World, ambientLight: Vec3f, skyColor: Vec3f, playerPo
gpu_performance_measuring.stopQuery();

// Render transparent chunk meshes:
worldFrameBuffer.bindDepthTexture(c.GL_TEXTURE5);


gpu_performance_measuring.startQuery(.transparent_rendering_preparation);

worldFrameBuffer.bindDepthTexture(c.GL_TEXTURE5);
c.glTextureBarrier();
transparentDepthFrameBuffer.bind();
depthCopyShader.bind();
c.glUniform1f(depthCopyUniforms.zNear, zNear);
c.glUniform1f(depthCopyUniforms.zFar, zFar);
c.glDisable(c.GL_DEPTH_TEST);
c.glDisable(c.GL_CULL_FACE);
c.glDisable(c.GL_BLEND);
c.glBindVertexArray(graphics.draw.rectVAO);
c.glDrawArrays(c.GL_TRIANGLE_STRIP, 0, 4);
c.glEnable(c.GL_BLEND);
c.glEnable(c.GL_DEPTH_TEST);
c.glEnable(c.GL_CULL_FACE);
worldFrameBuffer.bind();
transparentDepthFrameBuffer.bindImage(5, c.GL_R16F);
c.glMemoryBarrier(c.GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
c.glTextureBarrier();

c.glBlendEquation(c.GL_FUNC_ADD);
Expand Down Expand Up @@ -260,7 +290,7 @@ pub fn renderWorld(world: *World, ambientLight: Vec3f, skyColor: Vec3f, playerPo
gpu_performance_measuring.startQuery(.final_copy);
if(activeFrameBuffer == 0) c.glViewport(0, 0, main.Window.width, main.Window.height);
worldFrameBuffer.bindTexture(c.GL_TEXTURE3);
worldFrameBuffer.bindDepthTexture(c.GL_TEXTURE4);
transparentDepthFrameBuffer.bindTexture(c.GL_TEXTURE4);
worldFrameBuffer.unbind();
deferredRenderPassShader.bind();
c.glUniform1i(deferredUniforms.color, 3);
Expand Down

0 comments on commit b856815

Please sign in to comment.