mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
LOD shading closer to voxel shading.
This commit is contained in:
parent
ef67bd58ba
commit
dd74fa7e4a
@ -115,7 +115,7 @@ void main() {
|
||||
float opacity = clamp(distance / distance_divider, 0, 1);
|
||||
|
||||
if(threshold_matrix[int(gl_FragCoord.x) % 4][int(gl_FragCoord.y) % 4] > opacity) {
|
||||
tgt_color = vec4(color, 0.0);
|
||||
discard;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -64,5 +64,6 @@ void main() {
|
||||
// f_shadow = textureBicubic(t_horizon, pos_to_tex(f_pos.xy));
|
||||
|
||||
gl_Position = all_mat * vec4(f_pos, 1);
|
||||
// gl_Position.z = -gl_Position.z / 100.0;
|
||||
gl_Position.z = -1000.0 / (gl_Position.z + 10000.0);
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ 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 = srgb_to_linear(vec3(0.2, 0.5, 1.0));
|
||||
/*const */vec3 water_color = 1.0 - MU_WATER;//srgb_to_linear(vec3(0.2, 0.5, 1.0));
|
||||
// /*const */vec3 water_color = srgb_to_linear(vec3(0.0, 0.25, 0.5));
|
||||
|
||||
vec3 sun_dir = get_sun_dir(time_of_day.x);
|
||||
@ -52,13 +52,18 @@ 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;
|
||||
|
||||
float fluid_alt = max(ceil(f_pos.z), floor(f_alt));// f_alt;//max(f_alt - f_pos.z, 0.0);
|
||||
|
||||
const float alpha = 0.255/* / 4.0 / sqrt(2.0)*/;
|
||||
const float n2 = 1.3325;
|
||||
const float R_s2s0 = pow((1.0 - n2) / (1.0 + n2), 2);
|
||||
const float R_s1s0 = pow((1.3325 - n2) / (1.3325 + n2), 2);
|
||||
const float R_s2s1 = pow((1.0 - 1.3325) / (1.0 + 1.3325), 2);
|
||||
const float R_s1s2 = pow((1.3325 - 1.0) / (1.3325 + 1.0), 2);
|
||||
float R_s = (f_pos.z < f_alt) ? mix(R_s2s1 * R_s1s0, R_s1s0, medium.x) : mix(R_s2s0, R_s1s2 * R_s2s0, medium.x);
|
||||
float R_s = (f_pos.z < fluid_alt) ? mix(R_s2s1 * R_s1s0, R_s1s0, medium.x) : mix(R_s2s0, R_s1s2 * R_s2s0, medium.x);
|
||||
|
||||
// NOTE: Assumes normal is vertical.
|
||||
vec3 sun_view_dir = cam_pos.z <= fluid_alt ? /*refract(view_dir, -f_norm, 1.0 / n2)*//*reflect(view_dir, -f_norm)*/vec3(view_dir.xy, -view_dir.z) : view_dir;
|
||||
|
||||
vec3 k_a = vec3(1.0);
|
||||
vec3 k_d = vec3(1.0);
|
||||
@ -78,7 +83,7 @@ void main() {
|
||||
|
||||
// vec3 surf_color = /*srgb_to_linear*/(vec3(0.4, 0.7, 2.0));
|
||||
float max_light = 0.0;
|
||||
max_light += get_sun_diffuse2(f_norm, /*time_of_day.x*/sun_dir, moon_dir, /*-cam_to_frag*/view_dir, k_a/* * (shade_frac * 0.5 + light_frac * 0.5)*/, vec3(0.0), k_s, alpha, emitted_light, reflected_light);
|
||||
max_light += get_sun_diffuse2(f_norm, /*time_of_day.x*/sun_dir, moon_dir, /*-cam_to_frag*/sun_view_dir, k_a/* * (shade_frac * 0.5 + light_frac * 0.5)*/, /*vec3(0.0)*/k_d, k_s, alpha, emitted_light, reflected_light);
|
||||
reflected_light *= f_light * point_shadow * shade_frac;
|
||||
emitted_light *= f_light * point_shadow * max(shade_frac, MIN_SHADOW);
|
||||
max_light *= f_light * point_shadow * shade_frac;
|
||||
@ -96,16 +101,18 @@ void main() {
|
||||
emitted_light += point_light;
|
||||
reflected_light += point_light; */
|
||||
|
||||
vec3 diffuse_light_point = vec3(0.0);
|
||||
max_light += lights_at(f_pos, f_norm, view_dir, k_a, vec3(1.0), k_s, alpha, emitted_light, diffuse_light_point);
|
||||
max_light += lights_at(f_pos, f_norm, view_dir, /*vec3(0.0), vec3(1.0), fluid_alt, */k_a, k_d, k_s, alpha, emitted_light, reflected_light);
|
||||
// vec3 diffuse_light_point = vec3(0.0);
|
||||
// max_light += lights_at(f_pos, f_norm, view_dir, k_a, vec3(1.0), k_s, alpha, emitted_light, diffuse_light_point);
|
||||
|
||||
vec3 dump_light = vec3(0.0);
|
||||
vec3 specular_light_point = vec3(0.0);
|
||||
lights_at(f_pos, f_norm, view_dir, vec3(0.0), vec3(0.0), /*vec3(1.0)*/k_s, alpha, dump_light, specular_light_point);
|
||||
diffuse_light_point -= specular_light_point;
|
||||
float reflected_light_point = length(reflected_light);///*length*/(diffuse_light_point.r) + f_light * point_shadow;
|
||||
// vec3 dump_light = vec3(0.0);
|
||||
// vec3 specular_light_point = vec3(0.0);
|
||||
// lights_at(f_pos, f_norm, view_dir, vec3(0.0), vec3(0.0), /*vec3(1.0)*/k_s, alpha, dump_light, specular_light_point);
|
||||
// diffuse_light_point -= specular_light_point;
|
||||
|
||||
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 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 fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
|
||||
vec4 clouds;
|
||||
@ -114,7 +121,7 @@ void main() {
|
||||
float passthrough = /*pow(*/dot(faceforward(f_norm, f_norm, cam_to_frag/*view_dir*/), -cam_to_frag/*view_dir*/)/*, 0.5)*/;
|
||||
|
||||
vec3 surf_color = illuminate(max_light, water_color * fog_color * emitted_light, /*surf_color * */water_color * reflected_light);
|
||||
vec4 color = mix(vec4(surf_color, 1.0), vec4(surf_color, 1.0 / (1.0 + /*diffuse_light*//*(f_light * point_shadow + point_light)*/reflected_light_point/* * 0.25*/)), passthrough);
|
||||
vec4 color = mix(vec4(surf_color, 1.0), vec4(surf_color, 1.0 / (1.0 + /*diffuse_light*//*(f_light * point_shadow + point_light)*/4.0 * reflected_light_point/* * 0.25*/)), passthrough);
|
||||
|
||||
tgt_color = mix(mix(color, vec4(fog_color, 0.0), fog_level), vec4(clouds.rgb, 0.0), clouds.a);
|
||||
}
|
||||
|
@ -101,8 +101,9 @@ void main() {
|
||||
nmap = mix(f_norm, normalize(nmap), min(1.0 / pow(frag_dist, 0.75), 1));
|
||||
|
||||
vec3 norm = vec3(0, 0, 1) * nmap.z + b_norm * nmap.x + c_norm * nmap.y;
|
||||
// vec3 norm = f_norm;
|
||||
|
||||
float f_alt = alt_at_real(f_pos.xy);
|
||||
float f_alt = alt_at(f_pos.xy);
|
||||
|
||||
float fluid_alt = max(ceil(f_pos.z), floor(f_alt));// f_alt;//max(f_alt - f_pos.z, 0.0);
|
||||
const float alpha = 0.255/*/ / 4.0*//* / 4.0 / sqrt(2.0)*/;
|
||||
@ -118,7 +119,8 @@ void main() {
|
||||
vec4 _clouds;
|
||||
vec3 reflect_ray_dir = reflect(cam_to_frag/*-view_dir*/, norm);
|
||||
vec3 refract_ray_dir = refract(cam_to_frag/*-view_dir*/, norm, 1.0 / n2);
|
||||
vec3 sun_view_dir = cam_pos.z <= fluid_alt ? -view_dir : view_dir;
|
||||
vec3 sun_view_dir = /*sign(cam_pos.z - fluid_alt) * view_dir;*/cam_pos.z <= fluid_alt ? -view_dir : view_dir;
|
||||
// vec3 sun_view_dir = cam_pos.z <= fluid_alt ? -view_dir : view_dir;
|
||||
vec3 beam_view_dir = reflect_ray_dir;//cam_pos.z <= fluid_alt ? -refract_ray_dir : reflect_ray_dir;
|
||||
/* vec4 reflect_ray_dir4 = view_mat * vec4(reflect_ray_dir, 1.0);
|
||||
reflect_ray_dir = normalize(vec3(reflect_ray_dir4) / reflect_ray_dir4.w); */
|
||||
@ -130,7 +132,7 @@ void main() {
|
||||
// /*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.
|
||||
// See https://en.wikipedia.org/wiki/Electromagnetic_absorption_by_water
|
||||
/*const */vec3 water_attenuation = vec3(0.8, 0.05, 0.01);
|
||||
/*const */vec3 water_attenuation = MU_WATER;// vec3(0.8, 0.05, 0.01);
|
||||
// /*const */vec3 water_color = vec3(0.2, 0.95, 0.99);
|
||||
|
||||
vec3 sun_dir = get_sun_dir(time_of_day.x);
|
||||
@ -192,7 +194,7 @@ void main() {
|
||||
float passthrough = /*pow(*/dot(faceforward(f_norm, f_norm, cam_to_frag/*view_dir*/), -cam_to_frag/*view_dir*/)/*, 0.5)*/;
|
||||
|
||||
float max_light = 0.0;
|
||||
max_light += get_sun_diffuse2(norm, /*time_of_day.x*/sun_dir, moon_dir, 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, emitted_light, reflected_light);
|
||||
max_light += get_sun_diffuse2(norm, /*time_of_day.x*/sun_dir, moon_dir, 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, 1.0, emitted_light, reflected_light);
|
||||
reflected_light *= /*water_color_direct * */reflect_color * f_light * point_shadow * shade_frac;
|
||||
emitted_light *= /*water_color_direct*//*ambient_attenuation * */f_light * point_shadow * max(shade_frac, MIN_SHADOW);
|
||||
max_light *= f_light * point_shadow * shade_frac;
|
||||
@ -252,7 +254,8 @@ void main() {
|
||||
//vec4 color = vec4(surf_color, 1.0);
|
||||
// vec4 color = mix(vec4(reflect_color, 1.0), vec4(surf_color, 1.0 / (1.0 + /*diffuse_light*/(/*f_light * point_shadow*/reflected_light_point/* + point_light*//*reflected_light*/))), passthrough);
|
||||
|
||||
vec4 color = vec4(surf_color, 1.0 - passthrough * /*log(1.0 + cam_attenuation)*/cam_attenuation);
|
||||
float log_cam = log(min(cam_attenuation.r, min(cam_attenuation.g, cam_attenuation.b)));
|
||||
vec4 color = vec4(surf_color, passthrough * (1.0 - /*log(1.0 + cam_attenuation)*//*cam_attenuation*/1.0 / (1.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));
|
||||
|
||||
|
@ -41,5 +41,6 @@ void main() {
|
||||
gl_Position =
|
||||
all_mat *
|
||||
vec4(f_pos, 1);
|
||||
// gl_Position.z = -gl_Position.z / 100.0;
|
||||
gl_Position.z = -1000.0 / (gl_Position.z + 10000.0);
|
||||
}
|
||||
|
@ -8,13 +8,13 @@ const float PI = 3.141592;
|
||||
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_BOT = vec3(0.1, 0.2, 0.3);
|
||||
const vec3 DAY_LIGHT = vec3(1.0, 1.0, 1.0);
|
||||
const vec3 DAY_LIGHT = vec3(1.5, 1.4, 1.0);
|
||||
const vec3 SUN_HALO_DAY = vec3(0.35, 0.35, 0.0);
|
||||
|
||||
const vec3 SKY_DUSK_TOP = vec3(0.06, 0.1, 0.20);
|
||||
const vec3 SKY_DUSK_MID = vec3(0.35, 0.1, 0.15);
|
||||
const vec3 SKY_DUSK_BOT = vec3(0.0, 0.1, 0.23);
|
||||
const vec3 DUSK_LIGHT = vec3(3.0, 1.5, 0.3);
|
||||
const vec3 DUSK_LIGHT = vec3(8.0, 1.5, 0.15);
|
||||
const vec3 SUN_HALO_DUSK = vec3(1.2, 0.15, 0.0);
|
||||
|
||||
const vec3 SKY_NIGHT_TOP = vec3(0.001, 0.001, 0.0025);
|
||||
@ -135,7 +135,7 @@ vec3 get_moon_color(vec3 moon_dir) {
|
||||
// mu is the attenuation coefficient for any substance on a horizontal plane.
|
||||
// cam_attenuation is the total light attenuation due to the substance for beams between the point and the camera.
|
||||
// surface_alt is the altitude of the attenuating surface.
|
||||
float get_sun_diffuse2(vec3 norm, vec3 sun_dir, vec3 moon_dir, vec3 dir, vec3 wpos, vec3 mu, vec3 cam_attenuation, float surface_alt, vec3 k_a, vec3 k_d, vec3 k_s, float alpha, out vec3 emitted_light, out vec3 reflected_light) {
|
||||
float get_sun_diffuse2(vec3 norm, vec3 sun_dir, vec3 moon_dir, vec3 dir, vec3 wpos, vec3 mu, vec3 cam_attenuation, float surface_alt, vec3 k_a, vec3 k_d, vec3 k_s, float alpha, float voxel_lighting, out vec3 emitted_light, out vec3 reflected_light) {
|
||||
const vec3 SUN_AMBIANCE = MU_SCATTER;//0.23;/* / 1.8*/;// 0.1 / 3.0;
|
||||
const vec3 MOON_AMBIANCE = MU_SCATTER;//0.23;//0.1;
|
||||
|
||||
@ -239,7 +239,7 @@ float get_sun_diffuse2(vec3 norm, vec3 sun_dir, vec3 moon_dir, vec3 dir, vec3 wp
|
||||
vec3 R_t_r = R_d + R_r;
|
||||
|
||||
// vec3 half_vec = normalize(-norm + dir);
|
||||
vec3 light_frac = R_t_b * (sun_chroma * SUN_AMBIANCE + moon_chroma * MOON_AMBIANCE) * light_reflection_factor(norm, /*norm*//*dir*/dir, /*-norm*/-dir, /*k_d*/k_d/* * (1.0 - k_s)*/, /*k_s*/vec3(0.0), alpha);
|
||||
vec3 light_frac = R_t_b * (sun_chroma * SUN_AMBIANCE + moon_chroma * MOON_AMBIANCE) * light_reflection_factor(norm, /*norm*//*dir*/dir, /*-norm*/-dir, /*k_d*/k_d/* * (1.0 - k_s)*/, /*k_s*/vec3(0.0), alpha, voxel_lighting);
|
||||
// vec3 light_frac = /*vec3(1.0)*//*H_d * */
|
||||
// SUN_AMBIANCE * /*sun_light*/sun_chroma * light_reflection_factor(norm, dir, /*vec3(0, 0, -1.0)*/-norm, vec3((1.0 + cos_sun) * 0.5), vec3(k_s * (1.0 - cos_sun) * 0.5), alpha) +
|
||||
// MOON_AMBIANCE * /*sun_light*/moon_chroma * light_reflection_factor(norm, dir, /*vec3(0, 0, -1.0)*/-norm, vec3((1.0 + cos_moon) * 0.5), vec3(k_s * (1.0 - cos_moon) * 0.5), alpha);
|
||||
@ -259,10 +259,10 @@ float get_sun_diffuse2(vec3 norm, vec3 sun_dir, vec3 moon_dir, vec3 dir, vec3 wp
|
||||
|
||||
// TODO: Add shadows.
|
||||
reflected_light = R_t_r * (
|
||||
(1.0 - SUN_AMBIANCE) * sun_chroma * (light_reflection_factor(norm, dir, sun_dir, k_d, k_s, alpha) /*+
|
||||
(1.0 - SUN_AMBIANCE) * sun_chroma * (light_reflection_factor(norm, dir, sun_dir, k_d, k_s, alpha, voxel_lighting) /*+
|
||||
light_reflection_factor(norm, dir, normalize(sun_dir + vec3(0.0, 0.1, 0.0)), k_d, k_s, alpha) +
|
||||
light_reflection_factor(norm, dir, normalize(sun_dir - vec3(0.0, 0.1, 0.0)), k_d, k_s, alpha)*/) +
|
||||
(1.0 - MOON_AMBIANCE) * moon_chroma * 1.0 * /*4.0 * */light_reflection_factor(norm, dir, moon_dir, k_d, k_s, alpha)
|
||||
(1.0 - MOON_AMBIANCE) * moon_chroma * 1.0 * /*4.0 * */light_reflection_factor(norm, dir, moon_dir, k_d, k_s, alpha, voxel_lighting)
|
||||
);
|
||||
|
||||
/* light = sun_chroma + moon_chroma + PERSISTENT_AMBIANCE;
|
||||
@ -274,8 +274,12 @@ float get_sun_diffuse2(vec3 norm, vec3 sun_dir, vec3 moon_dir, vec3 dir, vec3 wp
|
||||
return rel_luminance(emitted_light + reflected_light);//rel_luminance(emitted_light + reflected_light);//sun_chroma + moon_chroma + PERSISTENT_AMBIANCE;
|
||||
}
|
||||
|
||||
float get_sun_diffuse2(vec3 norm, vec3 sun_dir, vec3 moon_dir, vec3 dir, vec3 k_a, vec3 k_d, vec3 k_s, float alpha, float voxel_lighting, out vec3 emitted_light, out vec3 reflected_light) {
|
||||
return get_sun_diffuse2(norm, sun_dir, moon_dir, dir, vec3(0.0), vec3(0.0), vec3(1.0), 0.0, k_a, k_d, k_s, alpha, voxel_lighting, emitted_light, reflected_light);
|
||||
}
|
||||
|
||||
float get_sun_diffuse2(vec3 norm, vec3 sun_dir, vec3 moon_dir, vec3 dir, vec3 k_a, vec3 k_d, vec3 k_s, float alpha, out vec3 emitted_light, out vec3 reflected_light) {
|
||||
return get_sun_diffuse2(norm, sun_dir, moon_dir, dir, vec3(0.0), vec3(0.0), vec3(1.0), 0.0, k_a, k_d, k_s, alpha, emitted_light, reflected_light);
|
||||
return get_sun_diffuse2(norm, sun_dir, moon_dir, dir, vec3(0.0), vec3(0.0), vec3(1.0), 0.0, k_a, k_d, k_s, alpha, 1.0, emitted_light, reflected_light);
|
||||
}
|
||||
|
||||
// This has been extracted into a function to allow quick exit when detecting a star.
|
||||
@ -299,11 +303,14 @@ float is_star_at(vec3 dir) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
vec3 get_sky_color(vec3 dir, float time_of_day, vec3 origin, vec3 f_pos, float quality, bool with_stars, out vec4 clouds) {
|
||||
vec3 get_sky_color(vec3 dir, float time_of_day, vec3 origin, vec3 f_pos, float quality, bool with_stars, float refractionIndex, out vec4 clouds) {
|
||||
// Sky color
|
||||
vec3 sun_dir = get_sun_dir(time_of_day);
|
||||
vec3 moon_dir = get_moon_dir(time_of_day);
|
||||
|
||||
// sun_dir = sun_dir.z <= 0 ? refract(sun_dir/*-view_dir*/, vec3(0.0, 0.0, 1.0), refractionIndex) : sun_dir;
|
||||
// moon_dir = moon_dir.z <= 0 ? refract(moon_dir/*-view_dir*/, vec3(0.0, 0.0, 1.0), refractionIndex) : moon_dir;
|
||||
|
||||
// Add white dots for stars. Note these flicker and jump due to FXAA
|
||||
float star = 0.0;
|
||||
if (with_stars) {
|
||||
@ -321,7 +328,7 @@ vec3 get_sky_color(vec3 dir, float time_of_day, vec3 origin, vec3 f_pos, float q
|
||||
);
|
||||
|
||||
vec3 sun_halo = pow(max(dot(dir, -sun_dir) + 0.1, 0.0), 8.0) * sun_halo_color;
|
||||
vec3 sun_surf = pow(max(dot(dir, -sun_dir) - 0.001, 0.0), 3000.0) * SUN_SURF_COLOR;
|
||||
vec3 sun_surf = pow(max(dot(dir, -sun_dir) - 0.001, 0.0), 3000.0) * SUN_SURF_COLOR * SUN_COLOR_FACTOR;
|
||||
vec3 sun_light = (sun_halo + sun_surf) * clamp(dir.z * 10.0, 0, 1);
|
||||
|
||||
// Moon
|
||||
@ -388,6 +395,10 @@ vec3 get_sky_color(vec3 dir, float time_of_day, vec3 origin, vec3 f_pos, float q
|
||||
return mix(sky_color, clouds.rgb, clouds.a);
|
||||
}
|
||||
|
||||
vec3 get_sky_color(vec3 dir, float time_of_day, vec3 origin, vec3 f_pos, float quality, bool with_stars, out vec4 clouds) {
|
||||
return get_sky_color(dir, time_of_day, origin, f_pos, quality, with_stars, 1.0, clouds);
|
||||
}
|
||||
|
||||
float fog(vec3 f_pos, vec3 focus_pos, uint medium) {
|
||||
return max(1.0 - 5000.0 / (1.0 + distance(f_pos.xy, focus_pos.xy)), 0.0);
|
||||
|
||||
|
@ -25,6 +25,11 @@ float pow5(float x) {
|
||||
return x2 * x2 * x;
|
||||
}
|
||||
|
||||
vec4 pow5(vec4 x) {
|
||||
vec4 x2 = x * x;
|
||||
return x2 * x2 * x;
|
||||
}
|
||||
|
||||
// Fresnel angle for perfectly specular dialectric materials.
|
||||
|
||||
// Schlick approximation
|
||||
@ -43,6 +48,54 @@ float BeckmannDistribution_D(float NdotH, float alpha) {
|
||||
return mix(k_spec, 0.0, NdotH == 0.0);
|
||||
}
|
||||
|
||||
// Voxel Distribution
|
||||
float BeckmannDistribution_D_Voxel(vec3 wh, vec3 norm, float alpha) {
|
||||
vec3 sides = sign(norm);
|
||||
// vec3 cos_sides_i = /*sides * */sides * norm;
|
||||
// vec3 cos_sides_o = max(sides * view_dir, 0.0);
|
||||
|
||||
vec3 NdotH = max(wh * sides, 0.0);/*cos_sides_i*///max(sides * wh, 0.0);
|
||||
|
||||
const float PI = 3.1415926535897932384626433832795;
|
||||
vec3 NdotH2 = NdotH * NdotH;
|
||||
vec3 NdotH2m2 = NdotH2 * alpha * alpha;
|
||||
vec3 k_spec = exp((NdotH2 - 1) / NdotH2m2) / (PI * NdotH2m2 * NdotH2);
|
||||
return dot(mix(k_spec, /*cos_sides_o*/vec3(0.0), equal(NdotH, vec3(0.0))), /*cos_sides_i*/abs(norm));
|
||||
// // const float PI = 3.1415926535897932384626433832795;
|
||||
// const vec3 normals[6] = vec3[](vec3(1,0,0), vec3(0,1,0), vec3(0,0,1), vec3(-1,0,0), vec3(0,-1,0), vec3(0,0,-1));
|
||||
|
||||
// float voxel_norm = 0.0;
|
||||
// for (int i = 0; i < 6; i ++) {
|
||||
// // Light reflecting off the half-angle can shine on up to three sides.
|
||||
// // So, the idea here is to figure out the ratio of visibility of each of these
|
||||
// // three sides such that their sum adds to 1, then computing a Beckmann Distribution for each side times
|
||||
// // the this ratio.
|
||||
// //
|
||||
// // The ratio of these normals in each direction should be the sum of their cosines with the light over π,
|
||||
// // I think.
|
||||
// //
|
||||
// // cos (wh, theta)
|
||||
// //
|
||||
// // - one normal
|
||||
// //
|
||||
// // The ratio of each of the three exposed sides should just be the slope.
|
||||
// vec3 side = normals[i];
|
||||
// float side_share = max(dot(norm, side), 0.0);
|
||||
// float NdotH = max(dot(wh, side), 0.0);
|
||||
// voxel_norm += side_share * BeckmannDistribution_D(NdotH, alpha);
|
||||
// // voxel_norm += normals[i] * side_visible * max(dot(-cam_dir, normals[i]), 0.0);
|
||||
// // voxel_norm += normals[i] * side_visible * max(dot(-cam_dir, normals[i]), 0.0);
|
||||
// }
|
||||
|
||||
// /* float NdotH = dot(wh, norm);
|
||||
// float NdotH2 = NdotH * NdotH;
|
||||
// float NdotH2m2 = NdotH2 * alpha * alpha;
|
||||
|
||||
// float k_spec = exp((NdotH2 - 1) / NdotH2m2) / (PI * NdotH2m2 * NdotH2);
|
||||
// return mix(k_spec, 0.0, NdotH == 0.0); */
|
||||
// return voxel_norm;
|
||||
}
|
||||
|
||||
float BeckmannDistribution_Lambda(vec3 norm, vec3 dir, float alpha) {
|
||||
float CosTheta = /*max(dot(norm, dir), 0.0);*/dot(norm, dir);
|
||||
/* if (CosTheta == 0.0) {
|
||||
@ -98,6 +151,7 @@ vec3 FresnelBlend_f(vec3 norm, vec3 dir, vec3 light_dir, vec3 R_d, vec3 R_s, flo
|
||||
alpha = alpha * sqrt(2.0);
|
||||
float cos_wi = /*max(*/dot(-light_dir, norm)/*, 0.0)*/;
|
||||
float cos_wo = /*max(*/dot(dir, norm)/*, 0.0)*/;
|
||||
|
||||
vec3 diffuse = (28.0 / (23.0 * PI)) * R_d *
|
||||
(1.0 - R_s) *
|
||||
(1.0 - pow5(1.0 - 0.5 * abs(cos_wi))) *
|
||||
@ -134,6 +188,41 @@ vec3 FresnelBlend_f(vec3 norm, vec3 dir, vec3 light_dir, vec3 R_d, vec3 R_s, flo
|
||||
return mix(/*diffuse*//* + specular*/diffuse + specular, vec3(0.0), bvec3(all(equal(light_dir, dir))));
|
||||
}
|
||||
|
||||
// Fresnel blending
|
||||
//
|
||||
// http://www.pbr-book.org/3ed-2018/Reflection_Models/Microfacet_Models.html#fragment-MicrofacetDistributionPublicMethods-2
|
||||
// and
|
||||
// http://www.pbr-book.org/3ed-2018/Reflection_Models/Fresnel_Incidence_Effects.html
|
||||
vec3 FresnelBlend_Voxel_f(vec3 norm, vec3 dir, vec3 light_dir, vec3 R_d, vec3 R_s, float alpha, float dist) {
|
||||
const float PI = 3.1415926535897932384626433832795;
|
||||
alpha = alpha * sqrt(2.0);
|
||||
float cos_wi = /*max(*/dot(-light_dir, norm)/*, 0.0)*/;
|
||||
float cos_wo = /*max(*/dot(dir, norm)/*, 0.0)*/;
|
||||
|
||||
vec3 sides = sign(norm);
|
||||
vec4 diffuse_factor =
|
||||
(1.0 - pow5(1.0 - 0.5 * max(vec4(-light_dir * sides, abs(cos_wi)), 0.0))) *
|
||||
(1.0 - pow5(1.0 - 0.5 * max(vec4(dir * sides, abs(cos_wo)), 0.0)));
|
||||
|
||||
vec3 diffuse = (28.0 / (23.0 * PI)) * R_d *
|
||||
(1.0 - R_s) *
|
||||
dot(diffuse_factor, vec4(abs(norm) * (1.0 - dist), dist));
|
||||
|
||||
vec3 wh = -light_dir + dir;
|
||||
if (cos_wi <= 0.0 || cos_wo <= 0.0) {
|
||||
return vec3(/*diffuse*/0.0);
|
||||
}
|
||||
wh = normalize(wh);//mix(normalize(wh), vec3(0.0), equal(light_dir, dir));
|
||||
float dot_wi_wh = dot(-light_dir, wh);
|
||||
float distr = BeckmannDistribution_D_Voxel(wh, norm, alpha);
|
||||
// float distr = BeckmannDistribution_D(dot(wh, norm), alpha);
|
||||
vec3 specular = distr /
|
||||
(4 * abs(dot_wi_wh)) *
|
||||
max(abs(cos_wi), abs(cos_wo)) *
|
||||
schlick_fresnel(R_s, dot_wi_wh);
|
||||
return mix(/*diffuse*//* + specular*/diffuse + specular, vec3(0.0), bvec3(all(equal(light_dir, dir))));
|
||||
}
|
||||
|
||||
// Phong reflection.
|
||||
//
|
||||
// Note: norm, dir, light_dir must all be normalizd.
|
||||
@ -201,6 +290,14 @@ vec3 light_reflection_factor(vec3 norm, vec3 dir, vec3 light_dir, vec3 k_d, vec3
|
||||
// // return vec3(0.0);
|
||||
}
|
||||
|
||||
vec3 light_reflection_factor(vec3 norm, vec3 dir, vec3 light_dir, vec3 k_d, vec3 k_s, float alpha, float voxel_lighting) {
|
||||
if (voxel_lighting < 1.0) {
|
||||
return FresnelBlend_Voxel_f(norm, dir, light_dir, k_d/* * max(dot(norm, -light_dir), 0.0)*/, k_s, alpha, voxel_lighting);
|
||||
} else {
|
||||
return FresnelBlend_f(norm, dir, light_dir, k_d/* * max(dot(norm, -light_dir), 0.0)*/, k_s, alpha);
|
||||
}
|
||||
}
|
||||
|
||||
float rel_luminance(vec3 rgb)
|
||||
{
|
||||
// https://en.wikipedia.org/wiki/Relative_luminance
|
||||
@ -242,13 +339,14 @@ bool IntersectRayPlane(vec3 rayOrigin, vec3 rayDirection, vec3 posOnPlane, vec3
|
||||
// Ideally, defaultpos is set so we can avoid branching on error.
|
||||
vec3 compute_attenuation(vec3 wpos, vec3 ray_dir, vec3 mu, float surface_alt, vec3 defaultpos) {
|
||||
// return vec3(1.0);
|
||||
/*if (dot(mu, mu) == 0.0) {
|
||||
/*if (mu == vec3(0.0)) {
|
||||
return vec3(1.0);
|
||||
}*//* else {
|
||||
return vec3(0.0);
|
||||
}*/
|
||||
// return vec3(0.0);
|
||||
vec3 surface_dir = surface_alt < wpos.z ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 0.0, -1.0);
|
||||
vec3 surface_dir = /*surface_alt < wpos.z ? vec3(0.0, 0.0, -1.0) : vec3(0.0, 0.0, 1.0)*/vec3(0.0, 0.0, sign(surface_alt - wpos.z));
|
||||
// vec3 surface_dir = surface_alt < wpos.z ? vec3(0.0, 0.0, -1.0) : vec3(0.0, 0.0, 1.0);
|
||||
// vec3 surface_dir = faceforward(vec3(0.0, 0.0, 1.0), ray_dir, vec3(0.0, 0.0, 1.0));
|
||||
bool _intersects_surface = IntersectRayPlane(wpos, ray_dir, vec3(0.0, 0.0, surface_alt), surface_dir, defaultpos);
|
||||
float depth = length(defaultpos - wpos);
|
||||
@ -259,13 +357,14 @@ 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) {
|
||||
// return vec3(1.0);
|
||||
/*if (dot(mu, mu) == 0.0) {
|
||||
/*if (mu == vec3(0.0)) {
|
||||
return vec3(1.0);
|
||||
}*//* else {
|
||||
return vec3(0.0);
|
||||
}*/
|
||||
// return vec3(0.0);
|
||||
vec3 surface_dir = surface_alt < wpos.z ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 0.0, -1.0);
|
||||
vec3 surface_dir = /*surface_alt < wpos.z ? vec3(0.0, 0.0, -1.0) : vec3(0.0, 0.0, 1.0)*/vec3(0.0, 0.0, sign(wpos.z - surface_alt));
|
||||
// vec3 surface_dir = surface_alt < wpos.z ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 0.0, -1.0);
|
||||
// vec3 surface_dir = faceforward(vec3(0.0, 0.0, 1.0), ray_dir, vec3(0.0, 0.0, 1.0));
|
||||
float max_length = dot(defaultpos - wpos, defaultpos - wpos);
|
||||
bool _intersects_surface = IntersectRayPlane(wpos, ray_dir, vec3(0.0, 0.0, surface_alt), surface_dir, defaultpos);
|
||||
|
@ -87,6 +87,82 @@ void main() {
|
||||
vec3 view_dir = -cam_to_frag;
|
||||
// vec3 view_dir = normalize(f_pos - cam_pos.xyz);
|
||||
|
||||
// const vec3 normals[3] = vec3[](vec3(1,0,0), vec3(0,1,0), vec3(0,0,1));//, vec3(-1,0,0), vec3(0,-1,0), vec3(0,0,-1));
|
||||
// const mat3 side_norms = vec3(1, 0, 0), vec3(0, 1, 0), vec3(0, 0, 1);
|
||||
// mat3 sides = mat3(
|
||||
// /*vec3(1, 0, 0),
|
||||
// vec3(0, 1, 0),
|
||||
// vec3(0, 0, 1)*/
|
||||
// vec3(1, 0, 0),
|
||||
// // faceforward(vec3(1, 0, 0), -f_norm, vec3(1, 0, 0)),
|
||||
// vec3(0, 1, 0),
|
||||
// // faceforward(vec3(0, 1, 0), -f_norm, vec3(0, 1, 0)),
|
||||
// vec3(0, 0, 1)
|
||||
// // faceforward(vec3(0, 0, 1), -f_norm, vec3(0, 0, 1))
|
||||
// );
|
||||
|
||||
// This vector is shorthand for a diagonal matrix, which works because:
|
||||
// (1) our voxel normal vectors are exactly the basis vectors in worldspace;
|
||||
// (2) only 3 of them can be in the direction of the actual normal anyway.
|
||||
// (NOTE: This normal should always be pointing up, so implicitly sides.z = 1.0).
|
||||
// vec3 sides = sign(f_norm);
|
||||
// // NOTE: Should really be sides * f_norm, i.e. abs(f_norm), but voxel_norm would then re-multiply by sides so it cancels out.
|
||||
// vec3 cos_sides_i = sides * f_norm;
|
||||
// vec3 cos_sides_o = sides * view_dir;
|
||||
// // vec3 side_factor_i = cos_sides_i;
|
||||
// // vec3 side_factor_i = f_norm;
|
||||
// // vec3 side_factor_i = cos_sides_o;
|
||||
// vec3 side_factor_i = 1.0 - pow(1.0 - 0.5 * cos_sides_i, vec3(5));
|
||||
// // vec3 side_factor_i = /*abs*/sign(f_norm) * cos_sides_i;//max(cos_sides_i, 0.0);// 1.0 - pow(1.0 - 0.5 * cos_sides_i, vec3(5.0)); // max(sides * f_norm, vec3(0.0));//
|
||||
// // vec3 side_factor_i = /*abs*/sign(f_norm) * cos_sides_i;//max(cos_sides_i, 0.0);// 1.0 - pow(1.0 - 0.5 * cos_sides_i, vec3(5.0)); // max(sides * f_norm, vec3(0.0));//
|
||||
// // vec3 side_factor_o = max(cos_sides_o, 0.0);// 1.0 - pow(1.0 - 0.5 * max(cos_sides_o, 0.0), vec3(5));
|
||||
// vec3 side_factor_o = 1.0 - pow(1.0 - 0.5 * max(cos_sides_o, 0.0), vec3(5));
|
||||
// // vec3 side_factor_o = max(cos_sides_o, 0.0);// 1.0 - pow(1.0 - 0.5 * max(cos_sides_o, vec3(0.0)), vec3(5.0));//max(sides * view_dir/* * sign(cos_sides_i) */, vec3(0.0));
|
||||
// // vec3 side_factor_o = max(sides * view_dir/* * cos_sides_o*/, 0.0);// 1.0 - pow(1.0 - 0.5 * max(cos_sides_o, vec3(0.0)), vec3(5.0));//max(sides * view_dir/* * sign(cos_sides_i) */, vec3(0.0));
|
||||
// // NOTE: side = transpose(sides), so we avoid the extra operatin.
|
||||
// // We multply the vector by the matrix from the *left*, so each normal gets multiplied by the corresponding factor.
|
||||
// // vec3 voxel_norm = normalize(/*sides * *//*sqrt(1.0 - cos_sides_i * cos_sides_i)*/(side_factor_i * side_factor_o));
|
||||
// vec3 voxel_norm = normalize(/*sides * *//*sqrt(1.0 - cos_sides_i * cos_sides_i)*/((28.0 / (23.0 * PI)) * side_factor_i * side_factor_o * sides));
|
||||
// vec3 voxel_norm = normalize(sign(f_norm) * sqrt(abs(f_norm)) * max(sign(f_norm) * view_dir, 0.0));
|
||||
float f_ao = 1.0;//1.0;//sqrt(dot(cos_sides_i, cos_sides_i) / 3.0);
|
||||
// float f_ao = 0.2;
|
||||
// sqrt(dot(sqrt(1.0 - cos_sides_i * cos_sides_i)), 1.0 - cos_sides_o/* * cos_sides_o*/);// length(sqrt(1.0 - cos_sides_o * cos_sides_o) / cos_sides_i * cos_sides_o);
|
||||
// f_ao = f_ao * f_ao;
|
||||
|
||||
// /* vec3 voxel_norm = vec3(0.0);
|
||||
// for (int i = 0; i < 3; i ++) {
|
||||
// // Light reflecting off the half-angle can shine on up to three sides.
|
||||
// // So, the idea here is to figure out the ratio of visibility of each of these
|
||||
// // three sides such that their sum adds to 1, then computing a Beckmann Distribution for each side times
|
||||
// // the this ratio.
|
||||
// //
|
||||
// // The ratio of these normals in each direction should be the sum of their cosines with the light over π,
|
||||
// // I think.
|
||||
// //
|
||||
// // cos (wh, theta)
|
||||
// //
|
||||
// // - one normal
|
||||
// //
|
||||
// // The ratio of each of the three exposed sides should just be the slope.
|
||||
// vec3 side = normals[i];
|
||||
// side = faceforward(side, -f_norm, side);
|
||||
// float cos_wi = max(dot(f_norm, side), 0.0);
|
||||
// float cos_wo = max(dot(view_dir, side), 0.0);
|
||||
// float share = cos_wi * cos_wo;
|
||||
// // float share = (1.0 - pow5(1.0 - 0.5 * cos_wi)) * (1.0 - pow5(1.0 - 0.5 * cos_wo));
|
||||
// voxel_norm += share * side;
|
||||
// // voxel_norm += normals[i] * side_visible * max(dot(-cam_dir, normals[i]), 0.0);
|
||||
// // voxel_norm += normals[i] * side_visible * max(dot(-cam_dir, normals[i]), 0.0);
|
||||
// }
|
||||
// voxel_norm = normalize(voxel_norm); */
|
||||
|
||||
float dist_lerp = clamp(pow(max(distance(focus_pos.xy, f_pos.xy) - view_distance.x, 0.0) / 1024.0, 2.0), 0, 1);
|
||||
// dist_lerp = 0.0;
|
||||
// voxel_norm = normalize(mix(voxel_norm, f_norm, /*pow(dist_lerp, 1.0)*/dist_lerp));
|
||||
|
||||
vec3 voxel_norm = f_norm;
|
||||
// voxel_norm = f_norm;
|
||||
|
||||
// Note: because voxels, we reduce the normal for reflections to just its z component, dpendng on distance to camera.
|
||||
// Idea: the closer we are to facing top-down, the more the norm should tend towards up-z.
|
||||
// vec3 l_norm; // = vec3(0.0, 0.0, 1.0);
|
||||
@ -150,13 +226,17 @@ void main() {
|
||||
// vec3 light, diffuse_light, ambient_light;
|
||||
// get_sun_diffuse(f_norm, time_of_day.x, cam_to_frag, (0.25 * shade_frac + 0.25 * light_frac) * f_col, 0.5 * shade_frac * f_col, 0.5 * shade_frac * /*vec3(1.0)*/f_col, 2.0, emitted_light, reflected_light);
|
||||
float max_light = 0.0;
|
||||
max_light += get_sun_diffuse2(f_norm/*l_norm*/, sun_dir, moon_dir, view_dir, vec3(1.0)/* * (0.5 * light_frac + vec3(0.5 * shade_frac))*/, vec3(1.0), /*0.5 * shade_frac * *//*vec3(1.0)*//*f_col*/vec3(R_s), alpha, emitted_light, reflected_light);
|
||||
max_light += get_sun_diffuse2(/*f_norm*/voxel_norm/*l_norm*/, sun_dir, moon_dir, view_dir, vec3(1.0)/* * (0.5 * light_frac + vec3(0.5 * shade_frac))*/, vec3(1.0), /*0.5 * shade_frac * *//*vec3(1.0)*//*f_col*/vec3(R_s), alpha, dist_lerp/*max(distance(focus_pos.xy, f_pos.xyz) - view_distance.x, 0.0) / 1000 < 1.0*/, emitted_light, reflected_light);
|
||||
// emitted_light = vec3(1.0);
|
||||
emitted_light *= max(shade_frac, MIN_SHADOW);
|
||||
reflected_light *= shade_frac;
|
||||
max_light *= shade_frac;
|
||||
// reflected_light = vec3(0.0);
|
||||
|
||||
float ao = /*pow(f_ao, 0.5)*/f_ao * 0.9 + 0.1;
|
||||
emitted_light *= ao;
|
||||
reflected_light *= ao;
|
||||
|
||||
// emitted_light += 0.5 * vec3(SUN_AMBIANCE * sun_shade_frac * sun_light + moon_shade_frac * moon_light) * f_col * (ambient_sides + 1.0);
|
||||
|
||||
// Ambient lighting attempt: vertical light.
|
||||
|
@ -36,13 +36,49 @@ void main() {
|
||||
|
||||
// f_pos.z -= 100.0 * pow(1.0 + 0.01 / view_distance.x, -pow(distance(focus_pos.xy, f_pos.xy), 2.0));
|
||||
// f_pos.z = mix(-f_pos.z, f_pos.z, view_distance.x <= distance(focus_pos.xy, f_pos.xy) + 32.0);
|
||||
|
||||
// bool faces_fluid = false;// bool((f_pos_norm >> 28) & 0x1u);
|
||||
// // TODO: Measure real water surface altitude here.
|
||||
// float surfaceAlt = mix(view_distance.z, /*floor*/(min(f_pos.z, floor(alt_at_real(cam_pos.xy)))), medium.x);
|
||||
// // float surfaceAlt = mix(view_distance.z, floor(max(cam_pos.z, alt_at_real(cam_pos.xy))), medium.x);
|
||||
// // float surfaceAlt = min(floor(f_pos.z), floor(alt_at_real(cam_pos.xy))); // faces_fluid ? max(ceil(f_pos.z), floor(f_alt)) : floor(f_alt);
|
||||
|
||||
// f_pos.z -= max(sign(view_distance.x - distance(focus_pos.xy, f_pos.xy)), 0.0) * (32.0 * view_distance.z / 255 + 32.0 * max(0.0, f_pos.z - cam_pos.z));
|
||||
f_pos.z -= max(view_distance.x - distance(focus_pos.xy, f_pos.xy), 0.0) * (1.0 + max(0.0, f_pos.z - focus_pos.z));
|
||||
|
||||
// vec3 wRayinitial = f_pos; // cam_pos.z < f_pos.z ? f_pos : cam_pos.xyz;
|
||||
// vec3 wRayfinal = cam_pos.xyz; // cam_pos.z < f_pos.z ? cam_pos.xyz : f_pos;
|
||||
// wRayfinal = dot(wRayfinal - wRayinitial, focus_pos.xyz - cam_pos.xyz) < 0.0 ? wRayfinal : wRayinitial;
|
||||
// vec3 wRayNormal = /*surfaceAlt < wRayinitial.z ? vec3(0.0, 0.0, -1.0) : */vec3(0.0, 0.0, 1.0);
|
||||
// float n_camera = mix(1.0, 1.3325, medium.x);
|
||||
// float n_vertex = faces_fluid ? 1.3325 : 1.0;
|
||||
// float n1 = n_vertex; // cam_pos.z < f_pos.z ? n_vertex : n_camera;
|
||||
// float n2 = n_camera; // cam_pos.z < f_pos.z ? n_camera : n_vertex;
|
||||
|
||||
// float wRayLength0 = length(wRayfinal - wRayinitial);
|
||||
// vec3 wRayDir = (wRayfinal - wRayinitial) / wRayLength0;
|
||||
// vec3 wPoint = wRayfinal;
|
||||
// bool wIntersectsSurface = IntersectRayPlane(wRayinitial, wRayDir, vec3(0.0, 0.0, surfaceAlt), -wRayNormal, wPoint);
|
||||
// float wRayLength = length(wPoint - wRayinitial);
|
||||
// wPoint = wRayLength < wRayLength0 ? wPoint : wRayfinal;
|
||||
// wRayLength = min(wRayLength, wRayLength0); // min(max_length, dot(wRayfinal - wpos, defaultpos - wpos));
|
||||
|
||||
// // vec3 wRayDir2 = (wRayfinal - wRayinitial) / wRayLength;
|
||||
|
||||
// vec3 wRayDir3 = (dot(wRayDir, wRayNormal) < 0.0 && surfaceAlt < wRayinitial.z && wIntersectsSurface/* && medium.x == 1u*/) ? refract(wRayDir, wRayNormal, n2 / n1) : wRayDir;
|
||||
// // wPoint -= wRayDir3 * wRayLength * n2 / n1;
|
||||
|
||||
// vec3 newRay = (dot(wRayDir3, focus_pos.xyz - cam_pos.xyz) < 0.0 && /*dot(wRayDir, wRayNormal) > 0.0 && *//*surfaceAlt < wRayinitial.z && */wIntersectsSurface && medium.x == 1u) ? wPoint - wRayDir3 * wRayLength * n2 / n1/*wPoint - wRayDir3 * wRayLength * n2 / n1*/ : f_pos;// - (wRayfinal - wPoint) * n2 / n1; // wPoint + n2 * (wRayfinal - wPoint) - n2 / n1 * wRayLength * wRayDir3;
|
||||
|
||||
// newRay.z -= max(view_distance.x - distance(focus_pos.xy, f_pos.xy), 0.0) * (1.0 + max(0.0, f_pos.z - focus_pos.z));
|
||||
|
||||
|
||||
// f_light = 1.0;
|
||||
|
||||
gl_Position =
|
||||
proj_mat *
|
||||
view_mat *
|
||||
vec4(f_pos, 1);
|
||||
vec4(f_pos/*newRay*/, 1);
|
||||
// gl_Position.z = -gl_Position.z / 100.0;
|
||||
gl_Position.z = -1000.0 / (gl_Position.z + 10000.0);
|
||||
}
|
||||
|
@ -21,10 +21,12 @@ void main() {
|
||||
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
|
||||
|
||||
float dist = 100000.0;
|
||||
|
||||
float refractionIndex = medium.x == 1u ? 1.0 / 1.3325 : 1.0;
|
||||
/* if (medium.x == 1u) {
|
||||
dist = UNDERWATER_MIST_DIST;
|
||||
} */
|
||||
vec3 wpos = cam_pos.xyz + /*normalize(f_pos)*/cam_dir * dist;
|
||||
|
||||
tgt_color = vec4(get_sky_color(normalize(f_pos), time_of_day.x, cam_pos.xyz, wpos, 1.0, true, _clouds), 1.0);
|
||||
tgt_color = vec4(get_sky_color(normalize(f_pos), time_of_day.x, cam_pos.xyz, wpos, 1.0, true, refractionIndex, _clouds), 1.0);
|
||||
}
|
||||
|
@ -58,5 +58,6 @@ void main() {
|
||||
gl_Position =
|
||||
all_mat *
|
||||
vec4(f_pos, 1);
|
||||
// gl_Position.z = -gl_Position.z / 100.0;
|
||||
gl_Position.z = -1000.0 / (gl_Position.z + 10000.0);
|
||||
}
|
||||
|
@ -6,8 +6,8 @@
|
||||
in vec3 f_pos;
|
||||
in vec3 f_chunk_pos;
|
||||
flat in uint f_pos_norm;
|
||||
in float f_alt;
|
||||
in vec4 f_shadow;
|
||||
// in float f_alt;
|
||||
// in vec4 f_shadow;
|
||||
in vec3 f_col;
|
||||
in float f_light;
|
||||
in float f_ao;
|
||||
@ -39,6 +39,26 @@ void main() {
|
||||
|
||||
vec3 sun_dir = get_sun_dir(time_of_day.x);
|
||||
vec3 moon_dir = get_moon_dir(time_of_day.x);
|
||||
|
||||
float f_alt = alt_at(f_pos.xy);
|
||||
vec4 f_shadow = textureBicubic(t_horizon, pos_to_tex(f_pos.xy));
|
||||
|
||||
float alpha = 1.0;
|
||||
// TODO: Possibly angle with water surface into account? Since we can basically assume it's horizontal.
|
||||
const float n2 = 1.01;
|
||||
const float R_s2s0 = pow((1.0 - n2) / (1.0 + n2), 2);
|
||||
const float R_s1s0 = pow((1.3325 - n2) / (1.3325 + n2), 2);
|
||||
const float R_s2s1 = pow((1.0 - 1.3325) / (1.0 + 1.3325), 2);
|
||||
const float R_s1s2 = pow((1.3325 - 1.0) / (1.3325 + 1.0), 2);
|
||||
// float faces_fluid = faces_fluid && f_pos.z <= floor(f_alt);
|
||||
float fluid_alt = max(ceil(f_pos.z), floor(f_alt));
|
||||
float R_s = /*(f_pos.z < f_alt)*/faces_fluid /*&& f_pos.z <= fluid_alt*/ ? mix(R_s2s1 * R_s1s0, R_s1s0, medium.x) : mix(R_s2s0, R_s1s2 * R_s2s0, medium.x);
|
||||
|
||||
// vec3 surf_color = /*srgb_to_linear*/(f_col);
|
||||
vec3 k_a = vec3(1.0);
|
||||
vec3 k_d = vec3(1.0);
|
||||
vec3 k_s = vec3(R_s);
|
||||
|
||||
// float sun_light = get_sun_brightness(sun_dir);
|
||||
// float moon_light = get_moon_brightness(moon_dir);
|
||||
/* float sun_shade_frac = horizon_at(f_pos, sun_dir);
|
||||
@ -55,33 +75,23 @@ void main() {
|
||||
// for the sun and moon (since they have different brightnesses / colors so the shadows shouldn't attenuate equally).
|
||||
float shade_frac = /*1.0;*/sun_shade_frac + moon_shade_frac;
|
||||
|
||||
vec3 surf_color = /*srgb_to_linear*/(f_col);
|
||||
float alpha = 1.0;
|
||||
// TODO: Possibly angle with water surface into account? Since we can basically assume it's horizontal.
|
||||
const float n2 = 1.01;
|
||||
const float R_s2s0 = pow((1.0 - n2) / (1.0 + n2), 2);
|
||||
const float R_s1s0 = pow((1.3325 - n2) / (1.3325 + n2), 2);
|
||||
const float R_s2s1 = pow((1.0 - 1.3325) / (1.0 + 1.3325), 2);
|
||||
const float R_s1s2 = pow((1.3325 - 1.0) / (1.3325 + 1.0), 2);
|
||||
// float faces_fluid = faces_fluid && f_pos.z <= floor(f_alt);
|
||||
float fluid_alt = max(ceil(f_pos.z), floor(f_alt));
|
||||
float R_s = /*(f_pos.z < f_alt)*/faces_fluid /*&& f_pos.z <= fluid_alt*/ ? mix(R_s2s1 * R_s1s0, R_s1s0, medium.x) : mix(R_s2s0, R_s1s2 * R_s2s0, medium.x);
|
||||
vec3 k_a = vec3(1.0);
|
||||
vec3 k_d = vec3(1.0);
|
||||
vec3 k_s = vec3(R_s);
|
||||
float max_light = 0.0;
|
||||
|
||||
// After shadows are computed, we use a refracted sun and moon direction.
|
||||
// sun_dir = faces_fluid && sun_shade_frac > 0.0 ? refract(sun_dir/*-view_dir*/, vec3(0.0, 0.0, 1.0), 1.0 / 1.3325) : sun_dir;
|
||||
// moon_dir = faces_fluid && moon_shade_frac > 0.0 ? refract(moon_dir/*-view_dir*/, vec3(0.0, 0.0, 1.0), 1.0 / 1.3325) : moon_dir;
|
||||
|
||||
// Compute attenuation due to water from the camera.
|
||||
vec3 mu = faces_fluid/* && f_pos.z <= fluid_alt*/ ? 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(f_pos, view_dir, mu, fluid_alt, /*cam_pos.z <= fluid_alt ? cam_pos.xyz : f_pos*/cam_pos.xyz);
|
||||
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);
|
||||
|
||||
// Computing light attenuation from water.
|
||||
vec3 emitted_light, reflected_light;
|
||||
// To account for prior saturation
|
||||
float f_light = pow(f_light, 1.5);
|
||||
float f_light = faces_fluid ? 1.0 : pow(f_light, 1.5);
|
||||
float point_shadow = shadow_at(f_pos, f_norm);
|
||||
max_light += get_sun_diffuse2(f_norm, /*time_of_day.x, */sun_dir, moon_dir, view_dir, f_pos, mu, cam_attenuation, fluid_alt, k_a/* * (shade_frac * 0.5 + light_frac * 0.5)*/, k_d, k_s, alpha, emitted_light, reflected_light);
|
||||
max_light += get_sun_diffuse2(f_norm, /*time_of_day.x, */sun_dir, moon_dir, view_dir, f_pos, mu, cam_attenuation, fluid_alt, k_a/* * (shade_frac * 0.5 + light_frac * 0.5)*/, k_d, k_s, alpha, 1.0, emitted_light, reflected_light);
|
||||
|
||||
emitted_light *= f_light * point_shadow * max(shade_frac, MIN_SHADOW);
|
||||
reflected_light *= f_light * point_shadow * shade_frac;
|
||||
@ -89,6 +99,8 @@ void main() {
|
||||
|
||||
max_light += lights_at(f_pos, f_norm, view_dir, mu, cam_attenuation, fluid_alt, k_a, k_d, k_s, alpha, emitted_light, reflected_light);
|
||||
|
||||
// float f_ao = 1.0;
|
||||
|
||||
float ao = /*pow(f_ao, 0.5)*/f_ao * 0.9 + 0.1;
|
||||
emitted_light *= ao;
|
||||
reflected_light *= ao;
|
||||
@ -115,7 +127,7 @@ void main() {
|
||||
|
||||
// vec3 surf_color = illuminate(srgb_to_linear(f_col), light, diffuse_light, ambient_light);
|
||||
vec3 col = srgb_to_linear(f_col + hash(vec4(floor(f_chunk_pos * 3.0 - f_norm * 0.5), 0)) * 0.02); // Small-scale noise
|
||||
surf_color = illuminate(max_light, col * emitted_light, col * reflected_light);
|
||||
vec3 surf_color = illuminate(max_light, col * emitted_light, col * reflected_light);
|
||||
|
||||
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
|
||||
vec4 clouds;
|
||||
|
@ -16,8 +16,8 @@ uniform u_locals {
|
||||
out vec3 f_pos;
|
||||
out vec3 f_chunk_pos;
|
||||
flat out uint f_pos_norm;
|
||||
out float f_alt;
|
||||
out vec4 f_shadow;
|
||||
// out float f_alt;
|
||||
// out vec4 f_shadow;
|
||||
out vec3 f_col;
|
||||
out float f_light;
|
||||
out float f_ao;
|
||||
@ -25,6 +25,7 @@ out float f_ao;
|
||||
const int EXTRA_NEG_Z = 32768;
|
||||
|
||||
void main() {
|
||||
// over it (if this vertex to see if it intersects.
|
||||
f_chunk_pos = vec3(ivec3((uvec3(v_pos_norm) >> uvec3(0, 6, 12)) & uvec3(0x3Fu, 0x3Fu, 0xFFFFu)) - ivec3(0, 0, EXTRA_NEG_Z));
|
||||
f_pos = f_chunk_pos + model_offs;
|
||||
|
||||
@ -39,11 +40,49 @@ void main() {
|
||||
f_pos_norm = v_pos_norm;
|
||||
|
||||
// Also precalculate shadow texture and estimated terrain altitude.
|
||||
f_alt = alt_at_real(f_pos.xy);
|
||||
f_shadow = textureBicubic(t_horizon, pos_to_tex(f_pos.xy));
|
||||
// f_alt = alt_at(f_pos.xy);
|
||||
// f_shadow = textureBicubic(t_horizon, pos_to_tex(f_pos.xy));
|
||||
|
||||
// IDEA: Cast a ray from the vertex to the camera (if this vertex is above the camera) or from the camera to the vertex (if this
|
||||
// vertex is below the camera) to see where it intersects the plane of water. All of this only applies if either the terrain
|
||||
// vertex is in water, or the camera is in water.
|
||||
//
|
||||
// If an intersection is found, refract the ray across the barrier using the correct ratio of indices of refraction (1 / N_WATER
|
||||
// if the vertex is above the camera [ray is going from air to water], N_WATER if the camera is above the vertex
|
||||
// [ray is going from water to air]).
|
||||
//
|
||||
// In order to make sure that terrain and other objects below such an interface are properly renered, we then "un-refract" by
|
||||
// reversing the refracted vector, and multiplying that by the distance from the object from which we cast the ray to the
|
||||
// intersectng point, in order to make the object appear to the viewer where it should after refraction.
|
||||
// bool faces_fluid = bool((f_pos_norm >> 28) & 0x1u);
|
||||
// // TODO: Measure real water surface altitude here.
|
||||
// float surfaceAlt = faces_fluid ? max(ceil(f_pos.z), floor(f_alt)) : /*floor(f_alt);*/mix(view_distance.z, min(f_alt, floor(alt_at_real(cam_pos.xy))), medium.x);
|
||||
|
||||
// vec3 wRayinitial = f_pos; // cam_pos.z < f_pos.z ? f_pos : cam_pos.xyz;
|
||||
// vec3 wRayfinal = cam_pos.xyz; // cam_pos.z < f_pos.z ? cam_pos.xyz : f_pos;
|
||||
// vec3 wRayNormal = surfaceAlt < wRayinitial.z ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 0.0, -1.0);
|
||||
// float n_camera = mix(1.0, 1.3325, medium.x);
|
||||
// float n_vertex = faces_fluid ? 1.3325 : 1.0;
|
||||
// float n1 = n_vertex; // cam_pos.z < f_pos.z ? n_vertex : n_camera;
|
||||
// float n2 = n_camera; // cam_pos.z < f_pos.z ? n_camera : n_vertex;
|
||||
|
||||
// float wRayLength0 = length(wRayfinal - wRayinitial);
|
||||
// vec3 wRayDir = (wRayfinal - wRayinitial) / wRayLength0;
|
||||
// vec3 wPoint = wRayfinal;
|
||||
// bool wIntersectsSurface = IntersectRayPlane(wRayinitial, wRayDir, vec3(0.0, 0.0, surfaceAlt), -wRayNormal, wPoint);
|
||||
// float wRayLength = length(wPoint - wRayinitial);
|
||||
// wPoint = wRayLength < wRayLength0 ? wPoint : wRayfinal;
|
||||
// wRayLength = min(wRayLength, wRayLength0); // min(max_length, dot(wRayfinal - wpos, defaultpos - wpos));
|
||||
|
||||
// // vec3 wRayDir2 = (wRayfinal - wRayinitial) / wRayLength;
|
||||
|
||||
// vec3 wRayDir3 = (dot(wRayDir, wRayNormal) < 0.0 && wIntersectsSurface) ? refract(wRayDir, wRayNormal, n2 / n1) : wRayDir;
|
||||
// // wPoint -= wRayDir3 * wRayLength * n2 / n1;
|
||||
// vec3 newRay = dot(wRayDir, wRayNormal) < 0.0 && wIntersectsSurface ? wPoint - wRayDir3 * wRayLength * n2 / n1 : f_pos;// - (wRayfinal - wPoint) * n2 / n1; // wPoint + n2 * (wRayfinal - wPoint) - n2 / n1 * wRayLength * wRayDir3;
|
||||
|
||||
gl_Position =
|
||||
all_mat *
|
||||
vec4(f_pos, 1);
|
||||
vec4(f_pos/*newRay*/, 1);
|
||||
// gl_Position.z = -gl_Position.z / 100.0;
|
||||
gl_Position.z = -1000.0 / (gl_Position.z + 10000.0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user