From 43f37763ce1ce94daf0cc7b82e6ea5754b56c97a Mon Sep 17 00:00:00 2001 From: OneAvargeCoder193 <85588535+OneAvargeCoder193@users.noreply.github.com> Date: Sun, 16 Jun 2024 08:50:52 -0400 Subject: [PATCH] Added biome fog (#466) * Added biome dependent fog * Fix day cycle length * Fixed indentation * Remove world changes * fixed the world frfr this time * fixed the world actually i promise this time * WHYYYYYYYYYYYYYYY * PLEEEEEEEEEEEAAAAAAAAAAAAAAASEEEEEEEEE BE THE LAST COMIT * Fixes * more fixes * Remove world changes * Remove biomeChecksum --- assets/cubyz/biomes/desert.json | 3 +++ src/game.zig | 27 ++++++++++++++++++--------- src/graphics.zig | 3 ++- src/renderer.zig | 6 +++--- src/renderer/chunk_meshing.zig | 2 +- src/server/terrain/biomes.zig | 13 +++++++++++++ 6 files changed, 40 insertions(+), 14 deletions(-) diff --git a/assets/cubyz/biomes/desert.json b/assets/cubyz/biomes/desert.json index db01d7d26..02910736b 100644 --- a/assets/cubyz/biomes/desert.json +++ b/assets/cubyz/biomes/desert.json @@ -9,6 +9,9 @@ "hills" : 20, "music" : "EasternThought", + + "fogDensity" : 20, + "fogColor" : 0xe0dcc3, "ground_structure" : [ "3 to 4 cubyz:sand" diff --git a/src/game.zig b/src/game.zig index 526e734ef..297ae0720 100644 --- a/src/game.zig +++ b/src/game.zig @@ -185,6 +185,7 @@ pub const World = struct { // Ambient light: { const dayTime = @abs(@mod(self.gameTime.load(.monotonic), dayCycle) -% dayCycle/2); + const biomeFog = fog.fogColor; if(dayTime < dayCycle/4 - dayCycle/16) { self.ambientLight = 0.1; self.clearColor[0] = 0; @@ -192,29 +193,29 @@ pub const World = struct { self.clearColor[2] = 0; } else if(dayTime > dayCycle/4 + dayCycle/16) { self.ambientLight = 1; - self.clearColor[0] = 0.8; - self.clearColor[1] = 0.8; - self.clearColor[2] = 1.0; + self.clearColor[0] = biomeFog[0]; + self.clearColor[1] = biomeFog[1]; + self.clearColor[2] = biomeFog[2]; } else { // b: if(dayTime > dayCycle/4) { - self.clearColor[2] = @as(f32, @floatFromInt(dayTime - dayCycle/4))/@as(f32, @floatFromInt(dayCycle/16)); + self.clearColor[2] = biomeFog[2] * @as(f32, @floatFromInt(dayTime - dayCycle/4))/@as(f32, @floatFromInt(dayCycle/16)); } else { self.clearColor[2] = 0; } // g: if(dayTime > dayCycle/4 + dayCycle/32) { - self.clearColor[1] = 0.8; + self.clearColor[1] = biomeFog[1]; } else if(dayTime > dayCycle/4 - dayCycle/32) { - self.clearColor[1] = 0.8 - 0.8*@as(f32, @floatFromInt(dayCycle/4 + dayCycle/32 - dayTime))/@as(f32, @floatFromInt(dayCycle/16)); + self.clearColor[1] = biomeFog[1] - biomeFog[1]*@as(f32, @floatFromInt(dayCycle/4 + dayCycle/32 - dayTime))/@as(f32, @floatFromInt(dayCycle/16)); } else { self.clearColor[1] = 0; } // r: if(dayTime > dayCycle/4) { - self.clearColor[0] = 0.8; + self.clearColor[0] = biomeFog[0]; } else { - self.clearColor[0] = 0.8 - 0.8*@as(f32, @floatFromInt(dayCycle/4 - dayTime))/@as(f32, @floatFromInt(dayCycle/16)); + self.clearColor[0] = biomeFog[0] - biomeFog[0]*@as(f32, @floatFromInt(dayCycle/4 - dayTime))/@as(f32, @floatFromInt(dayCycle/16)); } self.ambientLight = 0.1 + 0.9*@as(f32, @floatFromInt(dayTime - (dayCycle/4 - dayCycle/16)))/@as(f32, @floatFromInt(dayCycle/8)); } @@ -227,7 +228,7 @@ pub var world: ?*World = null; pub var projectionMatrix: Mat4f = Mat4f.identity(); -pub var fog = Fog{.color=.{0, 1, 0.5}, .density=1.0/15.0/128.0}; // TODO: Make this depend on the render distance. +pub var fog = Fog{.skyColor=.{0.8, 0.8, 1}, .fogColor=.{0.8, 0.8, 1}, .density=1.0/15.0/128.0}; // TODO: Make this depend on the render distance. var nextBlockPlaceTime: ?i64 = null; var nextBlockBreakTime: ?i64 = null; @@ -325,5 +326,13 @@ pub fn update(deltaTime: f64) void { defer Player.mutex.unlock(); Player.super.pos += movement*@as(Vec3d, @splat(deltaTime)); } + + const biome = world.?.playerBiome.load(.monotonic); + + const t = 1 - @as(f32, @floatCast(@exp(-2 * deltaTime))); + + fog.fogColor = (biome.fogColor - fog.fogColor) * @as(Vec3f, @splat(t)) + fog.fogColor; + fog.density = (biome.fogDensity - fog.density) * t + fog.density; + world.?.update(); } \ No newline at end of file diff --git a/src/graphics.zig b/src/graphics.zig index 748cdf36d..65fbe814f 100644 --- a/src/graphics.zig +++ b/src/graphics.zig @@ -1912,7 +1912,8 @@ pub const Image = struct { }; pub const Fog = struct { - color: Vec3f, + fogColor: Vec3f, + skyColor: Vec3f, density: f32, }; diff --git a/src/renderer.zig b/src/renderer.zig index bb3d06b1d..1f48476d8 100644 --- a/src/renderer.zig +++ b/src/renderer.zig @@ -130,7 +130,7 @@ pub fn render(playerPosition: Vec3d) void { ambient[1] = @max(0.1, world.ambientLight); ambient[2] = @max(0.1, world.ambientLight); const skyColor = vec.xyz(world.clearColor); - game.fog.color = skyColor; + game.fog.skyColor = skyColor; renderWorld(world, ambient, skyColor, playerPosition); const startTime = std.time.milliTimestamp(); @@ -271,7 +271,7 @@ pub fn renderWorld(world: *World, ambientLight: Vec3f, skyColor: Vec3f, playerPo c.glUniform1i(deferredUniforms.color, 3); c.glUniform1i(deferredUniforms.depthTexture, 4); if(!blocks.meshes.hasFog(playerBlock)) { - c.glUniform3fv(deferredUniforms.@"fog.color", 1, @ptrCast(&game.fog.color)); + c.glUniform3fv(deferredUniforms.@"fog.color", 1, @ptrCast(&game.fog.skyColor)); c.glUniform1f(deferredUniforms.@"fog.density", game.fog.density); } else { const fogColor = blocks.meshes.fogColor(playerBlock); @@ -337,7 +337,7 @@ const Bloom = struct { buffer1.bind(); c.glUniform1i(colorExtractUniforms.depthTexture, 4); if(!blocks.meshes.hasFog(playerBlock)) { - c.glUniform3fv(colorExtractUniforms.@"fog.color", 1, @ptrCast(&game.fog.color)); + c.glUniform3fv(colorExtractUniforms.@"fog.color", 1, @ptrCast(&game.fog.skyColor)); c.glUniform1f(colorExtractUniforms.@"fog.density", game.fog.density); } else { const fogColor = blocks.meshes.fogColor(playerBlock); diff --git a/src/renderer/chunk_meshing.zig b/src/renderer/chunk_meshing.zig index 68172b18f..626656c04 100644 --- a/src/renderer/chunk_meshing.zig +++ b/src/renderer/chunk_meshing.zig @@ -150,7 +150,7 @@ pub fn bindShaderAndUniforms(projMatrix: Mat4f, ambient: Vec3f, playerPos: Vec3d pub fn bindTransparentShaderAndUniforms(projMatrix: Mat4f, ambient: Vec3f, playerPos: Vec3d) void { transparentShader.bind(); - c.glUniform3fv(transparentUniforms.@"fog.color", 1, @ptrCast(&game.fog.color)); + c.glUniform3fv(transparentUniforms.@"fog.color", 1, @ptrCast(&game.fog.skyColor)); c.glUniform1f(transparentUniforms.@"fog.density", game.fog.density); bindCommonUniforms(&transparentUniforms, projMatrix, ambient, playerPos); diff --git a/src/server/terrain/biomes.zig b/src/server/terrain/biomes.zig index cd26f3e08..cea1b865d 100644 --- a/src/server/terrain/biomes.zig +++ b/src/server/terrain/biomes.zig @@ -7,6 +7,7 @@ const JsonElement = main.JsonElement; const terrain = main.server.terrain; const NeverFailingAllocator = main.utils.NeverFailingAllocator; const vec = @import("main.vec"); +const Vec3f = main.vec.Vec3f; const Vec3d = main.vec.Vec3d; const StructureModel = struct { @@ -182,6 +183,14 @@ pub const Interpolation = enum(u8) { square, }; +fn u32ToVec3(color: u32) Vec3f { + const r = @as(f32, @floatFromInt((color >> 16) & 0xFF)) / 255.0; + const g = @as(f32, @floatFromInt((color >> 8) & 0xFF)) / 255.0; + const b = @as(f32, @floatFromInt(color & 0xFF)) / 255.0; + + return .{ r, g, b }; +} + /// A climate region with special ground, plants and structures. pub const Biome = struct { const GenerationProperties = packed struct(u8) { @@ -225,6 +234,8 @@ pub const Biome = struct { crystals: u32, stalagmites: u32, stoneBlockType: u16, + fogDensity: f32, + fogColor: Vec3f, id: []const u8, structure: BlockStructure = undefined, /// Whether the starting point of a river can be in this biome. If false rivers will be able to flow through this biome anyways. @@ -246,6 +257,8 @@ pub const Biome = struct { .isCave = json.get(bool, "isCave", false), .radius = json.get(f32, "radius", 256), .stoneBlockType = blocks.getByID(json.get([]const u8, "stoneBlock", "cubyz:stone")), + .fogColor = u32ToVec3(json.get(u32, "fogColor", 0xffccccff)), + .fogDensity = json.get(f32, "fogDensity", 1.0)/15.0/128.0, .roughness = json.get(f32, "roughness", 0), .hills = json.get(f32, "hills", 0), .mountains = json.get(f32, "mountains", 0),