Merge branch 'zesterer/mini-fixes' into 'master'

Moving water, SSR, water shader fixes, camera fixes

See merge request veloren/veloren!3637
This commit is contained in:
Joshua Barretto 2022-10-23 23:19:38 +00:00
commit 588ccd84ed
42 changed files with 738 additions and 317 deletions

View File

@ -25,6 +25,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Pets can now be traded with.
- Crafting recipe for black lantern
- Added redwood and dead trees
- Water will now move according to its apparent flow direction
- Added screen-space reflection and refraction shaders
- Added reflection quality setting
### Changed
- Use fluent for translations
@ -60,6 +63,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Pets no longer aggro on pet owners after being healed
- Pets no longer lose their intrinsic weapons/armour when loaded on login.
- Fixed npcs using `/say` instead of `/tell`
- Camera jittering in third person has been significantly reduced
- Many water shader issues have been fixed
## [0.13.0] - 2022-07-23

View File

@ -72,8 +72,13 @@ hud-settings-antialiasing_mode = AntiAliasing Mode
hud-settings-upscale_factor = Internal Resolution
hud-settings-cloud_rendering_mode = Cloud Rendering Mode
hud-settings-fluid_rendering_mode = Fluid Rendering Mode
hud-settings-fluid_rendering_mode-cheap = Cheap
hud-settings-fluid_rendering_mode-shiny = Shiny
hud-settings-fluid_rendering_mode-low = Low
hud-settings-fluid_rendering_mode-medium = Medium
hud-settings-fluid_rendering_mode-high = High
hud-settings-reflection_rendering_mode = Reflection Rendering Mode
hud-settings-reflection_rendering_mode-low = Low
hud-settings-reflection_rendering_mode-medium = Medium
hud-settings-reflection_rendering_mode-high = High
hud-settings-cloud_rendering_mode-minimal = Minimal
hud-settings-cloud_rendering_mode-low = Low
hud-settings-cloud_rendering_mode-medium = Medium
@ -93,7 +98,7 @@ hud-settings-resolution = Resolution
hud-settings-bit_depth = Bit Depth
hud-settings-refresh_rate = Refresh Rate
hud-settings-lighting_rendering_mode = Lighting Rendering Mode
hud-settings-lighting_rendering_mode-ashikhmin = Type A - High
hud-settings-lighting_rendering_mode-ashikhmin = Type A - High
hud-settings-lighting_rendering_mode-blinnphong = Type B - Medium
hud-settings-lighting_rendering_mode-lambertian = Type L - Cheap
hud-settings-shadow_rendering_mode = Shadow Rendering Mode

View File

