diff --git a/assets/cubyz/shaders/chunks/chunk_fragment.frag b/assets/cubyz/shaders/chunks/chunk_fragment.frag index 8515a0bc84..8ee414ae18 100644 --- a/assets/cubyz/shaders/chunks/chunk_fragment.frag +++ b/assets/cubyz/shaders/chunks/chunk_fragment.frag @@ -51,12 +51,17 @@ vec4 fixedCubeMapLookup(vec3 v) { // Taken from http://the-witness.net/news/2012 return texture(reflectionMap, v); } +float srgbToLinear(float srgbChannel) { + if(srgbChannel <= 0.04045) return srgbChannel/12.92; + return pow((srgbChannel + 0.055)/1.055, 2.4); +} + void main() { float animatedTextureIndex = animatedTexture[textureIndex]; float normalVariation = lightVariation(normal); vec3 textureCoords = vec3(uv, animatedTextureIndex); - float reflectivity = texture(reflectivityAndAbsorptionSampler, textureCoords).a; + float reflectivity = srgbToLinear(texture(reflectivityAndAbsorptionSampler, textureCoords).a); float fresnelReflection = (1 + dot(normalize(direction), normal)); fresnelReflection *= fresnelReflection; fresnelReflection *= min(1, 2*reflectivity); // Limit it to 2*reflectivity to avoid making every block reflective. diff --git a/assets/cubyz/shaders/chunks/transparent_fragment.frag b/assets/cubyz/shaders/chunks/transparent_fragment.frag index 51b47e6b20..beed8b1aca 100644 --- a/assets/cubyz/shaders/chunks/transparent_fragment.frag +++ b/assets/cubyz/shaders/chunks/transparent_fragment.frag @@ -130,6 +130,19 @@ vec4 fixedCubeMapLookup(vec3 v) { // Taken from http://the-witness.net/news/2012 return texture(reflectionMap, v); } +float srgbToLinear(float srgbChannel) { + if(srgbChannel <= 0.04045) return srgbChannel/12.92; + return pow((srgbChannel + 0.055)/1.055, 2.4); +} + +vec3 srgbToLinear(vec3 srgb) { + return vec3( + srgbToLinear(srgb.r), + srgbToLinear(srgb.g), + srgbToLinear(srgb.b) + ); +} + void main() { float animatedTextureIndex = animatedTexture[textureIndex]; vec3 textureCoords = vec3(uv, animatedTextureIndex); @@ -138,11 +151,11 @@ void main() { float dist = zFromDepth(texelFetch(depthTexture, ivec2(gl_FragCoord.xy), 0).r); float fogDistance = calculateFogDistance(dist, densityAdjustment, playerPositionFraction.z, normalize(direction).z, fogData[int(animatedTextureIndex)].fogDensity, 1e10, 1e10); float airFogDistance = calculateFogDistance(dist, densityAdjustment, playerPositionFraction.z, normalize(direction).z, fog.density, fog.fogLower - playerPositionInteger.z, fog.fogHigher - playerPositionInteger.z); - vec3 fogColor = unpackColor(fogData[int(animatedTextureIndex)].fogColor); + vec3 fogColor = srgbToLinear(unpackColor(fogData[int(animatedTextureIndex)].fogColor)); vec3 pixelLight = max(light*normalVariation, texture(emissionSampler, textureCoords).r*4); vec4 textureColor = texture(textureSampler, textureCoords)*vec4(pixelLight, 1); - float reflectivity = texture(reflectivityAndAbsorptionSampler, textureCoords).a; + float reflectivity = srgbToLinear(texture(reflectivityAndAbsorptionSampler, textureCoords).a); float fresnelReflection = (1 + dot(normalize(direction), normal)); fresnelReflection *= fresnelReflection; fresnelReflection *= min(1, 2*reflectivity); // Limit it to 2*reflectivity to avoid making every block reflective. diff --git a/assets/cubyz/shaders/graphics/Circle.vert b/assets/cubyz/shaders/graphics/Circle.vert index 5946d1dcad..e9f7cd030e 100644 --- a/assets/cubyz/shaders/graphics/Circle.vert +++ b/assets/cubyz/shaders/graphics/Circle.vert @@ -12,6 +12,19 @@ layout(location = 2) uniform vec2 screen; layout(location = 3) uniform int circleColor; +float srgbToLinear(float srgbChannel) { + if(srgbChannel <= 0.04045) return srgbChannel/12.92; + return pow((srgbChannel + 0.055)/1.055, 2.4); +} + +vec3 srgbToLinear(vec3 srgb) { + return vec3( + srgbToLinear(srgb.r), + srgbToLinear(srgb.g), + srgbToLinear(srgb.b) + ); +} + void main() { // Convert to opengl coordinates: vec2 position_percentage = (center + vertex_pos*radius)/screen; @@ -20,7 +33,7 @@ void main() { gl_Position = vec4(position, 0, 1); - color = vec4((circleColor & 0xff0000)>>16, (circleColor & 0xff00)>>8, circleColor & 0xff, (circleColor>>24) & 255)/255.0; + color = vec4(srgbToLinear(vec3((circleColor & 0xff0000)>>16, (circleColor & 0xff00)>>8, circleColor & 0xff)/255.0), float((circleColor>>24) & 255)/255.0); unitPosition = vertex_pos; } diff --git a/assets/cubyz/shaders/graphics/Image.vert b/assets/cubyz/shaders/graphics/Image.vert index cb42f055e5..b55d66d1dc 100644 --- a/assets/cubyz/shaders/graphics/Image.vert +++ b/assets/cubyz/shaders/graphics/Image.vert @@ -14,6 +14,19 @@ layout(location = 4) uniform vec2 uvDim; layout(location = 5) uniform int color; +float srgbToLinear(float srgbChannel) { + if(srgbChannel <= 0.04045) return srgbChannel/12.92; + return pow((srgbChannel + 0.055)/1.055, 2.4); +} + +vec3 srgbToLinear(vec3 srgb) { + return vec3( + srgbToLinear(srgb.r), + srgbToLinear(srgb.g), + srgbToLinear(srgb.b) + ); +} + void main() { // Convert to opengl coordinates: vec2 position_percentage = (start + vec2(vertex_pos.x*size.x, size.y - vertex_pos.y*size.y))/screen; @@ -22,6 +35,6 @@ void main() { gl_Position = vec4(position, 0, 1); - fColor = vec4((color & 0xff0000)>>16, (color & 0xff00)>>8, color & 0xff, (color>>24) & 255)/255.0; + fColor = vec4(srgbToLinear(vec3((color & 0xff0000)>>16, (color & 0xff00)>>8, color & 0xff)/255.0), float((color>>24) & 255)/255.0); uv = uvOffset + vertex_pos*uvDim; } diff --git a/assets/cubyz/shaders/graphics/Line.vert b/assets/cubyz/shaders/graphics/Line.vert index e683b8fdb7..46f6fe7680 100644 --- a/assets/cubyz/shaders/graphics/Line.vert +++ b/assets/cubyz/shaders/graphics/Line.vert @@ -11,6 +11,19 @@ layout(location = 2) uniform vec2 screen; layout(location = 3) uniform int lineColor; +float srgbToLinear(float srgbChannel) { + if(srgbChannel <= 0.04045) return srgbChannel/12.92; + return pow((srgbChannel + 0.055)/1.055, 2.4); +} + +vec3 srgbToLinear(vec3 srgb) { + return vec3( + srgbToLinear(srgb.r), + srgbToLinear(srgb.g), + srgbToLinear(srgb.b) + ); +} + void main() { // Convert to opengl coordinates: vec2 position_percentage = (start + vertex_pos*direction)/screen; @@ -19,5 +32,5 @@ void main() { gl_Position = vec4(position, 0, 1); - color = vec4((lineColor & 0xff0000)>>16, (lineColor & 0xff00)>>8, lineColor & 0xff, (lineColor>>24) & 255)/255.0; + color = vec4(srgbToLinear(vec3((lineColor & 0xff0000)>>16, (lineColor & 0xff00)>>8, lineColor & 0xff)/255.0), float((lineColor>>24) & 255)/255.0); } diff --git a/assets/cubyz/shaders/graphics/Rect.vert b/assets/cubyz/shaders/graphics/Rect.vert index c6371a9146..5ffaf4dbf1 100644 --- a/assets/cubyz/shaders/graphics/Rect.vert +++ b/assets/cubyz/shaders/graphics/Rect.vert @@ -11,6 +11,19 @@ layout(location = 2) uniform vec2 screen; layout(location = 3) uniform int rectColor; +float srgbToLinear(float srgbChannel) { + if(srgbChannel <= 0.04045) return srgbChannel/12.92; + return pow((srgbChannel + 0.055)/1.055, 2.4); +} + +vec3 srgbToLinear(vec3 srgb) { + return vec3( + srgbToLinear(srgb.r), + srgbToLinear(srgb.g), + srgbToLinear(srgb.b) + ); +} + void main() { // Convert to opengl coordinates: vec2 position_percentage = (start + vertex_pos*size)/screen; @@ -19,5 +32,5 @@ void main() { gl_Position = vec4(position, 0, 1); - color = vec4((rectColor & 0xff0000)>>16, (rectColor & 0xff00)>>8, rectColor & 0xff, (rectColor>>24) & 255)/255.0;; + color = vec4(srgbToLinear(vec3((rectColor & 0xff0000)>>16, (rectColor & 0xff00)>>8, rectColor & 0xff)/255.0), float((rectColor>>24) & 255)/255.0); } diff --git a/assets/cubyz/shaders/graphics/RectBorder.vert b/assets/cubyz/shaders/graphics/RectBorder.vert index 88e6431d57..6eb58a86a6 100644 --- a/assets/cubyz/shaders/graphics/RectBorder.vert +++ b/assets/cubyz/shaders/graphics/RectBorder.vert @@ -12,6 +12,19 @@ layout(location = 3) uniform float lineWidth; layout(location = 4) uniform int rectColor; +float srgbToLinear(float srgbChannel) { + if(srgbChannel <= 0.04045) return srgbChannel/12.92; + return pow((srgbChannel + 0.055)/1.055, 2.4); +} + +vec3 srgbToLinear(vec3 srgb) { + return vec3( + srgbToLinear(srgb.r), + srgbToLinear(srgb.g), + srgbToLinear(srgb.b) + ); +} + void main() { // Convert to opengl coordinates: vec2 position_percentage = (start + vertex_pos.xy*size + vertex_pos.zw*lineWidth)/screen; @@ -20,5 +33,5 @@ void main() { gl_Position = vec4(position, 0, 1); - color = vec4((rectColor & 0xff0000)>>16, (rectColor & 0xff00)>>8, rectColor & 0xff, (rectColor>>24) & 255)/255.0;; + color = vec4(srgbToLinear(vec3((rectColor & 0xff0000)>>16, (rectColor & 0xff00)>>8, rectColor & 0xff)/255.0), float((rectColor>>24) & 255)/255.0); } diff --git a/assets/cubyz/shaders/graphics/Text.vert b/assets/cubyz/shaders/graphics/Text.vert index ee8f8ee775..e32442190f 100644 --- a/assets/cubyz/shaders/graphics/Text.vert +++ b/assets/cubyz/shaders/graphics/Text.vert @@ -14,6 +14,19 @@ layout(location = 4) uniform int fontEffects; layout(location = 5) uniform float alpha; +float srgbToLinear(float srgbChannel) { + if(srgbChannel <= 0.04045) return srgbChannel/12.92; + return pow((srgbChannel + 0.055)/1.055, 2.4); +} + +vec3 srgbToLinear(vec3 srgb) { + return vec3( + srgbToLinear(srgb.r), + srgbToLinear(srgb.g), + srgbToLinear(srgb.b) + ); +} + vec2 convert2Proportional(vec2 original, vec2 full) { return vec2(original.x/full.x, original.y/full.y); } @@ -33,5 +46,5 @@ void main() { gl_Position = vec4(position, 0, 1); frag_face_pos = face_pos; - color = vec4(vec3((fontEffects & 0xff0000)>>16, (fontEffects & 0xff00)>>8, fontEffects & 0xff)/255.0, alpha); + color = vec4(srgbToLinear(vec3((fontEffects & 0xff0000)>>16, (fontEffects & 0xff00)>>8, fontEffects & 0xff)/255.0), alpha); } diff --git a/assets/cubyz/shaders/graphics/graph.vert b/assets/cubyz/shaders/graphics/graph.vert index 9c2fe68db6..cbc59673ad 100644 --- a/assets/cubyz/shaders/graphics/graph.vert +++ b/assets/cubyz/shaders/graphics/graph.vert @@ -12,7 +12,6 @@ layout(std430, binding = 5) buffer _data float data[]; }; - void main() { float x = gl_VertexID; float y = -data[(gl_VertexID+offset)%points]; diff --git a/assets/cubyz/shaders/item_drop.frag b/assets/cubyz/shaders/item_drop.frag index 785163f5d2..8a2ff34e6d 100644 --- a/assets/cubyz/shaders/item_drop.frag +++ b/assets/cubyz/shaders/item_drop.frag @@ -42,6 +42,19 @@ layout(std430, binding = 1) buffer _animatedTexture float animatedTexture[]; }; +float srgbToLinear(float srgbChannel) { + if(srgbChannel <= 0.04045) return srgbChannel/12.92; + return pow((srgbChannel + 0.055)/1.055, 2.4); +} + +vec3 srgbToLinear(vec3 srgb) { + return vec3( + srgbToLinear(srgb.r), + srgbToLinear(srgb.g), + srgbToLinear(srgb.b) + ); +} + // block drops ------------------------------------------------------------------------------------------------------------------------- float lightVariation(vec3 normal) { @@ -182,6 +195,7 @@ void mainItemDrop() { fragColor = decodeColor(block); fragColor.a = 1; // No transparency supported! + fragColor.rgb = srgbToLinear(fragColor.rgb); fragColor = fragColor*vec4(ambientLight*normalVariations[lastNormal], 1); } diff --git a/src/blocks.zig b/src/blocks.zig index 195cf76853..907d509392 100644 --- a/src/blocks.zig +++ b/src/blocks.zig @@ -27,6 +27,7 @@ const BlockTouchCallback = main.callbacks.BlockTouchCallback; const sbb = main.server.terrain.structure_building_blocks; const blueprint = main.blueprint; const Assets = main.assets.Assets; +const Vec3f = main.vec.Vec3f; pub const maxBlockCount: usize = 65536; // 16 bit limit @@ -97,6 +98,13 @@ var size: u32 = 0; pub var ores: main.ListUnmanaged(Ore) = .{}; +pub fn transformLightFromSrgb(in: u32) u32 { + const srgb = @as(Vec3f, @floatFromInt(@Vector(3, u32){in >> 16 & 255, in >> 8 & 255, in & 255}))/@as(Vec3f, @splat(255)); + const linear = main.graphics.srgbToLinear(srgb); + const bytes: @Vector(3, u8) = @intFromFloat(@round(linear*@as(Vec3f, @splat(255)))); + return @as(u32, bytes[0]) << 16 | @as(u32, bytes[1]) << 8 | bytes[2]; +} + pub fn register(_: []const u8, id: []const u8, zon: ZonElement) u16 { _id[size] = main.worldArena.dupe(u8, id); reverseIndices.put(main.worldArena.allocator, _id[size], @intCast(size)) catch unreachable; @@ -117,8 +125,8 @@ pub fn register(_: []const u8, id: []const u8, zon: ZonElement) u16 { } } - _light[size] = zon.get(u32, "emittedLight", 0); - _absorption[size] = zon.get(u32, "absorbedLight", 0xffffff); + _light[size] = transformLightFromSrgb(zon.get(u32, "emittedLight", 0)); + _absorption[size] = transformLightFromSrgb(zon.get(u32, "absorbedLight", 0xffffff)); _degradable[size] = zon.get(bool, "degradable", false); _selectable[size] = zon.get(bool, "selectable", true); _replacable[size] = zon.get(bool, "replacable", false); @@ -766,9 +774,9 @@ pub const meshes = struct { // MARK: meshes pub fn generateTextureArray() void { const c = graphics.c; - blockTextureArray.generate(blockTextures.items, true, true); + blockTextureArray.generate(blockTextures.items, .srgb, true, true); c.glTexParameterf(c.GL_TEXTURE_2D_ARRAY, c.GL_TEXTURE_MAX_ANISOTROPY, @floatFromInt(main.settings.anisotropicFiltering)); - emissionTextureArray.generate(emissionTextures.items, true, false); + emissionTextureArray.generate(emissionTextures.items, .linear, true, false); c.glTexParameterf(c.GL_TEXTURE_2D_ARRAY, c.GL_TEXTURE_MAX_ANISOTROPY, @floatFromInt(main.settings.anisotropicFiltering)); const reflectivityAndAbsorptionTextures = main.stackAllocator.alloc(Image, reflectivityTextures.items.len); defer main.stackAllocator.free(reflectivityAndAbsorptionTextures); @@ -787,7 +795,7 @@ pub const meshes = struct { // MARK: meshes } } } - reflectivityAndAbsorptionTextureArray.generate(reflectivityAndAbsorptionTextures, true, false); + reflectivityAndAbsorptionTextureArray.generate(reflectivityAndAbsorptionTextures, .srgb, true, false); c.glTexParameterf(c.GL_TEXTURE_2D_ARRAY, c.GL_TEXTURE_MAX_ANISOTROPY, @floatFromInt(main.settings.anisotropicFiltering)); // Also generate additional buffers: diff --git a/src/graphics.zig b/src/graphics.zig index 5e6db485dc..dda15cbdae 100644 --- a/src/graphics.zig +++ b/src/graphics.zig @@ -2197,7 +2197,7 @@ pub const TextureArray = struct { // MARK: TextureArray } /// (Re-)Generates the GPU buffer. - pub fn generate(self: TextureArray, images: []Image, mipmapping: bool, alphaCorrectMipmapping: bool) void { + pub fn generate(self: TextureArray, images: []Image, transformFunction: enum{linear, srgb}, mipmapping: bool, alphaCorrectMipmapping: bool) void { var maxWidth: u31 = 1; var maxHeight: u31 = 1; for(images) |image| { @@ -2217,8 +2217,12 @@ pub const TextureArray = struct { // MARK: TextureArray self.bind(); const maxLOD = if(mipmapping) 1 + std.math.log2_int(u31, @min(maxWidth, maxHeight)) else 1; + const format = switch(transformFunction) { + .linear => c.GL_RGBA8, + .srgb => c.GL_SRGB8_ALPHA8, + }; for(0..maxLOD) |i| { - c.glTexImage3D(c.GL_TEXTURE_2D_ARRAY, @intCast(i), c.GL_RGBA8, @max(0, maxWidth >> @intCast(i)), @max(0, maxHeight >> @intCast(i)), @intCast(images.len), 0, c.GL_RGBA, c.GL_UNSIGNED_BYTE, null); + c.glTexImage3D(c.GL_TEXTURE_2D_ARRAY, @intCast(i), format, @max(0, maxWidth >> @intCast(i)), @max(0, maxHeight >> @intCast(i)), @intCast(images.len), 0, c.GL_RGBA, c.GL_UNSIGNED_BYTE, null); } const arena = main.stackAllocator.createArena(); defer main.stackAllocator.destroyArena(arena); @@ -2319,7 +2323,7 @@ pub const Texture = struct { // MARK: Texture var curSize: u31 = largestSize; while(curSize != 0) : (curSize /= 2) { - c.glTexImage2D(c.GL_TEXTURE_2D, maxLod - std.math.log2_int(u31, curSize), c.GL_RGBA8, curSize, curSize, 0, c.GL_RGBA, c.GL_UNSIGNED_BYTE, null); + c.glTexImage2D(c.GL_TEXTURE_2D, maxLod - std.math.log2_int(u31, curSize), c.GL_SRGB8_ALPHA8, curSize, curSize, 0, c.GL_RGBA, c.GL_UNSIGNED_BYTE, null); } curSize = largestSize; @@ -2360,7 +2364,7 @@ pub const Texture = struct { // MARK: Texture 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); + c.glTexImage2D(c.GL_TEXTURE_2D, 0, c.GL_SRGB8_ALPHA8, image.width, image.height, 0, c.GL_RGBA, c.GL_UNSIGNED_BYTE, image.imageData.ptr); c.glTexParameteri(c.GL_TEXTURE_2D, c.GL_TEXTURE_MIN_FILTER, c.GL_NEAREST); c.glTexParameteri(c.GL_TEXTURE_2D, c.GL_TEXTURE_MAG_FILTER, c.GL_NEAREST); c.glTexParameteri(c.GL_TEXTURE_2D, c.GL_TEXTURE_WRAP_S, c.GL_REPEAT); @@ -2699,7 +2703,7 @@ pub fn generateBlockTexture(blockType: u16) Texture { c.glDisable(c.GL_CULL_FACE); var finalFrameBuffer: FrameBuffer = undefined; finalFrameBuffer.init(false, c.GL_NEAREST, c.GL_REPEAT); - finalFrameBuffer.updateSize(textureSize, textureSize, c.GL_RGBA8); + finalFrameBuffer.updateSize(textureSize, textureSize, c.GL_SRGB8_ALPHA8); finalFrameBuffer.bind(); const texture = Texture{.textureID = finalFrameBuffer.texture}; defer c.glDeleteFramebuffers(1, &finalFrameBuffer.frameBuffer); @@ -2716,3 +2720,16 @@ pub fn generateBlockTexture(blockType: u16) Texture { c.glBlendFunc(c.GL_SRC_ALPHA, c.GL_ONE_MINUS_SRC_ALPHA); return texture; } + +fn srgbChannelToLinear(srgbChannel: f32) f32 { + if(srgbChannel <= 0.04045) return srgbChannel/12.92; + return std.math.pow(f32, (srgbChannel + 0.055)/1.055, 2.4); +} + +pub fn srgbToLinear(srgb: Vec3f) Vec3f { + return .{ + srgbChannelToLinear(srgb[0]), + srgbChannelToLinear(srgb[1]), + srgbChannelToLinear(srgb[2]), + }; +} diff --git a/src/main.zig b/src/main.zig index e7895ed076..e136a6b715 100644 --- a/src/main.zig +++ b/src/main.zig @@ -608,6 +608,7 @@ pub fn clientMain() void { // MARK: clientMain() const c = Window.c; Window.GLFWCallbacks.framebufferSize(undefined, Window.width, Window.height); + c.glEnable(c.GL_FRAMEBUFFER_SRGB); var lastBeginRendering = timestamp(); audio.setMusic("cubyz:TotalDemented/Cubyz"); diff --git a/src/particles.zig b/src/particles.zig index 0589f1bbf6..c80ab5fc6e 100644 --- a/src/particles.zig +++ b/src/particles.zig @@ -136,8 +136,8 @@ pub const ParticleManager = struct { } pub fn generateTextureArray() void { - textureArray.generate(textures.items, true, true); - emissionTextureArray.generate(emissionTextures.items, true, false); + textureArray.generate(textures.items, .srgb, true, true); + emissionTextureArray.generate(emissionTextures.items, .linear, true, false); particleTypesSSBO.bufferData(ParticleType, ParticleManager.types.items); particleTypesSSBO.bind(14); diff --git a/src/renderer.zig b/src/renderer.zig index b4162a8533..d1d0b79e63 100644 --- a/src/renderer.zig +++ b/src/renderer.zig @@ -153,7 +153,7 @@ pub fn render(playerPosition: Vec3d, deltaTime: f64) void { ambient[2] = @max(0.1, game.world.?.ambientLight); itemdrop.ItemDisplayManager.update(deltaTime); - renderWorld(game.world.?, ambient, game.fog.skyColor, playerPosition); + renderWorld(game.world.?, ambient, graphics.srgbToLinear(game.fog.skyColor), playerPosition); const startTime = main.timestamp(); mesh_storage.updateMeshes(startTime.addDuration(maximumMeshTime)); } @@ -299,13 +299,15 @@ pub fn renderWorld(world: *World, ambientLight: Vec3f, skyColor: Vec3f, playerPo worldFrameBuffer.unbind(); deferredRenderPassPipeline.bind(null); if(!blocks.meshes.hasFog(playerBlock)) { - c.glUniform3fv(deferredUniforms.@"fog.color", 1, @ptrCast(&game.fog.fogColor)); + const fogColor = graphics.srgbToLinear(game.fog.fogColor); + c.glUniform3fv(deferredUniforms.@"fog.color", 1, @ptrCast(&fogColor)); c.glUniform1f(deferredUniforms.@"fog.density", game.fog.density); c.glUniform1f(deferredUniforms.@"fog.fogLower", game.fog.fogLower); c.glUniform1f(deferredUniforms.@"fog.fogHigher", game.fog.fogHigher); } else { - const fogColor = blocks.meshes.fogColor(playerBlock); - 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); + const fogColorInt = blocks.meshes.fogColor(playerBlock); + const fogColor = graphics.srgbToLinear(Vec3f{@floatFromInt(fogColorInt >> 16 & 255), @floatFromInt(fogColorInt >> 8 & 255), @floatFromInt(fogColorInt >> 0 & 255)}/Vec3f{255, 255, 255}); + c.glUniform3fv(deferredUniforms.@"fog.color", 1, @ptrCast(&fogColor)); c.glUniform1f(deferredUniforms.@"fog.density", blocks.meshes.fogDensity(playerBlock)); c.glUniform1f(deferredUniforms.@"fog.fogLower", 1e10); c.glUniform1f(deferredUniforms.@"fog.fogHigher", 1e10); @@ -398,13 +400,15 @@ const Bloom = struct { // MARK: Bloom worldFrameBuffer.bindDepthTexture(c.GL_TEXTURE4); buffer1.bind(); if(!blocks.meshes.hasFog(playerBlock)) { - c.glUniform3fv(colorExtractUniforms.@"fog.color", 1, @ptrCast(&game.fog.fogColor)); + const fogColor = graphics.srgbToLinear(game.fog.fogColor); + c.glUniform3fv(colorExtractUniforms.@"fog.color", 1, @ptrCast(&fogColor)); c.glUniform1f(colorExtractUniforms.@"fog.density", game.fog.density); c.glUniform1f(colorExtractUniforms.@"fog.fogLower", game.fog.fogLower); c.glUniform1f(colorExtractUniforms.@"fog.fogHigher", game.fog.fogHigher); } else { - const fogColor = blocks.meshes.fogColor(playerBlock); - 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); + const fogColorInt = blocks.meshes.fogColor(playerBlock); + const fogColor = graphics.srgbToLinear(Vec3f{@floatFromInt(fogColorInt >> 16 & 255), @floatFromInt(fogColorInt >> 8 & 255), @floatFromInt(fogColorInt >> 0 & 255)}/Vec3f{255, 255, 255}); + c.glUniform3fv(colorExtractUniforms.@"fog.color", 1, @ptrCast(&fogColor)); c.glUniform1f(colorExtractUniforms.@"fog.density", blocks.meshes.fogDensity(playerBlock)); c.glUniform1f(colorExtractUniforms.@"fog.fogLower", 1e10); c.glUniform1f(colorExtractUniforms.@"fog.fogHigher", 1e10); diff --git a/src/renderer/chunk_meshing.zig b/src/renderer/chunk_meshing.zig index 29599f6d3b..88a992d1b4 100644 --- a/src/renderer/chunk_meshing.zig +++ b/src/renderer/chunk_meshing.zig @@ -210,7 +210,8 @@ pub fn bindShaderAndUniforms(projMatrix: Mat4f, ambient: Vec3f, playerPos: Vec3d pub fn bindTransparentShaderAndUniforms(projMatrix: Mat4f, ambient: Vec3f, playerPos: Vec3d) void { transparentPipeline.bind(null); - c.glUniform3fv(transparentUniforms.@"fog.color", 1, @ptrCast(&game.fog.fogColor)); + const fogColor = graphics.srgbToLinear(game.fog.fogColor); + c.glUniform3fv(transparentUniforms.@"fog.color", 1, @ptrCast(&fogColor)); c.glUniform1f(transparentUniforms.@"fog.density", game.fog.density); c.glUniform1f(transparentUniforms.@"fog.fogLower", game.fog.fogLower); c.glUniform1f(transparentUniforms.@"fog.fogHigher", game.fog.fogHigher); diff --git a/src/server/terrain/biomes.zig b/src/server/terrain/biomes.zig index 5b8cfe2e6f..b476c8dca6 100644 --- a/src/server/terrain/biomes.zig +++ b/src/server/terrain/biomes.zig @@ -330,7 +330,7 @@ pub const Biome = struct { // MARK: Biome .skyColor = blk: { break :blk u32ToVec3(zon.get(?u32, "skyColor", null) orelse break :blk .{0.46, 0.7, 1.0}); }, - .fogDensity = zon.get(f32, "fogDensity", 1.0)/15.0/128.0, + .fogDensity = zon.get(f32, "fogDensity", 1.0)/15.0/128.0/2.2, .fogLower = zon.get(f32, "fogLower", 100.0), .fogHigher = zon.get(f32, "fogHigher", 1000.0), .roughness = zon.get(f32, "roughness", 0),