Merge branch 'zesterer/experimental-shaders' into 'master'

Added point glow, more experimental shaders

See merge request veloren/veloren!3118
This commit is contained in:
Imbris 2022-01-20 01:52:11 +00:00
commit 2f45f08ef4
12 changed files with 134 additions and 25 deletions

View File

@ -40,6 +40,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Players can now mount and ride pets
- Experimental shaders, that can be enabled in Voxygen's settings (see the book for more information)
- Added arthropods
- A 'point light glow' effect, making lanterns and other point lights more visually pronounced
### Changed

View File

@ -21,6 +21,9 @@
#include <anti-aliasing.glsl>
#include <srgb.glsl>
#include <cloud.glsl>
#include <light.glsl>
// This *MUST* come after `cloud.glsl`: it contains a function that depends on `cloud.glsl` when clouds are enabled
#include <point_glow.glsl>
layout(set = 1, binding = 0)
uniform texture2D t_src_color;
@ -42,7 +45,6 @@ uniform u_locals {
layout(location = 0) out vec4 tgt_color;
vec3 wpos_at(vec2 uv) {
float buf_depth = texture(sampler2D(t_src_depth, s_src_depth), uv).x;
mat4 inv = view_mat_inv * proj_mat_inv;//inverse(all_mat);
@ -60,13 +62,17 @@ vec3 wpos_at(vec2 uv) {
void main() {
vec4 color = texture(sampler2D(t_src_color, s_src_color), uv);
vec3 wpos = wpos_at(uv);
float dist = distance(wpos, cam_pos.xyz);
vec3 dir = (wpos - cam_pos.xyz) / dist;
// Apply clouds
#if (CLOUD_MODE != CLOUD_MODE_NONE)
vec3 wpos = wpos_at(uv);
float dist = distance(wpos, cam_pos.xyz);
vec3 dir = (wpos - cam_pos.xyz) / dist;
color.rgb = get_cloud_color(color.rgb, dir, cam_pos.xyz, time_of_day.x, dist, 1.0);
#else
#ifdef BLOOM_FACTOR
color.rgb = apply_point_glow(cam_pos.xyz + focus_off.xyz, dir, dist, color.rgb, BLOOM_FACTOR);
#endif
#endif
tgt_color = vec4(color.rgb, 1);

View File

@ -145,8 +145,8 @@ void main() {
nmap = mix(f_norm, normalize(nmap), min(1.0 / pow(frag_dist, 0.75), 1));
//float suppress_waves = max(dot(), 0);
vec3 norm = normalize(vec3(0, 0, 1) * nmap.z + b_norm * nmap.x + c_norm * nmap.y);
// vec3 norm = f_norm;
vec3 norm = normalize(f_norm * nmap.z + b_norm * nmap.x + c_norm * nmap.y);
//norm = f_norm;
vec3 water_color = (1.0 - MU_WATER) * MU_SCATTER;
#if (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_MAP || FLUID_MODE == FLUID_MODE_SHINY)
@ -177,7 +177,7 @@ void main() {
// Squared to account for prior saturation.
float f_light = 1.0;// pow(f_light, 1.5);
vec3 reflect_color = get_sky_color(/*reflect_ray_dir*/beam_view_dir, time_of_day.x, f_pos, vec3(-100000), 0.125, true);
reflect_color = get_cloud_color(reflect_color, reflect_ray_dir, cam_pos.xyz, time_of_day.x, 100000.0, 0.1);
reflect_color = get_cloud_color(reflect_color, reflect_ray_dir, f_pos.xyz, time_of_day.x, 100000.0, 0.1);
reflect_color *= f_light;
// Prevent the sky affecting light when underground

View File

@ -1,5 +1,6 @@
#include <constants.glsl>
#include <random.glsl>
#include <light.glsl>
#include <lod.glsl>
float falloff(float x) {
@ -200,6 +201,10 @@ float dist_to_step(float dist, float quality) {
return pow(dist / STEP_SCALE * quality, 0.5);
}
// This *MUST* go here: when clouds are enabled, it relies on the declaration of `clouds_at` above. Sadly, GLSL doesn't
// consistently support forward declarations (not surprising, it's designed for single-pass compilers).
#include <point_glow.glsl>
vec3 get_cloud_color(vec3 surf_color, vec3 dir, vec3 origin, const float time_of_day, float max_dist, const float quality) {
// Limit the marching distance to reduce maximum jumps
max_dist = min(max_dist, DIST_CAP);
@ -259,5 +264,10 @@ vec3 get_cloud_color(vec3 surf_color, vec3 dir, vec3 origin, const float time_of
emission * density_integrals.y * step;
}
// Apply point glow
#ifdef BLOOM_FACTOR
surf_color = apply_point_glow(origin, dir, max_dist, surf_color, BLOOM_FACTOR);
#endif
return surf_color;
}

View File

@ -1,3 +1,6 @@
#ifndef LIGHT_GLSL
#define LIGHT_GLSL
#include <srgb.glsl>
#include <shadows.glsl>
@ -28,6 +31,11 @@ float attenuation_strength(vec3 rpos) {
return max(2.0 / pow(d2 + 10, 0.35) - pow(d2 / 50000.0, 0.8), 0.0);
}
float attenuation_strength_real(vec3 rpos) {
float d2 = rpos.x * rpos.x + rpos.y * rpos.y + rpos.z * rpos.z;
return 1.0 / (0.025 + d2);
}
// // Compute attenuation due to light passing through a substance that fills an area below a horizontal plane
// // (e.g. in most cases, water below the water surface depth).
// //
@ -243,3 +251,5 @@ float lights_at(vec3 wpos, vec3 wnorm, vec3 /*cam_to_frag*/view_dir, vec3 mu, ve
float lights_at(vec3 wpos, vec3 wnorm, vec3 view_dir, vec3 k_a, vec3 k_d, vec3 k_s, float alpha, inout vec3 emitted_light, inout vec3 reflected_light) {
return lights_at(wpos, wnorm, view_dir, vec3(0.0), vec3(1.0), 0.0, k_a, k_d, k_s, alpha, wnorm, 1.0, emitted_light, reflected_light);
}
#endif

View File

@ -313,7 +313,18 @@ vec3 lod_norm(vec2 f_pos/*vec3 pos*/, vec4 square) {
vec3 lod_norm(vec2 f_pos/*vec3 pos*/) {
const float SAMPLE_W = 32;
return lod_norm(f_pos, vec4(f_pos - vec2(SAMPLE_W), f_pos + vec2(SAMPLE_W)));
vec3 norm = lod_norm(f_pos, vec4(f_pos - vec2(SAMPLE_W), f_pos + vec2(SAMPLE_W)));
#ifdef EXPERIMENTAL_PROCEDURALLODDETAIL
vec2 wpos = f_pos + focus_off.xy;
norm.xy += vec2(
textureLod(sampler2D(t_noise, s_noise), wpos / 200, 0).x - 0.5,
textureLod(sampler2D(t_noise, s_noise), wpos / 200 + 0.5, 0).x - 0.5
) * 0.35;
norm = normalize(norm);
#endif
return norm;
}
@ -340,11 +351,27 @@ layout(set = 0, binding = 11)
uniform sampler s_map;
vec3 lod_col(vec2 pos) {
//return vec3(0, 0.5, 0);
// return /*linear_to_srgb*/vec3(alt_at(pos), textureBicubic(t_map, pos_to_tex(pos)).gb);
return /*linear_to_srgb*/(textureBicubic(t_map, s_map, pos_to_tex(pos)).rgb)
;//+ (texture(t_noise, pos * 0.04 + texture(t_noise, pos * 0.005).xy * 2.0 + texture(t_noise, pos * 0.06).xy * 0.6).x - 0.5) * 0.1;
//+ (texture(t_noise, pos * 0.04 + texture(t_noise, pos * 0.005).xy * 2.0 + texture(t_noise, pos * 0.06).xy * 0.6).x - 0.5) * 0.1;
#ifdef EXPERIMENTAL_PROCEDURALLODDETAIL
vec2 wpos = pos + focus_off.xy;
vec2 shift = vec2(
textureLod(sampler2D(t_noise, s_noise), wpos / 200, 0).x - 0.5,
textureLod(sampler2D(t_noise, s_noise), wpos / 200 + 0.5, 0).x - 0.5
) * 64;
pos += shift;
wpos += shift;
#endif
vec3 col = textureBicubic(t_map, s_map, pos_to_tex(pos)).rgb;
#ifdef EXPERIMENTAL_PROCEDURALLODDETAIL
col *= pow(vec3(
textureLod(sampler2D(t_noise, s_noise), wpos / 40, 0).x,
textureLod(sampler2D(t_noise, s_noise), wpos / 50 + 0.5, 0).x,
textureLod(sampler2D(t_noise, s_noise), wpos / 45 + 0.75, 0).x
), vec3(0.5));
#endif
return col;
}
#endif

View File

@ -0,0 +1,43 @@
#ifndef POINT_GLOW_GLSL
#define POINT_GLOW_GLSL
vec3 apply_point_glow(vec3 wpos, vec3 dir, float max_dist, vec3 color, const float factor) {
#ifndef EXPERIMENTAL_NOPOINTGLOW
for (uint i = 0u; i < light_shadow_count.x; i ++) {
// Only access the array once
Light L = lights[i];
vec3 light_pos = L.light_pos.xyz;
// Project light_pos to dir line
float t = max(dot(light_pos - wpos, dir), 0);
vec3 nearest = wpos + dir * min(t, max_dist);
vec3 difference = light_pos - nearest;
float distance_2 = dot(difference, difference);
if (distance_2 > 100000.0) {
continue;
}
#if (CLOUD_MODE >= CLOUD_MODE_HIGH)
vec3 _unused;
float unused2;
float spread = 1.0 / (1.0 + cloud_at(nearest, 0.0, _unused, unused2).z * 0.005);
#else
const float spread = 1.0;
#endif
float strength = pow(attenuation_strength_real(difference), spread);
vec3 light_color = srgb_to_linear(L.light_col.rgb) * strength * L.light_col.a;
const float LIGHT_AMBIANCE = 0.025;
color += light_color
* 0.025
// Constant, *should* const fold
* pow(factor, 0.65);
}
#endif
return color;
}
#endif

View File

@ -5,7 +5,7 @@
),
map: {
"Green0": (
vox_spec: ("lantern.green-0", (-2.0, -2.0, -7.0)),
vox_spec: ("lantern.green-0", (-2.5, -2.0, -9.0)),
color: None
),
"Magic": (
@ -13,7 +13,7 @@
color: None
),
"Black0": (
vox_spec: ("lantern.black-0", (-2.0, -2.0, -8.5)),
vox_spec: ("lantern.black-0", (-2.5, -2.0, -8.5)),
color: None
),
"Red0": (
@ -21,7 +21,7 @@
color: None
),
"Blue0": (
vox_spec: ("lantern.blue-0", (-2.0, -2.0, -7.0)),
vox_spec: ("lantern.blue-0", (-2.5, -2.0, -8.0)),
color: None
),
"GeodePurp": (
@ -29,11 +29,11 @@
color: None
),
"PumpkinLantern": (
vox_spec: ("lantern.pumpkin", (-3.5, -4.0, -8.5)),
vox_spec: ("lantern.pumpkin", (-4.0, -4.0, -8.5)),
color: None
),
"PolarisLantern": (
vox_spec: ("lantern.polaris", (-3.0, -4.0, -9.5)),
vox_spec: ("lantern.polaris", (-3.5, -4.0, -8.5)),
color: None
),
},

View File

@ -145,7 +145,7 @@ impl Skeleton for CharacterSkeleton {
make_bone(control_mat * hand_l_mat * Mat4::<f32>::from(self.hold)),
];
Offsets {
lantern: Some((lantern_mat * Vec4::new(0.0, 0.0, -4.0, 1.0)).xyz()),
lantern: Some((lantern_mat * Vec4::new(0.0, 0.5, -6.0, 1.0)).xyz()),
// TODO: see quadruped_medium for how to animate this
mount_bone: Transform {
position: common::comp::Body::Humanoid(body)

View File

@ -280,16 +280,16 @@ pub enum BloomFactor {
}
impl Default for BloomFactor {
fn default() -> Self { Self::Low }
fn default() -> Self { Self::Medium }
}
impl BloomFactor {
/// Fraction of output image luminosity that is blurred bloom
pub fn fraction(self) -> f32 {
match self {
Self::Low => 0.05,
Self::Medium => 0.10,
Self::High => 0.25,
Self::Low => 0.1,
Self::Medium => 0.2,
Self::High => 0.3,
Self::Custom(val) => val.max(0.0).min(1.0),
}
}
@ -300,7 +300,7 @@ impl BloomFactor {
pub struct BloomConfig {
/// Controls fraction of output image luminosity that is blurred bloom
///
/// Defaults to `Low`
/// Defaults to `Medium`
pub factor: BloomFactor,
/// Turning this on make the bloom blur less sharply concentrated around the
/// high intensity phenomena (removes adding in less blurred layers to the
@ -391,6 +391,10 @@ struct OtherModes {
profiler_enabled: bool,
}
/// Experimental shader modes.
///
/// You can enable these using Voxygen's `settings.ron`. See
/// [here](https://book.veloren.net/players/voxygen.html#experimental-shaders) for more information.
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum ExperimentalShader {
/// Add brick-like normal mapping to the world.
@ -399,4 +403,9 @@ pub enum ExperimentalShader {
NoNoise,
/// Simulated a curved world.
CurvedWorld,
/// Remove the glow effect around point lights (this is *not* the same thing
/// as bloom).
NoPointGlow,
/// Adds extra detail to distant LoD (Level of Detail) terrain procedurally.
ProceduralLodDetail,
}

View File

@ -141,6 +141,7 @@ impl ShaderModules {
let random = shaders.get("include.random").unwrap();
let lod = shaders.get("include.lod").unwrap();
let shadows = shaders.get("include.shadows").unwrap();
let point_glow = shaders.get("include.point_glow").unwrap();
// We dynamically add extra configuration settings to the constants file.
let mut constants = format!(
@ -241,6 +242,7 @@ impl ShaderModules {
"lod.glsl" => lod.0.to_owned(),
"anti-aliasing.glsl" => anti_alias.0.to_owned(),
"cloud.glsl" => cloud.0.to_owned(),
"point_glow.glsl" => point_glow.0.to_owned(),
other => {
return Err(format!(
"Include {} in {} is not defined",

View File

@ -37,6 +37,7 @@ impl assets::Compound for Shaders {
"include.random",
"include.lod",
"include.shadows",
"include.point_glow",
"antialias.none",
"antialias.fxaa",
"antialias.msaa-x4",