@ -6,9 +6,9 @@
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_SPECULAR
#if (FLUID_MODE == FLUID_MODE_CHEAP)
#if (FLUID_MODE == FLUID_MODE_LOW)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
#elif (FLUID_MODE == FLUID_MODE_SHINY)
#elif (FLUID_MODE >= FLUID_MODE_MEDIUM)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
#endif
@ -27,6 +27,7 @@
#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>
#include <random.glsl>
layout(set = 2, binding = 0)
uniform texture2D t_src_color;
@ -48,7 +49,9 @@ 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;
uvec2 sz = textureSize(sampler2D(t_src_depth, s_src_depth), 0);
float buf_depth = texelFetch(sampler2D(t_src_depth, s_src_depth), clamp(ivec2(uv * sz), ivec2(0), ivec2(sz) - 1), 0).x;
//float buf_depth = texture(sampler2D(t_src_depth, s_src_depth), uv).x;
vec4 clip_space = vec4((uv * 2.0 - 1.0) * vec2(1, -1), buf_depth, 1.0);
vec4 view_space = all_mat_inv * clip_space;
view_space /= view_space.w;
@ -60,6 +63,19 @@ vec3 wpos_at(vec2 uv) {
}
}
float depth_at(vec2 uv) {
uvec2 sz = textureSize(sampler2D(t_src_depth, s_src_depth), 0);
float buf_depth = texelFetch(sampler2D(t_src_depth, s_src_depth), clamp(ivec2(uv * sz), ivec2(0), ivec2(sz) - 1), 0).x;
if (buf_depth == 0.0) {
return 524288.0;
} else {
vec4 clip_space = vec4((uv * 2.0 - 1.0) * vec2(1, -1), buf_depth, 1.0);
vec4 view_space = all_mat_inv * clip_space;
view_space /= view_space.w;
return -(view_mat * view_space).z;
}
}
void main() {
vec4 color = texture(sampler2D(t_src_color, s_src_color), uv);
@ -70,13 +86,113 @@ void main() {
vec3 wpos = wpos_at(uv);
float dist = distance(wpos, cam_pos.xyz);
vec3 dir = (wpos - cam_pos.xyz) / dist;
vec3 cam_dir = (wpos - cam_pos.xyz) / dist;
vec3 dir = cam_dir;
// Apply clouds
float cloud_blend = 1.0;
if (color.a < 1.0) {
cloud_blend = 1.0 - color.a;
dist = DIST_CAP;
vec2 nz = vec2(0);
uvec2 col_sz = textureSize(sampler2D(t_src_color, s_src_color), 0);
#if (REFLECTION_MODE >= REFLECTION_MODE_MEDIUM)
nz = (vec2(
noise_3d(vec3((wpos.xy + focus_off.xy) * 0.1, tick.x * 0.2 + wpos.x * 0.01)).x,
noise_3d(vec3((wpos.yx + focus_off.yx) * 0.1, tick.x * 0.2 + wpos.y * 0.01)).x
) - 0.5) * (dir.z < 0.0 ? color.a : 1.0);
const float n2 = 1.3325;
vec3 refr_dir;
// TODO: Proper refraction
// if (medium.x == MEDIUM_WATER) {
// vec3 surf_norm = normalize(vec3(nz * 0.03 / (1.0 + dist * 0.1), 1));
// refr_dir = refract(dir, surf_norm * -sign(dir.z), 1.0 / n2);
// } else {
refr_dir = normalize(dir + vec3(nz * 1.5 / dist, 0.0));
// }
vec4 clip = (all_mat * vec4(cam_pos.xyz + refr_dir, 1.0));
vec2 new_uv = (clip.xy / max(clip.w, 0)) * 0.5 * vec2(1, -1) + 0.5;
float uv_merge = clamp((1.0 - abs(new_uv.y - 0.5) * 2) * 5.0, 0, 1);
new_uv = mix(uv, new_uv, uv_merge);
vec4 new_col = texelFetch(sampler2D(t_src_color, s_src_color), clamp(ivec2(new_uv * col_sz), ivec2(0), ivec2(col_sz) - 1), 0);
if (new_col.a < 1.0) {
color = new_col;
dir = refr_dir;
}
#endif
{
cloud_blend = 1.0 - color.a;
#if (FLUID_MODE >= FLUID_MODE_MEDIUM || REFLECTION_MODE >= REFLECTION_MODE_MEDIUM)
if (dir.z < 0.0) {
vec3 surf_norm = normalize(vec3(nz * 0.3 / (1.0 + dist * 0.1), 1));
vec3 refl_dir = reflect(dir, surf_norm);
vec4 clip = (all_mat * vec4(cam_pos.xyz + refl_dir, 1.0));
vec2 new_uv = (clip.xy / max(clip.w, 0)) * 0.5 * vec2(1, -1) + 0.5;
#if (REFLECTION_MODE >= REFLECTION_MODE_HIGH)
vec3 ray_end = wpos + refl_dir * 5.0 * dist;
// Trace through the screen-space depth buffer to find the ray intersection
const int MAIN_ITERS = 64;
for (int i = 0; i < MAIN_ITERS; i ++) {
float t = float(i) / float(MAIN_ITERS);
// TODO: Trace in screen space, not world space
vec3 swpos = mix(wpos, ray_end, t);
vec3 svpos = (view_mat * vec4(swpos, 1)).xyz;
vec4 clippos = proj_mat * vec4(svpos, 1);
vec2 suv = (clippos.xy / clippos.w) * 0.5 * vec2(1, -1) + 0.5;
float d = -depth_at(suv);
if (d < svpos.z * 0.8 && d > svpos.z * 0.999) {
// Don't cast into water!
if (texelFetch(sampler2D(t_src_color, s_src_color), clamp(ivec2(suv * col_sz), ivec2(0), ivec2(col_sz) - 1), 0).a >= 1.0) {
/* t -= 1.0 / float(MAIN_ITERS); */
// Do a bit of extra iteration to try to refine the estimate
const int ITERS = 8;
float diff = 1.0 / float(MAIN_ITERS);
for (int i = 0; i < ITERS; i ++) {
vec3 swpos = mix(wpos, ray_end, t);
svpos = (view_mat * vec4(swpos, 1)).xyz;
vec4 clippos = proj_mat * vec4(svpos, 1);
suv = (clippos.xy / clippos.w) * 0.5 * vec2(1, -1) + 0.5;
float d = -depth_at(suv);
t += ((d > svpos.z * 0.999) ? -1.0 : 1.0) * diff;
diff *= 0.5;
}
// Small offset to push us into obscured territory
new_uv = suv - vec2(0, 0.001);
break;
}
}
}
#endif
new_uv = clamp(new_uv, vec2(0), vec2(1));
vec3 new_wpos = wpos_at(new_uv);
float new_dist = distance(new_wpos, cam_pos.xyz);
float merge = min(
// Off-screen merge factor
clamp((1.0 - abs(new_uv.y - 0.5) * 2) * 3.0, 0, 1),
// Depth merge factor
clamp((new_dist - dist * 0.5) / (dist * 0.5), 0.0, 1.0)
);
if (merge > 0.0) {
vec3 new_col = texelFetch(sampler2D(t_src_color, s_src_color), clamp(ivec2(new_uv * col_sz), ivec2(0), ivec2(col_sz) - 1), 0).rgb;
new_col = get_cloud_color(new_col.rgb, refl_dir, wpos, time_of_day.x, distance(new_wpos, wpos.xyz), 1.0);
color.rgb = mix(color.rgb, new_col, min(merge * (color.a * 2.0), 0.75));
}
cloud_blend = 1;
} else {
#else
{
#endif
cloud_blend = 1;
}
}
}
color.rgb = mix(color.rgb, get_cloud_color(color.rgb, dir, cam_pos.xyz, time_of_day.x, dist, 1.0), cloud_blend);
@ -86,7 +202,7 @@ void main() {
if (medium.x == MEDIUM_AIR && rain_density > 0.001) {
vec3 cam_wpos = cam_pos.xyz + focus_off.xyz;
vec3 adjusted_dir = (vec4(dir, 0) * rain_dir_mat).xyz;
vec3 adjusted_dir = (vec4(cam_dir, 0) * rain_dir_mat).xyz;
vec2 dir2d = adjusted_dir.xy;
vec3 rorigin = cam_pos.xyz + focus_off.xyz + 0.5;

View File

@ -6,9 +6,9 @@
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_SPECULAR
#if (FLUID_MODE == FLUID_MODE_CHEAP)
#if (FLUID_MODE == FLUID_MODE_LOW)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
#elif (FLUID_MODE == FLUID_MODE_SHINY)
#elif (FLUID_MODE >= FLUID_MODE_MEDIUM)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
#endif

View File

@ -8,9 +8,9 @@
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_GLOSSY
#if (FLUID_MODE == FLUID_MODE_CHEAP)
#if (FLUID_MODE == FLUID_MODE_LOW)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
#elif (FLUID_MODE == FLUID_MODE_SHINY)
#elif (FLUID_MODE >= FLUID_MODE_MEDIUM)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
#endif
@ -32,6 +32,8 @@ layout(location = 0) in vec3 f_pos;
// flat in uint f_pos_norm;
layout(location = 1) flat in vec3 f_norm;
/*centroid */layout(location = 2) in vec2 f_uv_pos;
layout(location = 3) in vec3 m_pos;
layout(location = 4) in float scale;
// in float f_alt;
// in vec4 f_shadow;
// in vec3 light_pos[2];
@ -135,9 +137,9 @@ void main() {
// float moon_light = get_moon_brightness(moon_dir);
/* float sun_shade_frac = horizon_at(f_pos, sun_dir);
float moon_shade_frac = horizon_at(f_pos, moon_dir); */
#if (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_MAP || FLUID_MODE == FLUID_MODE_SHINY)
#if (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_MAP || FLUID_MODE >= FLUID_MODE_MEDIUM)
float f_alt = alt_at(f_pos.xy);
#elif (SHADOW_MODE == SHADOW_MODE_NONE || FLUID_MODE == FLUID_MODE_CHEAP)
#elif (SHADOW_MODE == SHADOW_MODE_NONE || FLUID_MODE == FLUID_MODE_LOW)
float f_alt = f_pos.z;
#endif
@ -161,7 +163,24 @@ void main() {
DirectionalLight sun_info = get_sun_info(sun_dir, point_shadow * sun_shade_frac, /*sun_pos*/f_pos);
DirectionalLight moon_info = get_moon_info(moon_dir, point_shadow * moon_shade_frac/*, light_pos*/);
vec3 surf_color = /*srgb_to_linear*/f_col;
vec3 surf_color;
// If the figure is large enough to be 'terrain-like', we apply a noise effect to it
#ifndef EXPERIMENTAL_NONOISE
if (scale >= 0.5) {
float noise = hash(vec4(floor(m_pos * 3.0 - f_norm * 0.5), 0));
const float A = 0.055;
const float W_INV = 1 / (1 + A);
const float W_2 = W_INV * W_INV;
const float NOISE_FACTOR = 0.015;
vec3 noise_delta = (sqrt(f_col) * W_INV + noise * NOISE_FACTOR);
surf_color = noise_delta * noise_delta * W_2;
} else
#endif
{
surf_color = f_col;
}
float alpha = 1.0;
const float n2 = 1.5;
@ -206,7 +225,7 @@ void main() {
vec3 cam_attenuation = vec3(1);
float fluid_alt = max(f_pos.z + 1, floor(f_alt + 1));
vec3 mu = medium.x == MEDIUM_WATER ? MU_WATER : vec3(0.0);
#if (FLUID_MODE == FLUID_MODE_SHINY)
#if (FLUID_MODE >= FLUID_MODE_MEDIUM)
cam_attenuation =
medium.x == MEDIUM_WATER ? compute_attenuation_point(cam_pos.xyz, view_dir, mu, fluid_alt, /*cam_pos.z <= fluid_alt ? cam_pos.xyz : f_pos*/f_pos)
: compute_attenuation_point(f_pos, -view_dir, mu, fluid_alt, /*cam_pos.z <= fluid_alt ? cam_pos.xyz : f_pos*/cam_pos.xyz);

View File

@ -70,6 +70,8 @@ layout(location = 0) out vec3 f_pos;
layout(location = 1) flat out vec3 f_norm;
// float dummy;
/*centroid */layout(location = 2) out vec2 f_uv_pos;
layout(location = 3) out vec3 m_pos;
layout(location = 4) out float scale;
// out vec3 f_col;
// out float f_ao;
// out float f_alt;
@ -90,6 +92,9 @@ void main() {
// vec4 bone_pos = bones[bone_idx].bone_mat * vec4(pos, 1);
m_pos = pos;
scale = length(bones[bone_idx].bone_mat[0]);
f_pos = (
bones[bone_idx].bone_mat *
vec4(pos, 1.0)

View File

@ -6,9 +6,9 @@
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_SPECULAR
#if (FLUID_MODE == FLUID_MODE_CHEAP)
#if (FLUID_MODE == FLUID_MODE_LOW)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
#elif (FLUID_MODE == FLUID_MODE_SHINY)
#elif (FLUID_MODE >= FLUID_MODE_MEDIUM)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
#endif
@ -23,6 +23,7 @@
layout(location = 0) in vec3 f_pos;
layout(location = 1) flat in uint f_pos_norm;
layout(location = 2) in vec2 f_vel;
// in vec3 f_col;
// in float f_light;
// in vec3 light_pos[2];
@ -50,6 +51,29 @@ layout(location = 0) out vec4 tgt_color;
#include <light.glsl>
#include <lod.glsl>
vec4 water_col(vec4 posx, vec4 posy) {
posx = (posx + focus_off.x) * 0.1;
posy = (posy + focus_off.y) * 0.1;
return 0.5 + (vec4(
textureLod(sampler2D(t_noise, s_noise), vec2(posx.x, posy.x), 0).x,
textureLod(sampler2D(t_noise, s_noise), vec2(posx.y, posy.y), 0).x,
textureLod(sampler2D(t_noise, s_noise), vec2(posx.z, posy.z), 0).x,
textureLod(sampler2D(t_noise, s_noise), vec2(posx.w, posy.w), 0).x
) - 0.5) * 1.0;
}
float water_col_vel(vec2 pos){
vec4 cols = water_col(
pos.x - tick.x * floor(f_vel.x) - vec2(0.0, tick.x).xyxy,
pos.y - tick.x * floor(f_vel.y) - vec2(0.0, tick.x).xxyy
);
return mix(
mix(cols.x, cols.y, fract(f_vel.x + 1.0)),
mix(cols.z, cols.w, fract(f_vel.x + 1.0)),
fract(f_vel.y + 1.0)
);
}
void main() {
#ifdef EXPERIMENTAL_BAREMINIMUM
tgt_color = vec4(simple_lighting(f_pos.xyz, MU_SCATTER, 1.0), 0.5);
@ -83,14 +107,15 @@ void main() {
// vec3 view_dir = normalize(-vec3(vert_pos4)/* / vert_pos4.w*/);
vec3 view_dir = -cam_to_frag;
// vec3 surf_color = /*srgb_to_linear*/(vec3(0.4, 0.7, 2.0));
/*const */vec3 water_color = (1.0 - MU_WATER) * MU_SCATTER;//srgb_to_linear(vec3(0.2, 0.5, 1.0));
// /*const */vec3 water_color = srgb_to_linear(vec3(0.0, 0.25, 0.5));
float water_shade = water_col_vel(f_pos.xy);
vec3 water_color = (1.0 - mix(MU_WATER, pow(vec3(0.8, 0.9, 0.08), vec3(0.25)), water_shade)) * MU_SCATTER;
/* vec3 sun_dir = get_sun_dir(time_of_day.x);
vec3 moon_dir = get_moon_dir(time_of_day.x); */
#if (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_MAP || FLUID_MODE == FLUID_MODE_SHINY)
#if (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_MAP || FLUID_MODE >= FLUID_MODE_MEDIUM)
float f_alt = alt_at(f_pos.xy);
#elif (SHADOW_MODE == SHADOW_MODE_NONE || FLUID_MODE == FLUID_MODE_CHEAP)
#elif (SHADOW_MODE == SHADOW_MODE_NONE || FLUID_MODE == FLUID_MODE_LOW)
float f_alt = f_pos.z;
#endif
@ -134,10 +159,18 @@ void main() {
vec3 k_d = vec3(1.0);
vec3 k_s = vec3(R_s);
vec3 reflect_ray_dir = reflect(cam_to_frag, f_norm);
vec3 reflect_color = vec3(0.0);
#if (REFLECTION_MODE >= REFLECTION_MODE_MEDIUM)
reflect_color = get_sky_color(reflect_ray_dir, time_of_day.x, f_pos, vec3(-100000), 0.125, true, 1.0, true, sun_shade_frac);
#endif
vec3 emitted_light, reflected_light;
// Prevent the sky affecting light when underground
float not_underground = clamp((f_pos.z - f_alt) / 128.0 + 1.0, 0.0, 1.0);
reflect_color *= not_underground;
// float point_shadow = shadow_at(f_pos, f_norm);
// vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz);
@ -191,15 +224,18 @@ void main() {
// float reflected_light_point = /*length*/(diffuse_light_point.r) + f_light * point_shadow;
// reflected_light += k_d * (diffuse_light_point + f_light * point_shadow * shade_frac) + specular_light_point;
float passthrough = max(dot(f_norm, -cam_to_frag), 0) * 0.75;
float passthrough = max(dot(cam_norm, -cam_to_frag), 0);
float min_refl = 0.0;
if (medium.x != MEDIUM_WATER) {
min_refl = min(emitted_light.r, min(emitted_light.g, emitted_light.b));
float opacity = (1.0 - passthrough) * 1.0 / (1.0 + min_refl);
if (medium.x == MEDIUM_WATER) {
// Hack to make the transparency of the surface fade when underwater to avoid artifacts
opacity = min(sqrt(max(opacity, clamp((f_pos.z - cam_pos.z) * 0.05, 0.0, 1.0))), 0.99);
}
vec3 surf_color = illuminate(max_light, view_dir, water_color * /* fog_color * */emitted_light, /*surf_color * */water_color * reflected_light);
vec3 surf_color = illuminate(max_light, view_dir, water_color * /* fog_color * */emitted_light, /*surf_color * */reflect_color * water_shade + water_color * reflected_light);
// vec4 color = vec4(surf_color, passthrough * 1.0 / (1.0 + min_refl));// * (1.0 - /*log(1.0 + cam_attenuation)*//*cam_attenuation*/1.0 / (2.0 - log_cam)));
vec4 color = vec4(surf_color, (1.0 - passthrough) * 1.0 / (1.0 + min_refl));
vec4 color = vec4(surf_color, opacity);
tgt_color = color;
}

View File

@ -6,9 +6,9 @@
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_SPECULAR
#if (FLUID_MODE == FLUID_MODE_CHEAP)
#if (FLUID_MODE == FLUID_MODE_LOW)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
#elif (FLUID_MODE == FLUID_MODE_SHINY)
#elif (FLUID_MODE >= FLUID_MODE_MEDIUM)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
#endif
@ -25,6 +25,7 @@
layout(location = 0) in vec3 f_pos;
layout(location = 1) flat in uint f_pos_norm;
layout(location = 2) in vec2 f_vel;
// in vec3 f_col;
// in float f_light;
// in vec3 light_pos[2];
@ -52,35 +53,72 @@ layout(location = 0) out vec4 tgt_color;
#include <light.glsl>
#include <lod.glsl>
vec2 wavedx(vec2 position, vec2 direction, float speed, float frequency, float timeshift) {
float x = dot(direction, position) * frequency + timeshift * speed;
float wave = pow(sin(x) + 0.5, 2);
float dx = wave * cos(x);
return vec2(wave, -dx);
void wave_dx(vec4 posx, vec4 posy, vec2 dir, float speed, float frequency, float timeshift, out vec4 wave, out vec4 dx) {
vec4 x = vec4(
dot(dir, vec2(posx.x, posy.x)),
dot(dir, vec2(posx.y, posy.y)),
dot(dir, vec2(posx.z, posy.z)),
dot(dir, vec2(posx.w, posy.w))
) * frequency + timeshift * speed;
wave = sin(x) + 0.5;
wave *= wave;
dx = -wave * cos(x);
}
// Based on https://www.shadertoy.com/view/MdXyzX
float wave_height(vec3 pos){
pos *= 0.3;
// Based loosely on https://www.shadertoy.com/view/MdXyzX.
// Modified to allow calculating the wave function 4 times at once using different positions (used for intepolation
// for moving water). The general idea is to sample the wave function at different positions, where those positions
// depend on increments of the velocity, and then interpolate between those velocities to get a smooth water velocity.
vec4 wave_height(vec4 posx, vec4 posy) {
float iter = 0.0;
float phase = 6.0;
float speed = 2.0;
float weight = 1.0;
float w = 0.0;
float phase = 4.0;
float weight = 1.5;
vec4 w = vec4(0.0);
float ws = 0.0;
const float drag_factor = 0.048;
for(int i = 0; i < 11; i ++){
const float speed_per_iter = 0.1;
#if (FLUID_MODE == FLUID_MODE_HIGH)
float speed = 1.0;
posx *= 0.2;
posy *= 0.2;
const float drag_factor = 0.035;
const int iters = 21;
const float scale = 25.0;
#else
float speed = 2.0;
posx *= 0.3;
posy *= 0.3;
const float drag_factor = 0.04;
const int iters = 11;
const float scale = 5.0;
#endif
const float iter_shift = (3.14159 * 2.0) / 7.3;
for(int i = 0; i < iters; i ++) {
vec2 p = vec2(sin(iter), cos(iter));
vec2 res = wavedx(pos.xy, p, speed, phase, tick.x);
pos.xy += p * res.y * weight * drag_factor;
w += res.x * weight;
iter += 10.0;
vec4 wave, dx;
wave_dx(posx, posy, p, speed, phase, tick.x, wave, dx);
posx += p.x * dx * weight * drag_factor;
posy += p.y * dx * weight * drag_factor;
w += wave * weight;
iter += iter_shift * 1.5;
ws += weight;
weight = mix(weight, 0.0, 0.15);
phase *= 1.18;
speed *= 1.07;
weight = mix(weight, 0.0, 0.2);
phase *= 1.2;
speed += speed_per_iter;
}
return w / ws * 10.0;
return w / ws * scale;
}
float wave_height_vel(vec2 pos) {
vec4 heights = wave_height(
pos.x - tick.x * floor(f_vel.x) - vec2(0.0, tick.x).xyxy,
pos.y - tick.x * floor(f_vel.y) - vec2(0.0, tick.x).xxyy
);
return mix(
mix(heights.x, heights.y, fract(f_vel.x + 1.0)),
mix(heights.z, heights.w, fract(f_vel.x + 1.0)),
fract(f_vel.y + 1.0)
);
}
void main() {
@ -127,11 +165,11 @@ void main() {
}
vec3 c_norm = cross(f_norm, b_norm);
vec3 wave_pos = mod(f_pos + focus_off.xyz, vec3(3000.0));
float wave_sample_dist = 0.025;
float wave00 = wave_height(wave_pos);
float wave10 = wave_height(wave_pos + vec3(wave_sample_dist, 0, 0));
float wave01 = wave_height(wave_pos + vec3(0, wave_sample_dist, 0));
vec3 wave_pos = mod(f_pos + focus_off.xyz, vec3(3000.0)) - (f_pos.z + focus_off.z) * 0.2;
float wave_sample_dist = 0.1;
float wave00 = wave_height_vel(wave_pos.xy);
float wave10 = wave_height_vel(wave_pos.xy + vec2(wave_sample_dist, 0));
float wave01 = wave_height_vel(wave_pos.xy + vec2(0, wave_sample_dist));
// Possibility of div by zero when slope = 0,
// however this only results in no water surface appearing
@ -175,9 +213,9 @@ void main() {
//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)
#if (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_MAP || FLUID_MODE >= FLUID_MODE_MEDIUM)
float f_alt = alt_at(f_pos.xy);
#elif (SHADOW_MODE == SHADOW_MODE_NONE || FLUID_MODE == FLUID_MODE_CHEAP)
#elif (SHADOW_MODE == SHADOW_MODE_NONE || FLUID_MODE == FLUID_MODE_LOW)
float f_alt = f_pos.z;
#endif
@ -209,14 +247,6 @@ void main() {
// TODO: Make this more efficient?
ray_dir = normalize(max(reflect_ray_dir, vec3(-1.0, -1.0, 0.0)));
}
vec3 reflect_color = get_sky_color(/*reflect_ray_dir*/ray_dir, time_of_day.x, f_pos, vec3(-100000), 0.125, true);
reflect_color = get_cloud_color(reflect_color, ray_dir, f_pos.xyz, time_of_day.x, 100000.0, 0.1);
reflect_color *= f_light;
// Prevent the sky affecting light when underground
float not_underground = clamp((f_pos.z - f_alt) / 32.0 + 1.0, 0.0, 1.0);
reflect_color *= not_underground;
// /*const */vec3 water_color = srgb_to_linear(vec3(0.2, 0.5, 1.0));
// /*const */vec3 water_color = srgb_to_linear(vec3(0.8, 0.9, 1.0));
// NOTE: Linear RGB, attenuation coefficients for water at roughly R, G, B wavelengths.
@ -237,6 +267,21 @@ void main() {
// float moon_shade_frac = horizon_at(/*f_shadow, f_pos.z, */f_pos, moon_dir);
// float shade_frac = /*1.0;*/sun_shade_frac + moon_shade_frac;
vec3 reflect_color;
#if (REFLECTION_MODE >= REFLECTION_MODE_MEDIUM)
reflect_color = get_sky_color(ray_dir, time_of_day.x, f_pos, vec3(-100000), 0.125, true, 1.0, true, sun_shade_frac);
reflect_color = get_cloud_color(reflect_color, ray_dir, f_pos.xyz, time_of_day.x, 100000.0, 0.1);
#else
reflect_color = get_sky_color(ray_dir, time_of_day.x, f_pos, vec3(-100000), 0.125, true, 1.0, true, sun_shade_frac);
#endif
// Sort of non-physical, but we try to balance the reflection intensity with the direct light from the sun,
// resulting in decent reflection of the ambient environment even after the sun has gone down.
reflect_color *= f_light * (sun_shade_frac * 0.75 + 0.25);
// Prevent the sky affecting light when underground
float not_underground = clamp((f_pos.z - f_alt) / 32.0 + 1.0, 0.0, 1.0);
reflect_color *= not_underground;
// DirectionalLight sun_info = get_sun_info(sun_dir, sun_shade_frac, light_pos);
float point_shadow = shadow_at(f_pos, f_norm);
DirectionalLight sun_info = get_sun_info(sun_dir, point_shadow * sun_shade_frac, /*sun_pos*/f_pos);
@ -271,6 +316,7 @@ void main() {
vec3 mu = MU_WATER;
// NOTE: Default intersection point is camera position, meaning if we fail to intersect we assume the whole camera is in water.
vec3 cam_attenuation = compute_attenuation_point(f_pos, -view_dir, mu, fluid_alt, cam_pos.xyz);
//reflect_color *= cam_attenuation;
// float water_depth_to_vertical = max(/*f_alt - f_pos.z*/f_light, 0.0);
// For ambient color, we just take the distance to the surface out of laziness.
// See https://en.wikipedia.org/wiki/Beer%E2%80%93Lambert_law.
@ -288,10 +334,10 @@ void main() {
// vec3 light, diffuse_light, ambient_light;
// vec3 light_frac = /*vec3(1.0);*/light_reflection_factor(f_norm/*vec3(0, 0, 1.0)*/, view_dir, vec3(0, 0, -1.0), vec3(1.0), vec3(R_s), alpha);
// 0 = 100% reflection, 1 = translucent water
float passthrough = max(dot(norm, -cam_to_frag), 0) * 0.75;
float passthrough = max(dot(cam_norm, -cam_to_frag), 0) * 0.75;
float max_light = 0.0;
max_light += get_sun_diffuse2(sun_info, moon_info, norm, /*time_of_day.x*/sun_view_dir, f_pos, mu, cam_attenuation, fluid_alt, k_a/* * (shade_frac * 0.5 + light_frac * 0.5)*/, vec3(k_d), /*vec3(f_light * point_shadow)*//*reflect_color*/k_s, alpha, f_norm, 1.0, emitted_light, reflected_light);
max_light += get_sun_diffuse2(sun_info, moon_info, cam_norm, /*time_of_day.x*/sun_view_dir, f_pos, mu, cam_attenuation, fluid_alt, k_a/* * (shade_frac * 0.5 + light_frac * 0.5)*/, vec3(k_d), /*vec3(f_light * point_shadow)*//*reflect_color*/k_s, alpha, f_norm, 1.0, emitted_light, reflected_light);
emitted_light *= not_underground;
reflected_light *= not_underground;
@ -332,7 +378,7 @@ void main() {
// diffuse_light += point_light;
// reflected_light += point_light;
// vec3 surf_color = srgb_to_linear(vec3(0.2, 0.5, 1.0)) * light * diffuse_light * ambient_light;
const float REFLECTANCE = 0.5;
const float REFLECTANCE = 1.0;
vec3 surf_color = illuminate(max_light, view_dir, water_color * emitted_light/* * log(1.0 - MU_WATER)*/, /*cam_attenuation * *//*water_color * */reflect_color * REFLECTANCE + water_color * reflected_light/* * log(1.0 - MU_WATER)*/);
// passthrough = pow(passthrough, 1.0 / (1.0 + water_depth_to_camera));
@ -359,10 +405,18 @@ void main() {
// float log_cam = log(min(cam_attenuation.r, min(cam_attenuation.g, cam_attenuation.b)));
float min_refl = 0.0;
float opacity = (1.0 - passthrough) * 0.5 / (1.0 + min_refl);
if (medium.x != MEDIUM_WATER) {
min_refl = min(emitted_light.r, min(emitted_light.g, emitted_light.b));
} else {
// Hack to make the transparency of the surface fade when underwater to avoid artifacts
if (dot(refract_ray_dir, cam_to_frag) > 0.0) {
opacity = 0.99;
} else {
opacity = min(sqrt(max(opacity, clamp((f_pos.z - cam_pos.z) * 0.05, 0.0, 1.0))), 0.99);
}
}
vec4 color = vec4(surf_color, (1.0 - passthrough) * 1.0 / (1.0 + min_refl));// * (1.0 - /*log(1.0 + cam_attenuation)*//*cam_attenuation*/1.0 / (2.0 - log_cam)));
vec4 color = vec4(surf_color, opacity);// * (1.0 - /*log(1.0 + cam_attenuation)*//*cam_attenuation*/1.0 / (2.0 - log_cam)));
// vec4 color = vec4(surf_color, mix(1.0, 1.0 / (1.0 + /*0.25 * *//*diffuse_light*/(/*f_light * point_shadow*/reflected_light_point)), passthrough));
// vec4 color = vec4(surf_color, mix(1.0, length(cam_attenuation), passthrough));

View File

@ -6,9 +6,9 @@
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_SPECULAR
#if (FLUID_MODE == FLUID_MODE_CHEAP)
#if (FLUID_MODE == FLUID_MODE_LOW)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
#elif (FLUID_MODE == FLUID_MODE_SHINY)
#elif (FLUID_MODE >= FLUID_MODE_MEDIUM)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
#endif
@ -21,6 +21,7 @@
#include <random.glsl>
layout(location = 0) in uint v_pos_norm;
layout(location = 1) in uint v_vel;
// in uint v_col_light;
layout(std140, set = 2, binding = 0)
@ -42,6 +43,7 @@ uniform u_locals {
layout(location = 0) out vec3 f_pos;
layout(location = 1) flat out uint f_pos_norm;
layout(location = 2) out vec2 f_vel;
// out vec3 f_col;
// out float f_light;
// out vec3 light_pos[2];
@ -50,6 +52,10 @@ const float EXTRA_NEG_Z = 65536.0/*65536.1*/;
void main() {
f_pos = vec3(v_pos_norm & 0x3Fu, (v_pos_norm >> 6) & 0x3Fu, float((v_pos_norm >> 12) & 0x1FFFFu) - EXTRA_NEG_Z) + model_offs - focus_off.xyz;
f_vel = vec2(
(float(v_vel & 0xFFFFu) - 32768.0) / 1000.0,
(float((v_vel >> 16u) & 0xFFFFu) - 32768.0) / 1000.0
);
// f_pos.z -= 250.0 * (1.0 - min(1.0001 - 0.02 / pow(tick.x - load_time, 10.0), 1.0));
// f_pos.z -= min(32.0, 25.0 * pow(distance(focus_pos.xy, f_pos.xy) / view_distance.x, 20.0));
@ -63,7 +69,7 @@ void main() {
#endif
float pull_down = pow(distance(focus_pos.xy, f_pos.xy) / (view_distance.x * 0.95), 20.0) * 0.7;
f_pos.z -= pull_down;
//f_pos.z -= pull_down;
#ifdef EXPERIMENTAL_CURVEDWORLD
f_pos.z -= pow(distance(f_pos.xy + focus_off.xy, focus_pos.xy + focus_off.xy) * 0.05, 2);
@ -73,7 +79,7 @@ void main() {
// f_pos.xy += 0.01; // Avoid z-fighting
// f_pos.x += 0.1 * sin(tick.x / 60 * hash(vec4(f_pos.xyz, 1.0)));
// f_pos.y += 0.1 * sin(tick.x / 60 * hash(vec4(f_pos.xyz, 2.0)));
#if (FLUID_MODE == FLUID_MODE_SHINY)
#if (FLUID_MODE >= FLUID_MODE_MEDIUM)
// f_pos.z -= 0.1 + 0.1 * (sin(tick.x/* / 60.0*/* 2.0 + f_pos.x * 2.0 + f_pos.y * 2.0) + 1.0) * 0.5;
#endif

View File

@ -1,8 +1,14 @@
#include <lod.glsl>
#include <sky.glsl>
vec3 get_cloud_color(vec3 surf_color, vec3 dir, vec3 origin, float time_of_day, float max_dist, float quality) {
// Underwater light attenuation
surf_color = water_diffuse(surf_color, dir, max_dist);
if (max_dist < DIST_CAP) {
vec3 sky_light = get_sky_light(dir, time_of_day, false);
surf_color = mix(sky_light, surf_color, 1.0 / exp(max_dist / 5000.0));
}
return surf_color;
}

View File

@ -232,92 +232,86 @@ vec3 get_cloud_color(vec3 surf_color, vec3 dir, vec3 origin, const float time_of
vec3 moon_color = get_moon_color();
// Clouds aren't visible underwater
#ifdef IS_POSTPROCESS
if (medium.x != 1) {
#endif
float cdist = max_dist;
float ldist = cdist;
// i is an emergency brake
float min_dist = clamp(max_dist / 4, 0.25, 24);
int i;
float cdist = max_dist;
float ldist = cdist;
// i is an emergency brake
float min_dist = clamp(max_dist / 4, 0.25, 24);
int i;
#if (CLOUD_MODE >= CLOUD_MODE_MEDIUM)
#if (CLOUD_MODE >= CLOUD_MODE_MEDIUM)
#ifndef EXPERIMENTAL_NORAINBOWS
// TODO: Make it a double rainbow
float rainbow_t = (0.7 - dot(sun_dir.xyz, dir)) * 8 / 0.05;
int rainbow_c = int(floor(rainbow_t));
rainbow_t = fract(rainbow_t);
rainbow_t = rainbow_t * rainbow_t;
#endif
#endif
for (i = 0; cdist > min_dist && i < 250; i ++) {
ldist = cdist;
cdist = step_to_dist(trunc(dist_to_step(cdist - 0.25, quality)), quality);
vec3 emission;
float not_underground; // Used to prevent sunlight leaking underground
vec3 pos = origin + dir * ldist * splay;
// `sample` is a reserved keyword
vec4 sample_ = cloud_at(origin + dir * ldist * splay, ldist, emission, not_underground);
vec2 density_integrals = max(sample_.zw, vec2(0));
float sun_access = max(sample_.x, 0);
float moon_access = max(sample_.y, 0);
float cloud_scatter_factor = density_integrals.x;
float global_scatter_factor = density_integrals.y;
float step = (ldist - cdist) * 0.01;
float cloud_darken = pow(1.0 / (1.0 + cloud_scatter_factor), step);
float global_darken = pow(1.0 / (1.0 + global_scatter_factor), step);
// Proportion of light diffusely scattered instead of absorbed
float cloud_diffuse = 0.25;
surf_color =
// Attenuate light passing through the clouds
surf_color * cloud_darken * global_darken +
// Add the directed light light scattered into the camera by the clouds and the atmosphere (global illumination)
sun_color * sun_scatter * get_sun_brightness() * (sun_access * (1.0 - cloud_darken) * cloud_diffuse /*+ sky_color * global_scatter_factor*/) +
moon_color * moon_scatter * get_moon_brightness() * (moon_access * (1.0 - cloud_darken) * cloud_diffuse /*+ sky_color * global_scatter_factor*/) +
sky_light * (1.0 - global_darken) * not_underground +
// A small amount fake ambient light underground
(1.0 - not_underground) * vec3(0.2, 0.35, 0.5) * (1.0 - global_darken) / (1.0 + max_dist * 0.003) +
emission * density_integrals.y * step;
// Rainbow
#if (CLOUD_MODE >= CLOUD_MODE_ULTRA)
#ifndef EXPERIMENTAL_NORAINBOWS
// TODO: Make it a double rainbow
float rainbow_t = (0.7 - dot(sun_dir.xyz, dir)) * 8 / 0.05;
int rainbow_c = int(floor(rainbow_t));
rainbow_t = fract(rainbow_t);
rainbow_t = rainbow_t * rainbow_t;
if (rainbow_c >= 0 && rainbow_c < 8) {
vec3 colors[9] = {
surf_color,
vec3(0.9, 0.5, 0.9),
vec3(0.25, 0.0, 0.5),
vec3(0.0, 0.0, 1.0),
vec3(0.0, 0.5, 0.0),
vec3(1.0, 1.0, 0.0),
vec3(1.0, 0.6, 0.0),
vec3(1.0, 0.0, 0.0),
surf_color,
};
float h = max(0.0, min(pos.z, 900.0 - pos.z) / 450.0);
float rain = rain_density_at(pos.xy) * pow(h, 0.1);
float sun = sun_access * get_sun_brightness();
float energy = pow(rain * sun * min(cdist / 500.0, 1.0), 2.0) * 0.4;
surf_color = mix(
surf_color,
mix(colors[rainbow_c], colors[rainbow_c + 1], rainbow_t),
energy
);
}
#endif
#endif
for (i = 0; cdist > min_dist && i < 250; i ++) {
ldist = cdist;
cdist = step_to_dist(trunc(dist_to_step(cdist - 0.25, quality)), quality);
vec3 emission;
float not_underground; // Used to prevent sunlight leaking underground
vec3 pos = origin + dir * ldist * splay;
// `sample` is a reserved keyword
vec4 sample_ = cloud_at(origin + dir * ldist * splay, ldist, emission, not_underground);
vec2 density_integrals = max(sample_.zw, vec2(0));
float sun_access = max(sample_.x, 0);
float moon_access = max(sample_.y, 0);
float cloud_scatter_factor = density_integrals.x;
float global_scatter_factor = density_integrals.y;
float step = (ldist - cdist) * 0.01;
float cloud_darken = pow(1.0 / (1.0 + cloud_scatter_factor), step);
float global_darken = pow(1.0 / (1.0 + global_scatter_factor), step);
// Proportion of light diffusely scattered instead of absorbed
float cloud_diffuse = 0.25;
surf_color =
// Attenuate light passing through the clouds
surf_color * cloud_darken * global_darken +
// Add the directed light light scattered into the camera by the clouds and the atmosphere (global illumination)
sun_color * sun_scatter * get_sun_brightness() * (sun_access * (1.0 - cloud_darken) * cloud_diffuse /*+ sky_color * global_scatter_factor*/) +
moon_color * moon_scatter * get_moon_brightness() * (moon_access * (1.0 - cloud_darken) * cloud_diffuse /*+ sky_color * global_scatter_factor*/) +
sky_light * (1.0 - global_darken) * not_underground +
// A small amount fake ambient light underground
(1.0 - not_underground) * vec3(0.2, 0.35, 0.5) * (1.0 - global_darken) / (1.0 + max_dist * 0.003) +
emission * density_integrals.y * step;
// Rainbow
#if (CLOUD_MODE >= CLOUD_MODE_ULTRA)
#ifndef EXPERIMENTAL_NORAINBOWS
if (rainbow_c >= 0 && rainbow_c < 8) {
vec3 colors[9] = {
surf_color,
vec3(0.9, 0.5, 0.9),
vec3(0.25, 0.0, 0.5),
vec3(0.0, 0.0, 1.0),
vec3(0.0, 0.5, 0.0),
vec3(1.0, 1.0, 0.0),
vec3(1.0, 0.6, 0.0),
vec3(1.0, 0.0, 0.0),
surf_color,
};
float h = max(0.0, min(pos.z, 900.0 - pos.z) / 450.0);
float rain = rain_density_at(pos.xy) * pow(h, 0.1);
float sun = sun_access * get_sun_brightness();
float energy = pow(rain * sun * min(cdist / 500.0, 1.0), 2.0) * 0.4;
surf_color = mix(
surf_color,
mix(colors[rainbow_c], colors[rainbow_c + 1], rainbow_t),
energy
);
}
#endif
#endif
}
#ifdef IS_POSTPROCESS
}
#endif
}
// Underwater light attenuation
surf_color = water_diffuse(surf_color, dir, max_dist);

View File

@ -6,8 +6,13 @@
#define VOXYGEN_COMPUTATION_PREFERENCE_FRAGMENT 0
#define VOXYGEN_COMPUTATION_PREFERENCE_VERTEX 1
#define FLUID_MODE_CHEAP 0
#define FLUID_MODE_SHINY 1
#define FLUID_MODE_LOW 0
#define FLUID_MODE_MEDIUM 1
#define FLUID_MODE_HIGH 2
#define REFLECTION_MODE_LOW 0
#define REFLECTION_MODE_MEDIUM 1
#define REFLECTION_MODE_HIGH 2
#define CLOUD_MODE_NONE 0
#define CLOUD_MODE_MINIMAL 1

View File

@ -138,7 +138,7 @@ float alt_at(vec2 pos) {
float alt_at_real(vec2 pos) {
// Basic idea: only really need the real altitude for an accurate water height estimation, so if we are in the cheap shader take a shortcut.
// #if (FLUID_MODE == FLUID_MODE_CHEAP)
// #if (FLUID_MODE == FLUID_MODE_LOW)
// return alt_at(pos);
// #elif (FLUID_MODE == FLUID_MODE_SHINY)
return (/*round*/(textureBicubic16(t_alt, s_alt, pos_to_tex(pos)).r * (/*1300.0*//*1278.7266845703125*/view_distance.w)) + /*140.0*/view_distance.z - focus_off.z);
@ -391,13 +391,13 @@ vec3 water_diffuse(vec3 color, vec3 dir, float max_dist) {
float f_alt = alt_at(cam_pos.xy);
float fluid_alt = max(cam_pos.z + 1, floor(f_alt + 1));
float water_dist = clamp((fluid_alt - cam_pos.z) / pow(max(dir.z, 0), 5), 0, max_dist);
float water_dist = clamp((fluid_alt - cam_pos.z) / pow(max(dir.z, 0), 2), 0, max_dist);
float fade = pow(0.97, water_dist);
float fade = pow(0.95, water_dist);
return mix(vec3(0.0, 0.2, 0.5)
* (get_sun_brightness() * get_sun_color() + get_moon_brightness() * get_moon_color())
* pow(0.99, max((fluid_alt - cam_pos.z) * 12.0 - dir.z * 200, 0)), color.rgb, fade);
* pow(0.99, max((fluid_alt - cam_pos.z) * 12.0 - dir.z * 200, 0)), color.rgb * exp(-MU_WATER * water_dist * 0.1), fade);
} else {
return color;
}

View File

@ -26,7 +26,7 @@ const vec3 DAWN_LIGHT = vec3(5.0, 2.0, 1.15);
const vec3 SUN_HALO_DAWN = vec3(8.2, 3.0, 2.1);
const vec3 SKY_DAY_TOP = vec3(0.1, 0.5, 0.9);
const vec3 SKY_DAY_MID = vec3(0.02, 0.28, 0.8);
const vec3 SKY_DAY_MID = vec3(0.18, 0.28, 0.6);
const vec3 SKY_DAY_BOT = vec3(0.1, 0.2, 0.3);
const vec3 DAY_LIGHT = vec3(3.8, 3.0, 1.8);
const vec3 SUN_HALO_DAY = vec3(0.25, 0.25, 0.001);
@ -503,7 +503,12 @@ float is_star_at(vec3 dir) {
//return 0.0;
return 5.0 / (1.0 + pow(dist * 750, 8));
#if (CLOUD_MODE == CLOUD_MODE_NONE)
const float power = 5.0;
#else
const float power = 50.0;
#endif
return power * max(sun_dir.z, 0.1) / (1.0 + pow(dist * 750, 8));
}
vec3 get_sky_light(vec3 dir, float time_of_day, bool with_stars) {
@ -570,7 +575,7 @@ vec3 get_sky_light(vec3 dir, float time_of_day, bool with_stars) {
return sky_color * magnetosphere_tint;
}
vec3 get_sky_color(vec3 dir, float time_of_day, vec3 origin, vec3 f_pos, float quality, bool with_features, float refractionIndex) {
vec3 get_sky_color(vec3 dir, float time_of_day, vec3 origin, vec3 f_pos, float quality, bool with_features, float refractionIndex, bool fake_clouds, float sun_shade_frac) {
// Sky color
/* vec3 sun_dir = get_sun_dir(time_of_day);
vec3 moon_dir = get_moon_dir(time_of_day); */
@ -581,7 +586,7 @@ vec3 get_sky_color(vec3 dir, float time_of_day, vec3 origin, vec3 f_pos, float q
// moon_dir = moon_dir.z <= 0 ? refract(moon_dir/*-view_dir*/, vec3(0.0, 0.0, 1.0), refractionIndex) : moon_dir;
// Sun
const vec3 SUN_SURF_COLOR = vec3(1.5, 0.9, 0.35) * 50.0;
const vec3 SUN_SURF_COLOR = vec3(1.5, 0.9, 0.35) * 10.0;
vec3 sun_halo_color = mix(
(sun_dir.x > 0 ? SUN_HALO_DUSK : SUN_HALO_DAWN)* magnetosphere_tint,
@ -591,15 +596,29 @@ vec3 get_sky_color(vec3 dir, float time_of_day, vec3 origin, vec3 f_pos, float q
float sun_halo_power = 20.0;
#if (CLOUD_MODE == CLOUD_MODE_NONE)
sun_halo_power = 1000.0;
sun_halo_color *= 0.1;
if (true) {
#else
if (fake_clouds || medium.x == MEDIUM_WATER) {
#endif
sun_halo_power = 30.0;
sun_halo_color *= 0.01;
}
vec3 sun_halo = sun_halo_color * 25 * pow(max(dot(dir, -sun_dir), 0), sun_halo_power);
vec3 sun_surf = vec3(0);
if (with_features) {
float angle = 0.00035;
sun_surf = clamp((dot(dir, -sun_dir) - (1.0 - angle)) * 4 / angle, 0, 1) * SUN_SURF_COLOR * SUN_COLOR_FACTOR;
sun_surf = clamp((dot(dir, -sun_dir) - (1.0 - angle)) * 4 / angle, 0, 1)
* SUN_SURF_COLOR
* SUN_COLOR_FACTOR
* sun_shade_frac;
}
#if (CLOUD_MODE == CLOUD_MODE_NONE)
if (true) {
#else
if (fake_clouds || medium.x == MEDIUM_WATER) {
#endif
sun_surf *= 0.1;
}
vec3 sun_light = sun_halo + sun_surf;
@ -610,25 +629,34 @@ vec3 get_sky_color(vec3 dir, float time_of_day, vec3 origin, vec3 f_pos, float q
vec3 moon_halo_color = MOON_HALO_COLOR;
float moon_halo_power = 20.0;
#if (CLOUD_MODE == CLOUD_MODE_NONE)
moon_halo_power = 2500.0;
moon_halo_color *= 0.1;
#endif
vec3 moon_halo = moon_halo_color * pow(max(dot(dir, -moon_dir), 0), moon_halo_power);
vec3 moon_surf = vec3(0);
if (with_features) {
float angle = 0.00035;
moon_surf = clamp((dot(dir, -moon_dir) - (1.0 - angle)) * 4 / angle, 0, 1) * MOON_SURF_COLOR;
}
#if (CLOUD_MODE == CLOUD_MODE_NONE)
if (true) {
#else
if (fake_clouds || medium.x == MEDIUM_WATER) {
#endif
moon_halo_power = 50.0;
moon_halo_color *= 0.2;
moon_surf *= 0.05;
}
vec3 moon_halo = moon_halo_color * pow(max(dot(dir, -moon_dir), 0), moon_halo_power);
vec3 moon_light = moon_halo + moon_surf;
// Replaced all clamp(sun_dir, 0, 1) with max(sun_dir, 0) because sun_dir is calculated from sin and cos, which are never > 1
vec3 sky_color;
#if (CLOUD_MODE == CLOUD_MODE_NONE)
vec3 sky_color = get_sky_light(dir, time_of_day, true);
if (true) {
#else
vec3 sky_color;
if (fake_clouds || medium.x == MEDIUM_WATER) {
#endif
sky_color = get_sky_light(dir, time_of_day, !fake_clouds);
} else {
if (medium.x == MEDIUM_WATER) {
sky_color = get_sky_light(dir, time_of_day, true);
} else {
@ -636,13 +664,17 @@ vec3 get_sky_color(vec3 dir, float time_of_day, vec3 origin, vec3 f_pos, float q
float star = is_star_at(star_dir);
sky_color = vec3(0) + star;
}
#endif
}
return sky_color + sun_light + moon_light;
}
vec3 get_sky_color(vec3 dir, float time_of_day, vec3 origin, vec3 f_pos, float quality, bool with_features, float refractionIndex) {
return get_sky_color(dir, time_of_day, origin, f_pos, quality, with_features, refractionIndex, false, 1.0);
}
vec3 get_sky_color(vec3 dir, float time_of_day, vec3 origin, vec3 f_pos, float quality, bool with_stars) {
return get_sky_color(dir, time_of_day, origin, f_pos, quality, with_stars, 1.0);
return get_sky_color(dir, time_of_day, origin, f_pos, quality, with_stars, 1.0, false, 1.0);
}
float fog(vec3 f_pos, vec3 focus_pos, uint medium) {

View File

@ -536,7 +536,7 @@ vec3 compute_attenuation(vec3 wpos, vec3 ray_dir, vec3 mu, float surface_alt, ve
// from the default point.
vec3 compute_attenuation_point(vec3 wpos, vec3 ray_dir, vec3 mu, float surface_alt, vec3 defaultpos) {
#if (LIGHTING_TRANSPORT_MODE == LIGHTING_TRANSPORT_MODE_IMPORTANCE)
return vec3(1.0);
return pow(1.0 - mu, vec3(3));
#elif (LIGHTING_TRANSPORT_MODE == LIGHTING_TRANSPORT_MODE_RADIANCE)
// return vec3(1.0);
/*if (mu == vec3(0.0)) {

View File

@ -7,9 +7,9 @@
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_GLOSSY
#if (FLUID_MODE == FLUID_MODE_CHEAP)
#if (FLUID_MODE == FLUID_MODE_LOW)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
#elif (FLUID_MODE == FLUID_MODE_SHINY)
#elif (FLUID_MODE >= FLUID_MODE_MEDIUM)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
#endif

View File

@ -9,9 +9,9 @@
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_GLOSSY
#if (FLUID_MODE == FLUID_MODE_CHEAP)
#if (FLUID_MODE == FLUID_MODE_LOW)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
#elif (FLUID_MODE == FLUID_MODE_SHINY)
#elif (FLUID_MODE >= FLUID_MODE_MEDIUM)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
#endif

View File

@ -11,9 +11,9 @@
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_GLOSSY
#if (FLUID_MODE == FLUID_MODE_CHEAP)
#if (FLUID_MODE == FLUID_MODE_LOW)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
#elif (FLUID_MODE == FLUID_MODE_SHINY)
#elif (FLUID_MODE >= FLUID_MODE_MEDIUM)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
#endif

View File

@ -11,9 +11,9 @@
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_GLOSSY
#if (FLUID_MODE == FLUID_MODE_CHEAP)
#if (FLUID_MODE == FLUID_MODE_LOW)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
#elif (FLUID_MODE == FLUID_MODE_SHINY)
#elif (FLUID_MODE >= FLUID_MODE_MEDIUM)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
#endif

View File

@ -7,9 +7,9 @@
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_GLOSSY
#if (FLUID_MODE == FLUID_MODE_CHEAP)
#if (FLUID_MODE == FLUID_MODE_LOW)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
#elif (FLUID_MODE == FLUID_MODE_SHINY)
#elif (FLUID_MODE >= FLUID_MODE_MEDIUM)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
#endif

View File

@ -6,9 +6,9 @@
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_GLOSSY
#if (FLUID_MODE == FLUID_MODE_CHEAP)
#if (FLUID_MODE == FLUID_MODE_LOW)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
#elif (FLUID_MODE == FLUID_MODE_SHINY)
#elif (FLUID_MODE >= FLUID_MODE_MEDIUM)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
#endif
@ -41,9 +41,9 @@ void main() {
vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz);
vec3 view_dir = -cam_to_frag;
#if (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_MAP || FLUID_MODE == FLUID_MODE_SHINY)
#if (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_MAP || FLUID_MODE >= FLUID_MODE_MEDIUM)
float f_alt = alt_at(f_pos.xy);
#elif (SHADOW_MODE == SHADOW_MODE_NONE || FLUID_MODE == FLUID_MODE_CHEAP)
#elif (SHADOW_MODE == SHADOW_MODE_NONE || FLUID_MODE == FLUID_MODE_LOW)
float f_alt = f_pos.z;
#endif

View File

@ -6,9 +6,9 @@
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_GLOSSY
#if (FLUID_MODE == FLUID_MODE_CHEAP)
#if (FLUID_MODE == FLUID_MODE_LOW)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
#elif (FLUID_MODE == FLUID_MODE_SHINY)
#elif (FLUID_MODE >= FLUID_MODE_MEDIUM)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
#endif
@ -445,10 +445,10 @@ void main() {
vec3 moon_dir = get_moon_dir(time_of_day.x); */
// voxel_norm = vec3(0.0);
#if (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_MAP || FLUID_MODE == FLUID_MODE_SHINY)
#if (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_MAP || FLUID_MODE >= FLUID_MODE_MEDIUM)
float shadow_alt = /*f_pos.z;*/alt_at(f_pos.xy);//max(alt_at(f_pos.xy), f_pos.z);
// float shadow_alt = f_pos.z;
#elif (SHADOW_MODE == SHADOW_MODE_NONE || FLUID_MODE == FLUID_MODE_CHEAP)
#elif (SHADOW_MODE == SHADOW_MODE_NONE || FLUID_MODE == FLUID_MODE_LOW)
float shadow_alt = f_pos.z;
#endif
@ -579,9 +579,9 @@ void main() {
vec3 emitted_light, reflected_light;
vec3 mu = medium.x == MEDIUM_WATER/* && f_pos.z <= fluid_alt*/ ? MU_WATER : vec3(0.0);
vec3 mu = medium.x == MEDIUM_WATER ? MU_WATER : vec3(0.0);
// NOTE: Default intersection point is camera position, meaning if we fail to intersect we assume the whole camera is in water.
vec3 cam_attenuation = compute_attenuation_point(cam_pos.xyz, view_dir, mu, fluid_alt, /*cam_pos.z <= fluid_alt ? cam_pos.xyz : f_pos*/f_pos);
vec3 cam_attenuation = compute_attenuation_point(f_pos, view_dir, mu, fluid_alt, /*cam_pos.z <= fluid_alt ? cam_pos.xyz : f_pos*/cam_pos.xyz);
// Use f_norm here for better shadows.
// vec3 light_frac = light_reflection_factor(f_norm/*l_norm*/, view_dir, vec3(0, 0, -1.0), vec3(1.0), vec3(/*1.0*/R_s), alpha);
@ -648,34 +648,43 @@ void main() {
// vec3 surf_color = illuminate(f_col, light, diffuse_light, ambient_light);
// f_col = f_col + (hash(vec4(floor(vec3(focus_pos.xy + splay(v_pos_orig), f_pos.z)) * 3.0 - round(f_norm) * 0.5, 0)) - 0.5) * 0.05; // Small-scale noise
vec3 surf_color;
#if (FLUID_MODE == FLUID_MODE_SHINY)
if (length(f_col_raw - vec3(0.02, 0.06, 0.22)) < 0.025 && dot(vec3(0, 0, 1), f_norm) > 0.9) {
float surf_alpha = 1.0;
if (length(f_col_raw - vec3(0.02, 0.06, 0.22)) < 0.025 && dot(vec3(0, 0, 1), f_norm) > 0.9) {
vec3 reflect_ray = cam_to_frag * vec3(1, 1, -1);
#if (FLUID_MODE >= FLUID_MODE_MEDIUM)
vec3 water_color = (1.0 - MU_WATER) * MU_SCATTER;
vec3 reflect_ray = cam_to_frag * vec3(1, 1, -1);
float passthrough = dot(faceforward(f_norm, f_norm, cam_to_frag), -cam_to_frag);
vec3 reflect_color = get_sky_color(reflect_ray, time_of_day.x, f_pos, vec3(-100000), 0.125, true);
reflect_color = get_cloud_color(reflect_color, reflect_ray, cam_pos.xyz, time_of_day.x, 100000.0, 0.1);
vec3 reflect_color;
#if (FLUID_MODE == FLUID_MODE_HIGH)
reflect_color = get_sky_color(reflect_ray, time_of_day.x, f_pos, vec3(-100000), 0.125, true, 1.0, true, sun_shade_frac);
reflect_color = get_cloud_color(reflect_color, reflect_ray, cam_pos.xyz, time_of_day.x, 100000.0, 0.1);
#else
reflect_color = get_sky_color(reflect_ray, time_of_day.x, f_pos, vec3(-100000), 0.125, true, 1.0, true, sun_shade_frac);
#endif
reflect_color *= sun_shade_frac * 0.75 + 0.25;
const float REFLECTANCE = 0.5;
const float REFLECTANCE = 1.0;
surf_color = illuminate(max_light, view_dir, f_col * emitted_light, reflect_color * REFLECTANCE + water_color * reflected_light);
const vec3 underwater_col = vec3(0.0);
float min_refl = min(emitted_light.r, min(emitted_light.g, emitted_light.b));
surf_color = mix(underwater_col, surf_color, (1.0 - passthrough) * 1.0 / (1.0 + min_refl));
} else {
surf_color = illuminate(max_light, view_dir, f_col * emitted_light, f_col * reflected_light);
}
#else
surf_alpha = 1.0 - passthrough;
#else
surf_alpha = 0.9;
surf_color = get_sky_color(reflect_ray, time_of_day.x, f_pos, vec3(-100000), 0.125, true, 1.0, true, sun_shade_frac);
#endif
} else {
surf_color = illuminate(max_light, view_dir, f_col * emitted_light, f_col * reflected_light);
#endif
}
// float mist_factor = max(1 - (f_pos.z + (texture(t_noise, f_pos.xy * 0.0005 + time_of_day.x * 0.0003).x - 0.5) * 128.0) / 400.0, 0.0);
// //float mist_factor = f_norm.z * 2.0;
// color = mix(color, vec3(1.0) * /*diffuse_light*/reflected_light, clamp(mist_factor * 0.00005 * distance(f_pos.xy, focus_pos.xy), 0, 0.3));
// color = surf_color;
tgt_color = vec4(surf_color, 1.0);
tgt_color = vec4(surf_color, surf_alpha);
}

View File

@ -6,9 +6,9 @@
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_GLOSSY
#if (FLUID_MODE == FLUID_MODE_CHEAP)
#if (FLUID_MODE == FLUID_MODE_LOW)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
#elif (FLUID_MODE == FLUID_MODE_SHINY)
#elif (FLUID_MODE >= FLUID_MODE_MEDIUM)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
#endif

View File

@ -6,9 +6,9 @@
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_GLOSSY
#if (FLUID_MODE == FLUID_MODE_CHEAP)
#if (FLUID_MODE == FLUID_MODE_LOW)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
#elif (FLUID_MODE == FLUID_MODE_SHINY)
#elif (FLUID_MODE >= FLUID_MODE_MEDIUM)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
#endif
@ -42,9 +42,9 @@ void main() {
vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz);
vec3 view_dir = -cam_to_frag;
#if (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_MAP || FLUID_MODE == FLUID_MODE_SHINY)
#if (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_MAP || FLUID_MODE >= FLUID_MODE_MEDIUM)
float f_alt = alt_at(f_pos.xy);
#elif (SHADOW_MODE == SHADOW_MODE_NONE || FLUID_MODE == FLUID_MODE_CHEAP)
#elif (SHADOW_MODE == SHADOW_MODE_NONE || FLUID_MODE == FLUID_MODE_LOW)
float f_alt = f_pos.z;
#endif
@ -88,7 +88,7 @@ void main() {
vec3 cam_attenuation = vec3(1);
float fluid_alt = max(f_pos.z + 1, floor(f_alt + 1));
vec3 mu = medium.x == MEDIUM_WATER ? MU_WATER : vec3(0.0);
#if (FLUID_MODE == FLUID_MODE_SHINY)
#if (FLUID_MODE >= FLUID_MODE_MEDIUM)
cam_attenuation =
medium.x == MEDIUM_WATER ? compute_attenuation_point(cam_pos.xyz, view_dir, MU_WATER, fluid_alt, /*cam_pos.z <= fluid_alt ? cam_pos.xyz : f_pos*/f_pos)
: compute_attenuation_point(f_pos, -view_dir, vec3(0), fluid_alt, /*cam_pos.z <= fluid_alt ? cam_pos.xyz : f_pos*/cam_pos.xyz);

View File

@ -7,9 +7,9 @@
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_GLOSSY
#if (FLUID_MODE == FLUID_MODE_CHEAP)
#if (FLUID_MODE == FLUID_MODE_LOW)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
#elif (FLUID_MODE == FLUID_MODE_SHINY)
#elif (FLUID_MODE >= FLUID_MODE_MEDIUM)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
#endif

View File

@ -6,9 +6,9 @@
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_SPECULAR
#if (FLUID_MODE == FLUID_MODE_CHEAP)
#if (FLUID_MODE == FLUID_MODE_LOW)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
#elif (FLUID_MODE == FLUID_MODE_SHINY)
#elif (FLUID_MODE >= FLUID_MODE_MEDIUM)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
#endif
@ -288,7 +288,7 @@ void main() {
vec4 final_color = aa_color;
#if (FLUID_MODE == FLUID_MODE_CHEAP)
#if (FLUID_MODE == FLUID_MODE_LOW)
if (medium.x == MEDIUM_WATER) {
final_color *= vec4(0.2, 0.2, 0.8, 1.0);
}

View File

@ -6,9 +6,9 @@
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_SPECULAR
#if (FLUID_MODE == FLUID_MODE_CHEAP)
#if (FLUID_MODE == FLUID_MODE_LOW)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
#elif (FLUID_MODE == FLUID_MODE_SHINY)
#elif (FLUID_MODE >= FLUID_MODE_MEDIUM)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
#endif

View File

@ -7,9 +7,9 @@
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_GLOSSY
#if (FLUID_MODE == FLUID_MODE_CHEAP)
#if (FLUID_MODE == FLUID_MODE_LOW)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
#elif (FLUID_MODE == FLUID_MODE_SHINY)
#elif (FLUID_MODE >= FLUID_MODE_MEDIUM)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
#endif

View File

@ -9,9 +9,9 @@
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_GLOSSY
#if (FLUID_MODE == FLUID_MODE_CHEAP)
#if (FLUID_MODE == FLUID_MODE_LOW)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
#elif (FLUID_MODE == FLUID_MODE_SHINY)
#elif (FLUID_MODE >= FLUID_MODE_MEDIUM)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
#endif

View File

@ -6,9 +6,9 @@
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_SPECULAR
#if (FLUID_MODE == FLUID_MODE_CHEAP)
#if (FLUID_MODE == FLUID_MODE_LOW)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
#elif (FLUID_MODE == FLUID_MODE_SHINY)
#elif (FLUID_MODE >= FLUID_MODE_MEDIUM)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
#endif
@ -55,5 +55,5 @@ void main() {
} */
vec3 wpos = cam_pos.xyz + /*normalize(f_pos)*/cam_dir * dist;
tgt_color = vec4(cam_attenuation * get_sky_color(normalize(f_pos), time_of_day.x, cam_pos.xyz, wpos, 1.0, true, refractionIndex), 1.0);
tgt_color = vec4(cam_attenuation * get_sky_color(normalize(f_pos), time_of_day.x, cam_pos.xyz, wpos, 1.0, true, refractionIndex, false, 1.0), 1.0);
}

View File

@ -6,9 +6,9 @@
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_SPECULAR
#if (FLUID_MODE == FLUID_MODE_CHEAP)
#if (FLUID_MODE == FLUID_MODE_LOW)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
#elif (FLUID_MODE == FLUID_MODE_SHINY)
#elif (FLUID_MODE >= FLUID_MODE_MEDIUM)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
#endif

View File

@ -6,9 +6,9 @@
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_GLOSSY
#if (FLUID_MODE == FLUID_MODE_CHEAP)
#if (FLUID_MODE == FLUID_MODE_LOW)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
#elif (FLUID_MODE == FLUID_MODE_SHINY)
#elif (FLUID_MODE >= FLUID_MODE_MEDIUM)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
#endif
@ -51,9 +51,9 @@ void main() {
vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz);
vec3 view_dir = -cam_to_frag;
#if (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_MAP || FLUID_MODE == FLUID_MODE_SHINY)
#if (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_MAP || FLUID_MODE >= FLUID_MODE_MEDIUM)
float f_alt = alt_at(f_pos.xy);
#elif (SHADOW_MODE == SHADOW_MODE_NONE || FLUID_MODE == FLUID_MODE_CHEAP)
#elif (SHADOW_MODE == SHADOW_MODE_NONE || FLUID_MODE == FLUID_MODE_LOW)
float f_alt = f_pos.z;
#endif
@ -94,7 +94,7 @@ void main() {
vec3 cam_attenuation = vec3(1);
float fluid_alt = max(f_pos.z + 1, floor(f_alt + 1));
vec3 mu = medium.x == MEDIUM_WATER ? MU_WATER : vec3(0.0);
#if (FLUID_MODE == FLUID_MODE_SHINY)
#if (FLUID_MODE >= FLUID_MODE_MEDIUM)
cam_attenuation =
medium.x == MEDIUM_WATER ? compute_attenuation_point(cam_pos.xyz, view_dir, mu, fluid_alt, /*cam_pos.z <= fluid_alt ? cam_pos.xyz : f_pos*/f_pos)
: compute_attenuation_point(f_pos, -view_dir, mu, fluid_alt, /*cam_pos.z <= fluid_alt ? cam_pos.xyz : f_pos*/cam_pos.xyz);

View File

@ -7,9 +7,9 @@
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_GLOSSY
#if (FLUID_MODE == FLUID_MODE_CHEAP)
#if (FLUID_MODE == FLUID_MODE_LOW)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
#elif (FLUID_MODE == FLUID_MODE_SHINY)
#elif (FLUID_MODE >= FLUID_MODE_MEDIUM)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
#endif
@ -209,9 +209,9 @@ void main() {
/* vec3 sun_dir = get_sun_dir(time_of_day.x);
vec3 moon_dir = get_moon_dir(time_of_day.x); */
#if (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_MAP || FLUID_MODE == FLUID_MODE_SHINY)
#if (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_MAP || FLUID_MODE >= FLUID_MODE_MEDIUM)
float f_alt = alt_at(f_pos.xy);
#elif (SHADOW_MODE == SHADOW_MODE_NONE || FLUID_MODE == FLUID_MODE_CHEAP)
#elif (SHADOW_MODE == SHADOW_MODE_NONE || FLUID_MODE == FLUID_MODE_LOW)
float f_alt = f_pos.z;
#endif
@ -234,6 +234,11 @@ void main() {
// Toggle to see rain_occlusion
// tgt_color = vec4(rain_occlusion_at(f_pos.xyz), 0.0, 0.0, 1.0);
// return;
#if (REFLECTION_MODE >= REFLECTION_MODE_HIGH)
float f_alpha = 1.0;
#else
const float f_alpha = 1.0;
#endif
#if (CLOUD_MODE != CLOUD_MODE_NONE)
if (rain_density > 0 && !faces_fluid && f_norm.z > 0.5) {
vec3 pos = f_pos + focus_off.xyz;
@ -244,23 +249,26 @@ void main() {
drop_pos.z *= 0.5 + hash_fast(uvec3(cell2d, 0));
vec3 cell = vec3(cell2d, floor(drop_pos.z * drop_density.z));
#ifdef EXPERIMENTAL_WETNESS
float puddle = clamp((noise_2d((f_pos.xy + focus_off.xy + vec2(0.1, 0)) * 0.03) - 0.5) * 20.0, 0.0, 1.0)
#if (REFLECTION_MODE >= REFLECTION_MODE_HIGH)
float puddle = clamp((noise_2d((f_pos.xy + focus_off.xy + vec2(0.1, 0)) * 0.02) - 0.5) * 20.0, 0.0, 1.0)
* min(rain_density * 10.0, 1.0)
* clamp((f_sky_exposure - 0.9) * 50.0, 0.0, 1.0);
* clamp((f_sky_exposure - 0.95) * 50.0, 0.0, 1.0);
#else
const float puddle = 1.0;
#endif
#ifdef EXPERIMENTAL_WETNESS
#if (REFLECTION_MODE >= REFLECTION_MODE_HIGH)
if (puddle > 0.0) {
float h = (noise_2d((f_pos.xy + focus_off.xy) * 0.3) - 0.5) * sin(tick.x * 8.0 + f_pos.x * 3)
+ (noise_2d((f_pos.xy + focus_off.xy) * 0.6) - 0.5) * sin(tick.x * 3.5 - f_pos.y * 6);
float hx = (noise_2d((f_pos.xy + focus_off.xy + vec2(0.1, 0)) * 0.3) - 0.5) * sin(tick.x * 8.0 + f_pos.x * 3)
+ (noise_2d((f_pos.xy + focus_off.xy + vec2(0.1, 0)) * 0.6) - 0.5) * sin(tick.x * 3.5 - f_pos.y * 6);
float hy = (noise_2d((f_pos.xy + focus_off.xy + vec2(0, 0.1)) * 0.3) - 0.5) * sin(tick.x * 8.0 + f_pos.x * 3)
+ (noise_2d((f_pos.xy + focus_off.xy + vec2(0, 0.1)) * 0.6) - 0.5) * sin(tick.x * 3.5 - f_pos.y * 6);
f_norm.xy += mix(vec2(0), vec2(h - hx, h - hy) / 0.1 * 0.03, puddle);
f_alpha = puddle * 0.2 * max(1.0 + cam_to_frag.z, 0.3);
#ifdef EXPERIMENTAL_PUDDLEDETAILS
float h = (noise_2d((f_pos.xy + focus_off.xy) * 0.3) - 0.5) * sin(tick.x * 8.0 + f_pos.x * 3)
+ (noise_2d((f_pos.xy + focus_off.xy) * 0.6) - 0.5) * sin(tick.x * 3.5 - f_pos.y * 6);
float hx = (noise_2d((f_pos.xy + focus_off.xy + vec2(0.1, 0)) * 0.3) - 0.5) * sin(tick.x * 8.0 + f_pos.x * 3)
+ (noise_2d((f_pos.xy + focus_off.xy + vec2(0.1, 0)) * 0.6) - 0.5) * sin(tick.x * 3.5 - f_pos.y * 6);
float hy = (noise_2d((f_pos.xy + focus_off.xy + vec2(0, 0.1)) * 0.3) - 0.5) * sin(tick.x * 8.0 + f_pos.x * 3)
+ (noise_2d((f_pos.xy + focus_off.xy + vec2(0, 0.1)) * 0.6) - 0.5) * sin(tick.x * 3.5 - f_pos.y * 6);
f_norm.xy += mix(vec2(0), vec2(h - hx, h - hy) / 0.1 * 0.03, puddle);
#endif
alpha = mix(1.0, 0.2, puddle);
f_col.rgb *= mix(1.0, 0.7, puddle);
k_s = mix(k_s, vec3(0.7, 0.7, 1.0), puddle);
@ -268,21 +276,17 @@ void main() {
#endif
if (rain_occlusion_at(f_pos.xyz + vec3(0, 0, 0.25)) > 0.5) {
if (fract(hash(fract(vec4(cell, 0) * 0.01))) < rain_density * 2.0 && puddle > 0.3) {
if (fract(hash(fract(vec4(cell, 0) * 0.01))) < rain_density * 2.0) {
vec3 off = vec3(hash_fast(uvec3(cell * 13)), hash_fast(uvec3(cell * 5)), 0);
vec3 near_cell = (cell + 0.5 + (off - 0.5) * 0.5) / drop_density;
float dist = length((drop_pos - near_cell) / vec3(1, 1, 2));
float drop_rad = 0.1;
float drop_rad = 0.075 + puddle * 0.05;
float distort = max(1.0 - abs(dist - drop_rad) * 100, 0) * 1.5 * max(drop_pos.z - near_cell.z, 0);
k_a += distort;
k_d += distort;
k_s += distort;
#ifdef EXPERIMENTAL_WETNESS
/* puddle = mix(puddle, 1.0, distort * 10); */
#endif
f_norm.xy += (drop_pos - near_cell).xy
* max(1.0 - abs(dist - drop_rad) * 30, 0)
* 500.0
@ -362,14 +366,18 @@ void main() {
// NOTE: Default intersection point is camera position, meaning if we fail to intersect we assume the whole camera is in water.
// Computing light attenuation from water.
vec3 cam_attenuation =
medium.x == MEDIUM_WATER ? compute_attenuation_point(cam_pos.xyz, view_dir, MU_WATER, fluid_alt, /*cam_pos.z <= fluid_alt ? cam_pos.xyz : f_pos*/f_pos)
false/*medium.x == MEDIUM_WATER*/ ? compute_attenuation_point(cam_pos.xyz, view_dir, MU_WATER, fluid_alt, /*cam_pos.z <= fluid_alt ? cam_pos.xyz : f_pos*/f_pos)
: compute_attenuation_point(f_pos, -view_dir, mu, fluid_alt, /*cam_pos.z <= fluid_alt ? cam_pos.xyz : f_pos*/cam_pos.xyz);
// Prevent the sky affecting light when underground
float not_underground = clamp((f_pos.z - f_alt) / 128.0 + 1.0, 0.0, 1.0);
// To account for prior saturation
/*float */f_light = faces_fluid ? not_underground : f_light * sqrt(f_light);
#if (FLUID_MODE == FLUID_MODE_LOW)
f_light = f_light * sqrt(f_light);
#else
f_light = faces_fluid ? not_underground : f_light * sqrt(f_light);
#endif
vec3 emitted_light = vec3(1.0);
vec3 reflected_light = vec3(1.0);
@ -396,7 +404,7 @@ void main() {
reflected_light *= 0.4 + f_ao * 0.6;
#ifndef EXPERIMENTAL_NOCAUSTICS
#if (FLUID_MODE == FLUID_MODE_SHINY)
#if (FLUID_MODE >= FLUID_MODE_MEDIUM)
if (faces_fluid) {
vec3 wpos = f_pos + vec3(focus_off.xy, 0);
vec3 spos = (wpos + (fluid_alt - wpos.z) * vec3(sun_dir.xy, 0)) * 0.25;
@ -521,5 +529,5 @@ void main() {
float f_select = (select_pos.w > 0 && select_pos.xyz == floor(f_pos - f_norm * 0.5)) ? 1.0 : 0.0;
surf_color += f_select * (surf_color + 0.1) * vec3(0.5, 0.5, 0.5);
tgt_color = vec4(surf_color, 1.0);
tgt_color = vec4(surf_color, f_alpha);
}

View File

@ -6,9 +6,9 @@
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_GLOSSY
#if (FLUID_MODE == FLUID_MODE_CHEAP)
#if (FLUID_MODE == FLUID_MODE_LOW)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
#elif (FLUID_MODE == FLUID_MODE_SHINY)
#elif (FLUID_MODE >= FLUID_MODE_MEDIUM)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
#endif

View File

@ -6,9 +6,9 @@
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_GLOSSY
#if (FLUID_MODE == FLUID_MODE_CHEAP)
#if (FLUID_MODE == FLUID_MODE_LOW)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
#elif (FLUID_MODE == FLUID_MODE_SHINY)
#elif (FLUID_MODE >= FLUID_MODE_MEDIUM)
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
#endif

View File

@ -7,7 +7,7 @@ use crate::{
},
render::{
AaMode, BloomConfig, BloomFactor, BloomMode, CloudMode, FluidMode, LightingMode,
PresentMode, RenderMode, ShadowMapMode, ShadowMode, UpscaleMode,
PresentMode, ReflectionMode, RenderMode, ShadowMapMode, ShadowMode, UpscaleMode,
},
session::settings_change::Graphics as GraphicsChange,
settings::Fps,
@ -90,6 +90,8 @@ widget_ids! {
cloud_mode_list,
fluid_mode_text,
fluid_mode_list,
reflection_mode_text,
reflection_mode_list,
fullscreen_mode_text,
fullscreen_mode_list,
//
@ -1038,12 +1040,14 @@ impl<'a> Widget for Video<'a> {
.color(TEXT_COLOR)
.set(state.ids.fluid_mode_text, ui);
let mode_list = [FluidMode::Cheap, FluidMode::Shiny];
let mode_list = [FluidMode::Low, FluidMode::Medium, FluidMode::High];
let mode_label_list = [
self.localized_strings
.get_msg("hud-settings-fluid_rendering_mode-cheap"),
.get_msg("hud-settings-fluid_rendering_mode-low"),
self.localized_strings
.get_msg("hud-settings-fluid_rendering_mode-shiny"),
.get_msg("hud-settings-fluid_rendering_mode-medium"),
self.localized_strings
.get_msg("hud-settings-fluid_rendering_mode-high"),
];
// Get which fluid rendering mode is currently active
@ -1063,13 +1067,56 @@ impl<'a> Widget for Video<'a> {
})));
}
// ReflectionMode
Text::new(
&self
.localized_strings
.get_msg("hud-settings-reflection_rendering_mode"),
)
.down_from(state.ids.fluid_mode_list, 8.0)
.font_size(self.fonts.cyri.scale(14))
.font_id(self.fonts.cyri.conrod_id)
.color(TEXT_COLOR)
.set(state.ids.reflection_mode_text, ui);
let mode_list = [
ReflectionMode::Low,
ReflectionMode::Medium,
ReflectionMode::High,
];
let mode_label_list = [
self.localized_strings
.get_msg("hud-settings-reflection_rendering_mode-low"),
self.localized_strings
.get_msg("hud-settings-reflection_rendering_mode-medium"),
self.localized_strings
.get_msg("hud-settings-reflection_rendering_mode-high"),
];
// Get which fluid rendering mode is currently active
let selected = mode_list.iter().position(|x| *x == render_mode.reflection);
if let Some(clicked) = DropDownList::new(&mode_label_list, selected)
.w_h(400.0, 22.0)
.color(MENU_BG)
.label_color(TEXT_COLOR)
.label_font_id(self.fonts.cyri.conrod_id)
.down_from(state.ids.reflection_mode_text, 8.0)
.set(state.ids.reflection_mode_list, ui)
{
events.push(GraphicsChange::ChangeRenderMode(Box::new(RenderMode {
reflection: mode_list[clicked],
..render_mode.clone()
})));
}
// LightingMode
Text::new(
&self
.localized_strings
.get_msg("hud-settings-lighting_rendering_mode"),
)
.down_from(state.ids.fluid_mode_list, 8.0)
.down_from(state.ids.reflection_mode_list, 8.0)
.font_size(self.fonts.cyri.scale(14))
.font_id(self.fonts.cyri.conrod_id)
.color(TEXT_COLOR)

View File

@ -9,7 +9,7 @@ use crate::{
scene::terrain::BlocksOfInterest,
};
use common::{
terrain::Block,
terrain::{Block, TerrainChunk},
util::either_with,
vol::{ReadVol, RectRasterableVol},
volumes::vol_grid_2d::{CachedVolGrid2d, VolGrid2d},
@ -226,8 +226,8 @@ fn calc_light<V: RectRasterableVol<Vox = Block> + ReadVol + Debug>(
}
#[allow(clippy::type_complexity)]
pub fn generate_mesh<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug + 'static>(
vol: &'a VolGrid2d<V>,
pub fn generate_mesh<'a>(
vol: &'a VolGrid2d<TerrainChunk>,
(range, max_texture_size, _boi): (Aabb<i32>, Vec2<u16>, &'a BlocksOfInterest),
) -> MeshGen<
TerrainVertex,
@ -390,7 +390,37 @@ pub fn generate_mesh<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug + '
let mesh_delta = Vec3::new(0.0, 0.0, (z_start + range.min.z) as f32);
let create_opaque =
|atlas_pos, pos, norm, meta| TerrainVertex::new(atlas_pos, pos + mesh_delta, norm, meta);
let create_transparent = |_atlas_pos, pos, norm| FluidVertex::new(pos + mesh_delta, norm);
let create_transparent = |_atlas_pos, pos: Vec3<f32>, norm| {
// TODO: It *should* be possible to pull most of this code out of this function
// and compute it per-chunk. For some reason, this doesn't work! If you,
// dear reader, feel like giving it a go then feel free. For now
// it's been kept as-is because I'm lazy and water vertices aren't nearly common
// enough for this to matter much. If you want to test whether your
// change works, look carefully at how waves interact between water
// polygons in different chunks. If the join is smooth, you've solved the
// problem!
let key = vol.pos_key(range.min + pos.as_());
let v00 = vol
.get_key(key + Vec2::new(0, 0))
.map_or(Vec3::zero(), |c| c.meta().river_velocity());
let v10 = vol
.get_key(key + Vec2::new(1, 0))
.map_or(Vec3::zero(), |c| c.meta().river_velocity());
let v01 = vol
.get_key(key + Vec2::new(0, 1))
.map_or(Vec3::zero(), |c| c.meta().river_velocity());
let v11 = vol
.get_key(key + Vec2::new(1, 1))
.map_or(Vec3::zero(), |c| c.meta().river_velocity());
let factor =
(range.min + pos.as_()).map(|e| e as f32) / TerrainChunk::RECT_SIZE.map(|e| e as f32);
let vel = Lerp::lerp(
Lerp::lerp(v00, v10, factor.x.rem_euclid(1.0)),
Lerp::lerp(v01, v11, factor.x.rem_euclid(1.0)),
factor.y.rem_euclid(1.0),
);
FluidVertex::new(pos + mesh_delta, norm, vel.xy())
};
let mut greedy =
GreedyMesh::<guillotiere::SimpleAtlasAllocator>::new(max_size, greedy::general_config());

View File

@ -151,14 +151,15 @@ impl Default for CloudMode {
/// Fluid modes
#[derive(PartialEq, Eq, Clone, Copy, Debug, Serialize, Deserialize)]
pub enum FluidMode {
/// "Cheap" water. This water implements no waves, no reflections, no
/// "Low" water. This water implements no waves, no reflections, no
/// diffraction, and no light attenuation through water. As a result,
/// it can be much cheaper than shiny reflection.
Cheap,
/// "Shiny" water. This water implements waves on the surfaces, some
/// attempt at reflections, and tries to compute accurate light
/// attenuation through water (this is what results in the
/// colors changing as you descend into deep water).
Low,
High,
/// This water implements waves on the surfaces, some attempt at
/// reflections, and tries to compute accurate light attenuation through
/// water (this is what results in the colors changing as you descend
/// into deep water).
///
/// Unfortunately, the way the engine is currently set up, calculating
/// accurate attenuation is a bit difficult; we use estimates from
@ -172,11 +173,28 @@ pub enum FluidMode {
/// which causes attenuation to be computed incorrectly; this can be
/// addressed by using shadow maps (at least for terrain).
#[serde(other)]
Shiny,
Medium,
}
impl Default for FluidMode {
fn default() -> Self { FluidMode::Shiny }
fn default() -> Self { FluidMode::Medium }
}
/// Reflection modes
#[derive(PartialEq, Eq, Clone, Copy, Debug, Serialize, Deserialize)]
pub enum ReflectionMode {
/// No or minimal reflections.
Low,
/// High quality reflections with screen-space raycasting and
/// all the bells & whistles.
High,
// Medium quality screen-space reflections.
#[serde(other)]
Medium,
}
impl Default for ReflectionMode {
fn default() -> Self { ReflectionMode::Medium }
}
/// Lighting modes
@ -358,6 +376,7 @@ impl BloomMode {
pub struct RenderMode {
pub aa: AaMode,
pub cloud: CloudMode,
pub reflection: ReflectionMode,
pub fluid: FluidMode,
pub lighting: LightingMode,
pub shadow: ShadowMode,
@ -381,6 +400,7 @@ impl Default for RenderMode {
aa: AaMode::default(),
cloud: CloudMode::default(),
fluid: FluidMode::default(),
reflection: ReflectionMode::default(),
lighting: LightingMode::default(),
shadow: ShadowMode::default(),
rain_occlusion: ShadowMapMode::default(),
@ -402,6 +422,7 @@ impl RenderMode {
aa: self.aa,
cloud: self.cloud,
fluid: self.fluid,
reflection: self.reflection,
lighting: self.lighting,
shadow: self.shadow,
rain_occlusion: self.rain_occlusion,
@ -426,6 +447,7 @@ pub struct PipelineModes {
aa: AaMode,
pub cloud: CloudMode,
fluid: FluidMode,
reflection: ReflectionMode,
lighting: LightingMode,
pub shadow: ShadowMode,
pub rain_occlusion: ShadowMapMode,
@ -497,6 +519,6 @@ pub enum ExperimentalShader {
DirectionalShadowMapTexelGrid,
/// Disable rainbows
NoRainbows,
/// Make objects appear wet when appropriate.
Wetness,
/// Add extra detailing to puddles.
PuddleDetails,
}

View File

@ -7,10 +7,11 @@ use vek::*;
#[derive(Copy, Clone, Debug, Zeroable, Pod)]
pub struct Vertex {
pos_norm: u32,
vel: u32,
}
impl Vertex {
pub fn new(pos: Vec3<f32>, norm: Vec3<f32>) -> Self {
pub fn new(pos: Vec3<f32>, norm: Vec3<f32>, river_velocity: Vec2<f32>) -> Self {
let (norm_axis, norm_dir) = norm
.as_slice()
.iter()
@ -27,11 +28,19 @@ impl Vertex {
| ((pos.y as u32) & 0x003F) << 6
| (((pos.z + EXTRA_NEG_Z).max(0.0).min((1 << 17) as f32) as u32) & 0x1FFFF) << 12
| (norm_bits & 0x7) << 29,
vel: river_velocity
.map2(Vec2::new(0, 16), |e, off| {
((e * 1000.0 + 32768.9) as u16 as u32) << off
})
.reduce_bitor(),
}
}
fn desc<'a>() -> wgpu::VertexBufferLayout<'a> {
const ATTRIBUTES: [wgpu::VertexAttribute; 1] = wgpu::vertex_attr_array![0 => Uint32];
const ATTRIBUTES: [wgpu::VertexAttribute; 2] = wgpu::vertex_attr_array![
0 => Uint32,
1 => Uint32,
];
wgpu::VertexBufferLayout {
array_stride: Self::STRIDE,
step_mode: wgpu::InputStepMode::Vertex,
@ -124,7 +133,7 @@ impl FluidPipeline {
alpha: wgpu::BlendComponent {
src_factor: wgpu::BlendFactor::One,
dst_factor: wgpu::BlendFactor::One,
operation: wgpu::BlendOperation::Add,
operation: wgpu::BlendOperation::Min,
},
}),
write_mask: wgpu::ColorWrite::ALL,

View File

@ -6,8 +6,8 @@ use super::{
blit, bloom, clouds, debug, figure, fluid, lod_object, lod_terrain, particle,
postprocess, shadow, skybox, sprite, terrain, trail, ui,
},
AaMode, BloomMode, CloudMode, FluidMode, LightingMode, PipelineModes, RenderError,
ShadowMode,
AaMode, BloomMode, CloudMode, FluidMode, LightingMode, PipelineModes, ReflectionMode,
RenderError, ShadowMode,
},
shaders::Shaders,
ImmutableLayouts, Layouts,
@ -173,6 +173,7 @@ impl ShaderModules {
#define VOXYGEN_COMPUTATION_PREFERENCE {}
#define FLUID_MODE {}
#define CLOUD_MODE {}
#define REFLECTION_MODE {}
#define LIGHTING_ALGORITHM {}
#define SHADOW_MODE {}
@ -181,8 +182,9 @@ impl ShaderModules {
// TODO: Configurable vertex/fragment shader preference.
"VOXYGEN_COMPUTATION_PREFERENCE_FRAGMENT",
match pipeline_modes.fluid {
FluidMode::Cheap => "FLUID_MODE_CHEAP",
FluidMode::Shiny => "FLUID_MODE_SHINY",
FluidMode::Low => "FLUID_MODE_LOW",
FluidMode::Medium => "FLUID_MODE_MEDIUM",
FluidMode::High => "FLUID_MODE_HIGH",
},
match pipeline_modes.cloud {
CloudMode::None => "CLOUD_MODE_NONE",
@ -192,6 +194,11 @@ impl ShaderModules {
CloudMode::High => "CLOUD_MODE_HIGH",
CloudMode::Ultra => "CLOUD_MODE_ULTRA",
},
match pipeline_modes.reflection {
ReflectionMode::Low => "REFLECTION_MODE_LOW",
ReflectionMode::Medium => "REFLECTION_MODE_MEDIUM",
ReflectionMode::High => "REFLECTION_MODE_HIGH",
},
match pipeline_modes.lighting {
LightingMode::Ashikhmin => "LIGHTING_ALGORITHM_ASHIKHMIN",
LightingMode::BlinnPhong => "LIGHTING_ALGORITHM_BLINN_PHONG",
@ -298,8 +305,8 @@ impl ShaderModules {
};
let selected_fluid_shader = ["fluid-frag.", match pipeline_modes.fluid {
FluidMode::Cheap => "cheap",
FluidMode::Shiny => "shiny",
FluidMode::Low => "cheap",
_ => "shiny",
}]
.concat();

View File

@ -1,6 +1,6 @@
use common::{terrain::TerrainGrid, vol::ReadVol};
use common_base::span;
use core::{f32::consts::PI, fmt::Debug};
use core::{f32::consts::PI, fmt::Debug, ops::Range};
use num::traits::{real::Real, FloatConst};
use treeculler::Frustum;
use vek::*;
@ -12,7 +12,7 @@ const FIRST_PERSON_INTERP_TIME: f32 = 0.1;
const THIRD_PERSON_INTERP_TIME: f32 = 0.1;
const FREEFLY_INTERP_TIME: f32 = 0.0;
const LERP_ORI_RATE: f32 = 15.0;
const CLIPPING_MODE_DISTANCE: f32 = 20.0;
const CLIPPING_MODE_RANGE: Range<f32> = 2.0..20.0;
pub const MIN_ZOOM: f32 = 0.1;
// Possible TODO: Add more modes
@ -368,7 +368,7 @@ impl Camera {
) {
span!(_guard, "compute_dependents", "Camera::compute_dependents");
// TODO: More intelligent function to decide on which strategy to use
if self.tgt_dist < CLIPPING_MODE_DISTANCE {
if self.tgt_dist < CLIPPING_MODE_RANGE.end {
self.compute_dependents_near(terrain, is_transparent)
} else {
self.compute_dependents_far(terrain, is_transparent)
@ -425,18 +425,23 @@ impl Camera {
.unwrap_or(0.0)
};
if self.dist >= dist {
self.dist = dist;
}
// Recompute only if needed
if (dist - self.tgt_dist).abs() > f32::EPSILON {
let dependents = self.compute_dependents_helper(dist);
self.frustum = self.compute_frustum(&dependents);
self.dependents = dependents;
// If the camera ends up being too close to the focus point, switch policies.
if dist < CLIPPING_MODE_RANGE.start {
self.compute_dependents_far(terrain, is_transparent);
} else {
self.dependents = local_dependents;
self.frustum = frustum;
if self.dist >= dist {
self.dist = dist;
}
// Recompute only if needed
if (dist - self.tgt_dist).abs() > f32::EPSILON {
let dependents = self.compute_dependents_helper(dist);
self.frustum = self.compute_frustum(&dependents);
self.dependents = dependents;
} else {
self.dependents = local_dependents;
self.frustum = frustum;
}
}
}

View File

@ -224,12 +224,12 @@ impl assets::Asset for SpriteSpec {
/// skip_remesh is either None (do the full remesh, including recomputing the
/// light map), or Some((light_map, glow_map)).
fn mesh_worker<V: BaseVol<Vox = Block> + RectRasterableVol + ReadVol + Debug + 'static>(
fn mesh_worker(
pos: Vec2<i32>,
z_bounds: (f32, f32),
skip_remesh: Option<(LightMapFn, LightMapFn)>,
started_tick: u64,
volume: <VolGrid2d<V> as SampleVol<Aabr<i32>>>::Sample,
volume: <VolGrid2d<TerrainChunk> as SampleVol<Aabr<i32>>>::Sample,
max_texture_size: u16,
chunk: Arc<TerrainChunk>,
range: Aabb<i32>,
@ -274,11 +274,12 @@ fn mesh_worker<V: BaseVol<Vox = Block> + RectRasterableVol + ReadVol + Debug + '
prof_span!("extract sprite_instances");
let mut instances = [(); SPRITE_LOD_LEVELS].map(|()| Vec::new());
for x in 0..V::RECT_SIZE.x as i32 {
for y in 0..V::RECT_SIZE.y as i32 {
for x in 0..TerrainChunk::RECT_SIZE.x as i32 {
for y in 0..TerrainChunk::RECT_SIZE.y as i32 {
for z in z_bounds.0 as i32..z_bounds.1 as i32 + 1 {
let rel_pos = Vec3::new(x, y, z);
let wpos = Vec3::from(pos * V::RECT_SIZE.map(|e: u32| e as i32)) + rel_pos;
let wpos = Vec3::from(pos * TerrainChunk::RECT_SIZE.map(|e: u32| e as i32))
+ rel_pos;
let block = if let Ok(block) = volume.get(wpos) {
block