diff --git a/assets/voxygen/shaders/figure/frag.glsl b/assets/voxygen/shaders/figure/frag.glsl index a142b4c2ab..89d8bddd2c 100644 --- a/assets/voxygen/shaders/figure/frag.glsl +++ b/assets/voxygen/shaders/figure/frag.glsl @@ -23,12 +23,13 @@ uniform u_bones { #include #include +#include out vec4 tgt_color; void main() { vec3 light = get_sun_diffuse(f_norm, time_of_day.x) + light_at(f_pos, f_norm); - vec3 surf_color = model_col.rgb * f_col * 2.0 * light; + vec3 surf_color = srgb_to_linear(model_col.rgb * f_col) * 2.0 * light; float fog_level = fog(f_pos.xy, focus_pos.xy); vec3 fog_color = get_sky_color(normalize(f_pos - cam_pos.xyz), time_of_day.x); diff --git a/assets/voxygen/shaders/include/light.glsl b/assets/voxygen/shaders/include/light.glsl index ebdc3beaec..68ad6f5e6b 100644 --- a/assets/voxygen/shaders/include/light.glsl +++ b/assets/voxygen/shaders/include/light.glsl @@ -8,6 +8,8 @@ uniform u_lights { Light lights[32]; }; +#include + float attenuation_strength(vec3 rpos) { return 1.0 / (rpos.x * rpos.x + rpos.y * rpos.y + rpos.z * rpos.z); } @@ -30,7 +32,7 @@ vec3 light_at(vec3 wpos, vec3 wnorm) { float strength = attenuation_strength(difference); // Multiply the vec3 only once - vec3 color = L.light_col.rgb * (strength * L.light_col.a); + vec3 color = srgb_to_linear(L.light_col.rgb) * (strength * L.light_col.a); // This is commented out to avoid conditional branching. See here: https://community.khronos.org/t/glsl-float-multiply-by-zero/104391 // if (max(max(color.r, color.g), color.b) < 0.002) { diff --git a/assets/voxygen/shaders/include/srgb.glsl b/assets/voxygen/shaders/include/srgb.glsl index e69de29bb2..4eaf579e17 100644 --- a/assets/voxygen/shaders/include/srgb.glsl +++ b/assets/voxygen/shaders/include/srgb.glsl @@ -0,0 +1,8 @@ +//https://gamedev.stackexchange.com/questions/92015/optimized-linear-to-srgb-glsl +vec3 srgb_to_linear(vec3 srgb) { + bvec3 cutoff = lessThan(srgb, vec3(0.04045)); + vec3 higher = pow((srgb + vec3(0.055))/vec3(1.055), vec3(2.4)); + vec3 lower = srgb/vec3(12.92); + + return mix(higher, lower, cutoff); +} \ No newline at end of file diff --git a/assets/voxygen/shaders/postprocess/frag.glsl b/assets/voxygen/shaders/postprocess/frag.glsl index 1e40bdbbb9..a9316ac993 100644 --- a/assets/voxygen/shaders/postprocess/frag.glsl +++ b/assets/voxygen/shaders/postprocess/frag.glsl @@ -170,7 +170,8 @@ void main() { hsva_color.y *= 1.45; hsva_color.z *= 0.85; //hsva_color.z = 1.0 - 1.0 / (1.0 * hsva_color.z + 1.0); - vec4 final_color = vec4(hsv2rgb(hsva_color.rgb), hsva_color.a); + vec4 final_color = fxaa_color; + //vec4 final_color = vec4(hsv2rgb(hsva_color.rgb), hsva_color.a); tgt_color = vec4(final_color.rgb, 1); } diff --git a/assets/voxygen/shaders/terrain/frag.glsl b/assets/voxygen/shaders/terrain/frag.glsl index cb0f75cf71..e565f8f48c 100644 --- a/assets/voxygen/shaders/terrain/frag.glsl +++ b/assets/voxygen/shaders/terrain/frag.glsl @@ -16,10 +16,11 @@ out vec4 tgt_color; #include #include +#include void main() { vec3 light = get_sun_diffuse(f_norm, time_of_day.x) * f_light + light_at(f_pos, f_norm); - vec3 surf_color = f_col * light; + vec3 surf_color = srgb_to_linear(f_col) * light; float fog_level = fog(f_pos.xy, focus_pos.xy); vec3 fog_color = get_sky_color(normalize(f_pos - cam_pos.xyz), time_of_day.x); diff --git a/assets/voxygen/shaders/terrain/vert.glsl b/assets/voxygen/shaders/terrain/vert.glsl index 3011d5a238..0c89e768a0 100644 --- a/assets/voxygen/shaders/terrain/vert.glsl +++ b/assets/voxygen/shaders/terrain/vert.glsl @@ -38,7 +38,7 @@ void main() { float((v_col_light >> 8) & 0xFFu), float((v_col_light >> 16) & 0xFFu), float((v_col_light >> 24) & 0xFFu) - ) / 200.0; + ) / 255.0; f_light = float(v_col_light & 0xFFu) / 255.0; diff --git a/common/Cargo.toml b/common/Cargo.toml index ee081d972c..f26fde7800 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "veloren-common" version = "0.3.0" -authors = ["Joshua Barretto ", "Maciej Ćwięka , Imbris "] +authors = ["Joshua Barretto ", "Maciej Ćwięka ", "Imbris "] edition = "2018" [dependencies] diff --git a/common/src/assets/mod.rs b/common/src/assets/mod.rs index 7f4614eb37..959d6a4483 100644 --- a/common/src/assets/mod.rs +++ b/common/src/assets/mod.rs @@ -121,7 +121,7 @@ pub fn load_watched( } let owned_specifier = specifier.to_string(); - indicator.add(specifier, move || { + indicator.add(path, move || { if let Err(err) = reload::(&owned_specifier) { error!("Error reloading {}: {:#?}", &owned_specifier, err); } diff --git a/common/src/assets/watch.rs b/common/src/assets/watch.rs index 9f117d6930..ddc675b73c 100644 --- a/common/src/assets/watch.rs +++ b/common/src/assets/watch.rs @@ -149,9 +149,6 @@ impl ReloadIndicator { self.paths.push(path.clone()); }; - let mut path = super::ASSETS_PATH.clone(); - path.push(specifier); - if WATCHER_TX .lock() .unwrap() diff --git a/common/src/util/mod.rs b/common/src/util/mod.rs index 6ab36f75c4..11e29232ac 100644 --- a/common/src/util/mod.rs +++ b/common/src/util/mod.rs @@ -1 +1,35 @@ pub const GIT_HASH: &str = include_str!(concat!(env!("OUT_DIR"), "/githash")); + +use vek::{Rgb, Rgba}; +#[inline(always)] +pub fn srgb_to_linear(col: Rgb) -> Rgb { + #[inline(always)] + fn to_linear(x: f32) -> f32 { + if x <= 0.04045 { + x / 12.92 + } else { + ((x + 0.055) / 1.055).powf(2.4) + } + } + col.map(to_linear) +} +#[inline(always)] +pub fn linear_to_srgb(col: Rgb) -> Rgb { + #[inline(always)] + fn to_srgb(x: f32) -> f32 { + if x <= 0.0031308 { + x * 12.92 + } else { + x.powf(1.0 / 2.4) * 1.055 - 0.055 + } + } + col.map(to_srgb) +} +#[inline(always)] +pub fn srgba_to_linear(col: Rgba) -> Rgba { + Rgba::from_translucent(srgb_to_linear(Rgb::from(col)), col.a) +} +#[inline(always)] +pub fn linear_to_srgba(col: Rgba) -> Rgba { + Rgba::from_translucent(linear_to_srgb(Rgb::from(col)), col.a) +} diff --git a/voxygen/Cargo.toml b/voxygen/Cargo.toml index 43c477e8dc..4d1b597034 100644 --- a/voxygen/Cargo.toml +++ b/voxygen/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "veloren-voxygen" version = "0.3.0" -authors = ["Joshua Barretto "] +authors = ["Joshua Barretto ", "Imbris "] edition = "2018" default-run = "veloren-voxygen" diff --git a/voxygen/src/mesh/segment.rs b/voxygen/src/mesh/segment.rs index 7ab8555f2c..ac1667688d 100644 --- a/voxygen/src/mesh/segment.rs +++ b/voxygen/src/mesh/segment.rs @@ -4,6 +4,7 @@ use crate::{ }; use common::{ figure::Segment, + util::{linear_to_srgb, srgb_to_linear}, vol::{ReadVol, SizedVol}, }; use vek::*; @@ -28,7 +29,12 @@ impl Meshable for Segment { offs + pos.map(|e| e as f32), col, |origin, norm, col, ao, light| { - FigureVertex::new(origin, norm, col * ao * light, 0) + FigureVertex::new( + origin, + norm, + linear_to_srgb(srgb_to_linear(col) * ao * light), + 0, + ) }, true, &[[[1.0; 3]; 3]; 3], diff --git a/voxygen/src/render/pipelines/terrain.rs b/voxygen/src/render/pipelines/terrain.rs index 03372d6461..d28aa3acbf 100644 --- a/voxygen/src/render/pipelines/terrain.rs +++ b/voxygen/src/render/pipelines/terrain.rs @@ -54,9 +54,9 @@ impl Vertex { | ((pos.z.max(0.0).min((1 << 13) as f32) as u32) & 0x1FFF) << 16 | ((norm_bits as u32) & 0x7) << 29, col_light: 0 - | ((col.r.mul(200.0) as u32) & 0xFF) << 8 - | ((col.g.mul(200.0) as u32) & 0xFF) << 16 - | ((col.b.mul(200.0) as u32) & 0xFF) << 24 + | ((col.r.mul(255.0) as u32) & 0xFF) << 8 + | ((col.g.mul(255.0) as u32) & 0xFF) << 16 + | ((col.b.mul(255.0) as u32) & 0xFF) << 24 | ((light.mul(255.0) as u32) & 0xFF) << 0, } } diff --git a/voxygen/src/render/renderer.rs b/voxygen/src/render/renderer.rs index 1bfc0210e7..fb0da068bb 100644 --- a/voxygen/src/render/renderer.rs +++ b/voxygen/src/render/renderer.rs @@ -18,7 +18,7 @@ use log::error; use vek::*; /// Represents the format of the pre-processed color target. -pub type TgtColorFmt = gfx::format::Rgba16F; +pub type TgtColorFmt = gfx::format::Srgba8; /// Represents the format of the pre-processed depth target. pub type TgtDepthFmt = gfx::format::Depth; @@ -476,11 +476,15 @@ fn create_pipelines( let light = assets::load_watched::("voxygen.shaders.include.light", shader_reload_indicator) .unwrap(); + let srgb = + assets::load_watched::("voxygen.shaders.include.srgb", shader_reload_indicator) + .unwrap(); let mut include_ctx = IncludeContext::new(); include_ctx.include("globals.glsl", &globals); include_ctx.include("sky.glsl", &sky); include_ctx.include("light.glsl", &light); + include_ctx.include("srgb.glsl", &srgb); // Construct a pipeline for rendering skyboxes let skybox_pipeline = create_pipeline( diff --git a/voxygen/src/ui/graphic/renderer.rs b/voxygen/src/ui/graphic/renderer.rs index 06efe2d609..0542d8b268 100644 --- a/voxygen/src/ui/graphic/renderer.rs +++ b/voxygen/src/ui/graphic/renderer.rs @@ -1,6 +1,6 @@ -use super::super::{linear_to_srgb, srgb_to_linear}; use common::{ figure::Segment, + util::{linear_to_srgba, srgba_to_linear}, vol::{ReadVol, SizedVol, Vox}, }; use euc::{buffer::Buffer2d, rasterizer, Pipeline}; @@ -46,13 +46,13 @@ impl<'a> Pipeline for Voxel { }: &Self::Vertex, ) -> ([f32; 3], Self::VsOut) { let light = Rgba::from_opaque(Rgb::from(*ao_level as f32 / 4.0 + 0.25)); - let color = light * srgb_to_linear(Rgba::from_opaque(*col)); + let color = light * srgba_to_linear(Rgba::from_opaque(*col)); let position = Vec3::from(self.mvp * Vec4::from_point(*pos)).into_array(); (position, color) } #[inline(always)] fn frag(&self, color: &Self::VsOut) -> Self::Pixel { - linear_to_srgb(*color) + linear_to_srgba(*color) .map(|e| (e * 255.0) as u8) .into_array() } diff --git a/voxygen/src/ui/mod.rs b/voxygen/src/ui/mod.rs index 8e9125eb03..d61c2c5006 100644 --- a/voxygen/src/ui/mod.rs +++ b/voxygen/src/ui/mod.rs @@ -2,7 +2,6 @@ mod cache; mod event; mod graphic; mod scale; -mod util; mod widgets; #[macro_use] pub mod img_ids; @@ -28,7 +27,7 @@ use crate::{ Error, }; use cache::Cache; -use common::assets; +use common::{assets, util::srgba_to_linear}; use conrod_core::{ event::Input, graph::Graph, @@ -48,7 +47,6 @@ use std::{ sync::Arc, time::Duration, }; -use util::{linear_to_srgb, srgb_to_linear}; use vek::*; use widgets::tooltip::TooltipManager; @@ -406,7 +404,7 @@ impl Ui { } let color = - srgb_to_linear(color.unwrap_or(conrod_core::color::WHITE).to_fsa().into()); + srgba_to_linear(color.unwrap_or(conrod_core::color::WHITE).to_fsa().into()); let resolution = Vec2::new( (rect.w() * p_scale_factor).round() as u16, @@ -485,7 +483,7 @@ impl Ui { }) .unwrap(); - let color = srgb_to_linear(color.to_fsa().into()); + let color = srgba_to_linear(color.to_fsa().into()); for g in positioned_glyphs { if let Ok(Some((uv_rect, screen_rect))) = @@ -514,7 +512,7 @@ impl Ui { } } PrimitiveKind::Rectangle { color } => { - let color = srgb_to_linear(color.to_fsa().into()); + let color = srgba_to_linear(color.to_fsa().into()); // Don't draw a transparent rectangle. if color[3] == 0.0 { continue; @@ -534,7 +532,7 @@ impl Ui { } PrimitiveKind::TrianglesSingleColor { color, triangles } => { // Don't draw transparent triangle or switch state if there are actually no triangles. - let color = srgb_to_linear(Rgba::from(Into::<[f32; 4]>::into(color))); + let color = srgba_to_linear(Rgba::from(Into::<[f32; 4]>::into(color))); if triangles.is_empty() || color[3] == 0.0 { continue; } diff --git a/voxygen/src/ui/util.rs b/voxygen/src/ui/util.rs deleted file mode 100644 index 6359ddd8dd..0000000000 --- a/voxygen/src/ui/util.rs +++ /dev/null @@ -1,36 +0,0 @@ -use vek::*; - -#[inline(always)] -pub fn srgb_to_linear(c: Rgba) -> Rgba { - #[inline(always)] - fn to_linear(x: f32) -> f32 { - if x <= 0.04045 { - x / 12.92 - } else { - ((x + 0.055) / 1.055).powf(2.4) - } - } - Rgba { - r: to_linear(c.r), - g: to_linear(c.g), - b: to_linear(c.b), - a: c.a, - } -} -#[inline(always)] -pub fn linear_to_srgb(c: Rgba) -> Rgba { - #[inline(always)] - fn to_srgb(x: f32) -> f32 { - if x <= 0.0031308 { - x * 12.92 - } else { - x.powf(1.0 / 2.4) * 1.055 - 0.055 - } - } - Rgba { - r: to_srgb(c.r), - g: to_srgb(c.g), - b: to_srgb(c.b), - a: c.a, - } -} diff --git a/world/src/block/mod.rs b/world/src/block/mod.rs index 42c4b010c3..3a010570c1 100644 --- a/world/src/block/mod.rs +++ b/world/src/block/mod.rs @@ -7,6 +7,7 @@ use crate::{ }; use common::{ terrain::{structure::StructureBlock, Block, Structure}, + util::linear_to_srgb, vol::{ReadVol, Vox}, }; use noise::NoiseFn; @@ -208,7 +209,8 @@ impl<'a> BlockGen<'a> { // Sample blocks - let stone_col = Rgb::new(240, 230, 220); + // let stone_col = Rgb::new(240, 230, 220); + let stone_col = Rgb::new(248, 243, 239); // let dirt_col = Rgb::new(79, 67, 60); let air = Block::empty(); @@ -217,12 +219,13 @@ impl<'a> BlockGen<'a> { // let dirt = Block::new(1, dirt_col); // let sand = Block::new(1, Rgb::new(180, 150, 50)); // let warm_stone = Block::new(1, Rgb::new(165, 165, 130)); - let water = Block::new(1, Rgb::new(100, 150, 255)); + // let water = Block::new(1, Rgb::new(100, 150, 255)); + let water = Block::new(1, Rgb::new(168, 202, 255)); let grass_depth = 1.5 + 2.0 * chaos; let block = if (wposf.z as f32) < height - grass_depth { let col = Lerp::lerp( - sub_surface_color.map(|e| (e * 255.0) as u8), + linear_to_srgb(sub_surface_color).map(|e| (e * 255.0) as u8), stone_col, (height - grass_depth - wposf.z as f32) * 0.15, ); @@ -242,7 +245,10 @@ impl<'a> BlockGen<'a> { .powf(0.5), ); // Surface - Some(Block::new(1, col.map(|e| (e * 255.0) as u8))) + Some(Block::new( + 1, + linear_to_srgb(col).map(|e| (e * 255.0) as u8), + )) } else if (wposf.z as f32) < water_height { // Ocean Some(water) @@ -279,9 +285,9 @@ impl<'a> BlockGen<'a> { 1, stone_col - Rgb::new( - field0.get(wpos) as u8 % 32, - field1.get(wpos) as u8 % 32, - field2.get(wpos) as u8 % 32, + field0.get(wpos) as u8 % 16, + field1.get(wpos) as u8 % 16, + field2.get(wpos) as u8 % 16, ), )) } else { @@ -407,7 +413,7 @@ impl StructureInfo { .map(|e: i32| (e.abs() / 2) * 2) .reduce_max() { - Some(Block::new(2, Rgb::new(180, 140, 90))) + Some(Block::new(2, Rgb::new(219, 196, 160))) } else { None } @@ -445,19 +451,27 @@ fn block_from_structure( match sblock { StructureBlock::TemperateLeaves => Some(Block::new( 1, - Lerp::lerp(Rgb::new(0.0, 70.0, 35.0), Rgb::new(100.0, 140.0, 0.0), lerp) - .map(|e| e as u8), + Lerp::lerp( + Rgb::new(0.00, 143.0, 103.6), + Rgb::new(168.1, 195.5, 0.0), + lerp, + ) + .map(|e| e as u8), )), StructureBlock::PineLeaves => Some(Block::new( 1, - Lerp::lerp(Rgb::new(0.0, 60.0, 50.0), Rgb::new(30.0, 100.0, 10.0), lerp) - .map(|e| e as u8), + Lerp::lerp( + Rgb::new(0.00, 133.2, 122.4), + Rgb::new(96.3, 168.1, 55.8), + lerp, + ) + .map(|e| e as u8), )), StructureBlock::PalmLeaves => Some(Block::new( 1, Lerp::lerp( - Rgb::new(15.0, 100.0, 30.0), - Rgb::new(55.0, 220.0, 0.0), + Rgb::new(68.6, 168.1, 96.3), + Rgb::new(128.0, 239.0, 0.00), lerp, ) .map(|e| e as u8), @@ -465,16 +479,20 @@ fn block_from_structure( StructureBlock::Acacia => Some(Block::new( 1, Lerp::lerp( - Rgb::new(35.0, 100.0, 10.0), - Rgb::new(70.0, 190.0, 25.0), + Rgb::new(103.6, 168.1, 55.8), + Rgb::new(143.0, 224.0, 88.2), lerp, ) .map(|e| e as u8), )), StructureBlock::Fruit => Some(Block::new( 1, - Lerp::lerp(Rgb::new(255.0, 0.0, 0.0), Rgb::new(200.0, 255.0, 6.0), lerp) - .map(|e| e as u8), + Lerp::lerp( + Rgb::new(255.0, 0.0, 0.0), + Rgb::new(229.1, 255.0, 42.4), + lerp, + ) + .map(|e| e as u8), )), StructureBlock::Hollow => Some(Block::empty()), StructureBlock::Block(block) => Some(block).filter(|block| !block.is_empty()),