diff --git a/assets/cubyz/shaders/bloom/color_extractor_downsample.fs b/assets/cubyz/shaders/bloom/color_extractor_downsample.fs index c09e512b..51ceaf9e 100644 --- a/assets/cubyz/shaders/bloom/color_extractor_downsample.fs +++ b/assets/cubyz/shaders/bloom/color_extractor_downsample.fs @@ -7,7 +7,8 @@ in vec2 texCoords; layout(binding = 3) uniform sampler2D color; uniform sampler2D depthTexture; -uniform float nearPlane; +uniform float zNear; +uniform float zFar; uniform vec2 tanXY; struct Fog { @@ -17,8 +18,12 @@ struct Fog { uniform Fog fog; +float zFromDepth(float depthBufferValue) { + return zNear*zFar/(depthBufferValue*(zNear - zFar) + zFar); +} + float calculateFogDistance(float depthBufferValue, float fogDensity) { - float distCameraTerrain = nearPlane*fogDensity/depthBufferValue; + float distCameraTerrain = zFromDepth(depthBufferValue)*fogDensity; float distFromCamera = 0; float distFromTerrain = distFromCamera - distCameraTerrain; if(distCameraTerrain < 10) { // Resolution range is sufficient. diff --git a/assets/cubyz/shaders/chunks/transparent_fragment.fs b/assets/cubyz/shaders/chunks/transparent_fragment.fs index ecfae352..804b7f4d 100644 --- a/assets/cubyz/shaders/chunks/transparent_fragment.fs +++ b/assets/cubyz/shaders/chunks/transparent_fragment.fs @@ -63,7 +63,8 @@ const vec3[6] normals = vec3[6]( vec3(0, 0, -1) ); -uniform float nearPlane; +uniform float zNear; +uniform float zFar; uniform Fog fog; @@ -120,8 +121,12 @@ vec3 unpackColor(uint color) { )/255.0; } +float zFromDepth(float depthBufferValue) { + return zNear*zFar/(depthBufferValue*(zNear - zFar) + zFar); +} + float calculateFogDistance(float depthBufferValue, float fogDensity) { - float distCameraTerrain = nearPlane*fogDensity/depthBufferValue; + float distCameraTerrain = zFromDepth(depthBufferValue)*fogDensity; float distFromCamera = abs(mvVertexPos.z)*fogDensity; float distFromTerrain = distFromCamera - distCameraTerrain; if(distCameraTerrain < 10) { // Resolution range is sufficient. diff --git a/assets/cubyz/shaders/deferred_render_pass.fs b/assets/cubyz/shaders/deferred_render_pass.fs index 1f1470c9..7c97af9b 100644 --- a/assets/cubyz/shaders/deferred_render_pass.fs +++ b/assets/cubyz/shaders/deferred_render_pass.fs @@ -6,7 +6,8 @@ in vec2 texCoords; uniform sampler2D color; uniform sampler2D depthTexture; -uniform float nearPlane; +uniform float zNear; +uniform float zFar; uniform vec2 tanXY; struct Fog { @@ -16,8 +17,12 @@ struct Fog { uniform Fog fog; +float zFromDepth(float depthBufferValue) { + return zNear*zFar/(depthBufferValue*(zNear - zFar) + zFar); +} + float calculateFogDistance(float depthBufferValue, float fogDensity) { - float distCameraTerrain = nearPlane*fogDensity/depthBufferValue; + float distCameraTerrain = zFromDepth(depthBufferValue)*fogDensity; float distFromCamera = 0; float distFromTerrain = distFromCamera - distCameraTerrain; if(distCameraTerrain < 10) { // Resolution range is sufficient. diff --git a/src/chunk.zig b/src/chunk.zig index 2be4b7b2..2fb13faf 100644 --- a/src/chunk.zig +++ b/src/chunk.zig @@ -400,7 +400,8 @@ pub const meshing = struct { time: c_int, visibilityMask: c_int, voxelSize: c_int, - nearPlane: c_int, + zNear: c_int, + zFar: c_int, }; pub var uniforms: UniformStruct = undefined; pub var transparentUniforms: UniformStruct = undefined; @@ -455,7 +456,8 @@ pub const meshing = struct { c.glUniform1i(uniforms.time, @as(u31, @truncate(time))); - c.glUniform1f(uniforms.nearPlane, renderer.zNear); + c.glUniform1f(uniforms.zNear, renderer.zNear); + c.glUniform1f(uniforms.zFar, renderer.zFar); c.glBindVertexArray(vao); } @@ -477,7 +479,8 @@ pub const meshing = struct { c.glUniform1i(transparentUniforms.time, @as(u31, @truncate(time))); - c.glUniform1f(transparentUniforms.nearPlane, renderer.zNear); + c.glUniform1f(transparentUniforms.zNear, renderer.zNear); + c.glUniform1f(transparentUniforms.zFar, renderer.zFar); c.glBindVertexArray(vao); } diff --git a/src/graphics.zig b/src/graphics.zig index bd2ccded..0447399b 100644 --- a/src/graphics.zig +++ b/src/graphics.zig @@ -1660,7 +1660,7 @@ pub fn generateBlockTexture(blockType: u16) !Texture { frameBuffer.clear(.{0, 0, 0, 0}); } - const projMatrix = Mat4f.perspective(0.013, 1, 64); + const projMatrix = Mat4f.perspective(0.013, 1, 64, 256); const oldViewMatrix = main.game.camera.viewMatrix; main.game.camera.viewMatrix = Mat4f.rotationX(std.math.pi/4.0).mul(Mat4f.rotationY(-std.math.pi/4.0)); defer main.game.camera.viewMatrix = oldViewMatrix; diff --git a/src/main.zig b/src/main.zig index a2f6a9a9..4366426d 100644 --- a/src/main.zig +++ b/src/main.zig @@ -714,8 +714,7 @@ pub fn main() !void { c.glCullFace(c.GL_BACK); c.glEnable(c.GL_BLEND); - c.glClipControl(c.GL_LOWER_LEFT, c.GL_ZERO_TO_ONE); - c.glDepthFunc(c.GL_GREATER); + c.glDepthFunc(c.GL_LESS); c.glBlendFunc(c.GL_SRC_ALPHA, c.GL_ONE_MINUS_SRC_ALPHA); Window.GLFWCallbacks.framebufferSize(undefined, Window.width, Window.height); var lastTime = std.time.nanoTimestamp(); diff --git a/src/renderer.zig b/src/renderer.zig index 3734ebbe..3a3e9401 100644 --- a/src/renderer.zig +++ b/src/renderer.zig @@ -27,7 +27,8 @@ const Mat4f = vec.Mat4f; /// The number of milliseconds after which no more chunk meshes are created. This allows the game to run smoother on movement. const maximumMeshTime = 12; -pub const zNear = 1e-10; +pub const zNear = 0.1; +pub const zFar = 65536.0; // TODO: Fix z-fighting problems. var deferredRenderPassShader: graphics.Shader = undefined; var deferredUniforms: struct { @@ -36,7 +37,8 @@ var deferredUniforms: struct { @"fog.color": c_int, @"fog.density": c_int, tanXY: c_int, - nearPlane: c_int, + zNear: c_int, + zFar: c_int, } = undefined; pub var activeFrameBuffer: c_uint = 0; @@ -68,7 +70,7 @@ pub fn updateViewport(width: u31, height: u31, fov: f32) void { lastHeight = height; lastFov = fov; c.glViewport(0, 0, width, height); - game.projectionMatrix = Mat4f.perspective(std.math.degreesToRadians(f32, fov), @as(f32, @floatFromInt(width))/@as(f32, @floatFromInt(height)), zNear); + game.projectionMatrix = Mat4f.perspective(std.math.degreesToRadians(f32, fov), @as(f32, @floatFromInt(width))/@as(f32, @floatFromInt(height)), zNear, zFar); worldFrameBuffer.updateSize(width, height, c.GL_RGBA16F); worldFrameBuffer.unbind(); } @@ -123,7 +125,6 @@ pub fn renderWorld(world: *World, ambientLight: Vec3f, skyColor: Vec3f, playerPo _ = world; worldFrameBuffer.bind(); gpu_performance_measuring.startQuery(.clear); - c.glClearDepth(0.0); worldFrameBuffer.clear(Vec4f{skyColor[0], skyColor[1], skyColor[2], 1}); gpu_performance_measuring.stopQuery(); game.camera.updateViewMatrix(); @@ -189,7 +190,7 @@ pub fn renderWorld(world: *World, ambientLight: Vec3f, skyColor: Vec3f, playerPo c.glBlendEquationSeparate(c.GL_FUNC_ADD, c.GL_FUNC_ADD); c.glBlendFuncSeparate(c.GL_DST_ALPHA, c.GL_SRC1_COLOR, c.GL_DST_ALPHA, c.GL_ZERO); - c.glDepthFunc(c.GL_GEQUAL); + c.glDepthFunc(c.GL_LEQUAL); c.glDepthMask(c.GL_FALSE); { var i: usize = meshes.len; @@ -200,7 +201,7 @@ pub fn renderWorld(world: *World, ambientLight: Vec3f, skyColor: Vec3f, playerPo } } c.glDepthMask(c.GL_TRUE); - c.glDepthFunc(c.GL_GREATER); + c.glDepthFunc(c.GL_LESS); c.glBlendFunc(c.GL_SRC_ALPHA, c.GL_ONE_MINUS_SRC_ALPHA); gpu_performance_measuring.stopQuery(); // NormalChunkMesh.bindTransparentShader(ambientLight, directionalLight.getDirection(), time); @@ -235,7 +236,8 @@ pub fn renderWorld(world: *World, ambientLight: Vec3f, skyColor: Vec3f, playerPo c.glUniform3f(deferredUniforms.@"fog.color", @as(f32, @floatFromInt(fogColor >> 16 & 255))/255.0, @as(f32, @floatFromInt(fogColor >> 8 & 255))/255.0, @as(f32, @floatFromInt(fogColor >> 0 & 255))/255.0); c.glUniform1f(deferredUniforms.@"fog.density", blocks.meshes.fogDensity(playerBlock)); } - c.glUniform1f(deferredUniforms.nearPlane, zNear); + c.glUniform1f(deferredUniforms.zNear, zNear); + c.glUniform1f(deferredUniforms.zFar, zFar); c.glUniform2f(deferredUniforms.tanXY, 1.0/game.projectionMatrix.columns[0][0], 1.0/game.projectionMatrix.columns[1][1]); c.glBindFramebuffer(c.GL_FRAMEBUFFER, activeFrameBuffer); @@ -269,7 +271,8 @@ const Bloom = struct { var upscaleShader: graphics.Shader = undefined; var colorExtractUniforms: struct { depthTexture: c_int, - nearPlane: c_int, + zNear: c_int, + zFar: c_int, tanXY: c_int, @"fog.color": c_int, @"fog.density": c_int, @@ -306,7 +309,8 @@ const Bloom = struct { c.glUniform3f(colorExtractUniforms.@"fog.color", @as(f32, @floatFromInt(fogColor >> 16 & 255))/255.0, @as(f32, @floatFromInt(fogColor >> 8 & 255))/255.0, @as(f32, @floatFromInt(fogColor >> 0 & 255))/255.0); c.glUniform1f(colorExtractUniforms.@"fog.density", blocks.meshes.fogDensity(playerBlock)); } - c.glUniform1f(colorExtractUniforms.nearPlane, zNear); + c.glUniform1f(colorExtractUniforms.zNear, zNear); + c.glUniform1f(colorExtractUniforms.zFar, zFar); c.glUniform2f(colorExtractUniforms.tanXY, 1.0/game.projectionMatrix.columns[0][0], 1.0/game.projectionMatrix.columns[1][1]); c.glBindVertexArray(graphics.draw.rectVAO); c.glDrawArrays(c.GL_TRIANGLE_STRIP, 0, 4); diff --git a/src/vec.zig b/src/vec.zig index c6cdc717..c48dfba6 100644 --- a/src/vec.zig +++ b/src/vec.zig @@ -170,15 +170,15 @@ pub const Mat4f = struct { }; } - pub fn perspective(fovY: f32, aspect: f32, near: f32) Mat4f { + pub fn perspective(fovY: f32, aspect: f32, near: f32, far: f32) Mat4f { const tanY = std.math.tan(fovY*0.5); const tanX = aspect*tanY; - return Mat4f { // Taken from https://chaosinmotion.com/2010/09/06/goodbye-far-clipping-plane/ + return Mat4f { .columns = [4]Vec4f { // Keep in mind that this is the transpose! - Vec4f{1/tanX, 0, 0, 0}, - Vec4f{0, 1/tanY, 0, 0}, - Vec4f{0, 0, 0, -1}, - Vec4f{0, 0, near, 0}, + Vec4f{1/tanX, 0, 0, 0}, + Vec4f{0, 1/tanY, 0, 0}, + Vec4f{0, 0, (far + near)/(near - far), -1}, + Vec4f{0, 0, 2*near*far/(near - far), 0}, } }; }