mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
WIP: better graphics config, better LOD, shadow maps.
This commit is contained in:
parent
22ddbad3eb
commit
04382dc286
@ -1,4 +1,18 @@
|
|||||||
#version 330 core
|
#version 400 core
|
||||||
|
|
||||||
|
#include <constants.glsl>
|
||||||
|
|
||||||
|
#define LIGHTING_TYPE LIGHTING_TYPE_REFLECTION
|
||||||
|
|
||||||
|
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_GLOSSY
|
||||||
|
|
||||||
|
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION_SCHEME LIGHTING_DISTRIBUTION_SCHEME_MICROFACET
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION LIGHTING_DISTRIBUTION_BECKMANN
|
||||||
|
|
||||||
|
#define HAS_SHADOW_MAPS
|
||||||
|
|
||||||
#include <globals.glsl>
|
#include <globals.glsl>
|
||||||
|
|
||||||
@ -59,7 +73,7 @@ void main() {
|
|||||||
|
|
||||||
vec3 surf_color = /*srgb_to_linear*/(model_col.rgb * f_col);
|
vec3 surf_color = /*srgb_to_linear*/(model_col.rgb * f_col);
|
||||||
float alpha = 1.0;
|
float alpha = 1.0;
|
||||||
const float n2 = 1.01;
|
const float n2 = 1.5;
|
||||||
const float R_s2s0 = pow((1.0 - n2) / (1.0 + n2), 2);
|
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_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_s2s1 = pow((1.0 - 1.3325) / (1.0 + 1.3325), 2);
|
||||||
@ -102,7 +116,7 @@ void main() {
|
|||||||
// diffuse_light += point_light;
|
// diffuse_light += point_light;
|
||||||
// reflected_light += point_light;
|
// reflected_light += point_light;
|
||||||
// vec3 surf_color = illuminate(srgb_to_linear(model_col.rgb * f_col), light, diffuse_light, ambient_light);
|
// vec3 surf_color = illuminate(srgb_to_linear(model_col.rgb * f_col), light, diffuse_light, ambient_light);
|
||||||
surf_color = illuminate(max_light, surf_color * emitted_light, surf_color * reflected_light);
|
surf_color = illuminate(max_light, view_dir, surf_color * emitted_light, surf_color * reflected_light);
|
||||||
|
|
||||||
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
|
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
|
||||||
vec4 clouds;
|
vec4 clouds;
|
||||||
|
@ -1,5 +1,17 @@
|
|||||||
#version 330 core
|
#version 330 core
|
||||||
|
|
||||||
|
#include <constants.glsl>
|
||||||
|
|
||||||
|
#define LIGHTING_TYPE LIGHTING_TYPE_REFLECTION
|
||||||
|
|
||||||
|
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_GLOSSY
|
||||||
|
|
||||||
|
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION_SCHEME LIGHTING_DISTRIBUTION_SCHEME_MICROFACET
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION LIGHTING_DISTRIBUTION_BECKMANN
|
||||||
|
|
||||||
#include <globals.glsl>
|
#include <globals.glsl>
|
||||||
#include <lod.glsl>
|
#include <lod.glsl>
|
||||||
|
|
||||||
|
@ -1,4 +1,22 @@
|
|||||||
#version 330 core
|
#version 400 core
|
||||||
|
|
||||||
|
#include <constants.glsl>
|
||||||
|
|
||||||
|
#define LIGHTING_TYPE (LIGHTING_TYPE_TRANSMISSION | LIGHTING_TYPE_REFLECTION)
|
||||||
|
|
||||||
|
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_SPECULAR
|
||||||
|
|
||||||
|
#if (FLUID_MODE == FLUID_MODE_CHEAP)
|
||||||
|
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
|
||||||
|
#elif (FLUID_MODE == FLUID_MODE_SHINY)
|
||||||
|
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION_SCHEME LIGHTING_DISTRIBUTION_SCHEME_MICROFACET
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION LIGHTING_DISTRIBUTION_BECKMANN
|
||||||
|
|
||||||
|
#define HAS_SHADOW_MAPS
|
||||||
|
|
||||||
#include <globals.glsl>
|
#include <globals.glsl>
|
||||||
#include <random.glsl>
|
#include <random.glsl>
|
||||||
@ -25,7 +43,7 @@ out vec4 tgt_color;
|
|||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
// First 3 normals are negative, next 3 are positive
|
// First 3 normals are negative, next 3 are positive
|
||||||
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) );
|
vec3 normals[6] = vec3[](vec3(-1,0,0), vec3(1,0,0), vec3(0,-1,0), vec3(0,1,0), vec3(0,0,-1), vec3(0,0,1));
|
||||||
|
|
||||||
// TODO: last 3 bits in v_pos_norm should be a number between 0 and 5, rather than 0-2 and a direction.
|
// TODO: last 3 bits in v_pos_norm should be a number between 0 and 5, rather than 0-2 and a direction.
|
||||||
uint norm_axis = (f_pos_norm >> 30) & 0x3u;
|
uint norm_axis = (f_pos_norm >> 30) & 0x3u;
|
||||||
@ -52,7 +70,7 @@ void main() {
|
|||||||
// float moon_shade_frac = horizon_at(/*f_shadow, f_pos.z, */f_pos, moon_dir);
|
// 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 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);
|
float fluid_alt = f_pos.z;//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 alpha = 0.255/* / 4.0 / sqrt(2.0)*/;
|
||||||
const float n2 = 1.3325;
|
const float n2 = 1.3325;
|
||||||
@ -62,8 +80,15 @@ void main() {
|
|||||||
const float R_s1s2 = pow((1.3325 - 1.0) / (1.3325 + 1.0), 2);
|
const float R_s1s2 = pow((1.3325 - 1.0) / (1.3325 + 1.0), 2);
|
||||||
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);
|
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);
|
||||||
|
|
||||||
|
// Water is transparent so both normals are valid.
|
||||||
|
vec3 cam_norm = faceforward(f_norm, f_norm, cam_to_frag);
|
||||||
|
|
||||||
|
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 = vec3(1.0);//compute_attenuation_point(f_pos, -view_dir, mu, fluid_alt, cam_pos.xyz);
|
||||||
|
|
||||||
// NOTE: Assumes normal is vertical.
|
// 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 sun_view_dir = cam_pos.z <= fluid_alt ? /*refract(view_dir, -f_norm, 1.0 / n2)*//*reflect(view_dir, -f_norm)*/-view_dir : view_dir;//vec3(view_dir.xy, -view_dir.z) : view_dir;
|
||||||
|
|
||||||
vec3 k_a = vec3(1.0);
|
vec3 k_a = vec3(1.0);
|
||||||
vec3 k_d = vec3(1.0);
|
vec3 k_d = vec3(1.0);
|
||||||
@ -83,7 +108,7 @@ void main() {
|
|||||||
|
|
||||||
// vec3 surf_color = /*srgb_to_linear*/(vec3(0.4, 0.7, 2.0));
|
// vec3 surf_color = /*srgb_to_linear*/(vec3(0.4, 0.7, 2.0));
|
||||||
float max_light = 0.0;
|
float max_light = 0.0;
|
||||||
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);
|
max_light += get_sun_diffuse2(f_norm, /*time_of_day.x*/sun_dir, moon_dir, /*-cam_to_frag*/sun_view_dir/*view_dir*/, f_pos, mu, cam_attenuation, fluid_alt, k_a/* * (shade_frac * 0.5 + light_frac * 0.5)*/, /*vec3(0.0)*/k_d, k_s, alpha, 1.0, emitted_light, reflected_light);
|
||||||
reflected_light *= f_light * point_shadow * shade_frac;
|
reflected_light *= f_light * point_shadow * shade_frac;
|
||||||
emitted_light *= f_light * point_shadow * max(shade_frac, MIN_SHADOW);
|
emitted_light *= f_light * point_shadow * max(shade_frac, MIN_SHADOW);
|
||||||
max_light *= f_light * point_shadow * shade_frac;
|
max_light *= f_light * point_shadow * shade_frac;
|
||||||
@ -101,7 +126,7 @@ void main() {
|
|||||||
emitted_light += point_light;
|
emitted_light += point_light;
|
||||||
reflected_light += point_light; */
|
reflected_light += point_light; */
|
||||||
|
|
||||||
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);
|
max_light += lights_at(f_pos, /*f_norm*/cam_norm, view_dir, mu, cam_attenuation, fluid_alt, k_a, k_d, k_s, alpha, 1.0, emitted_light, reflected_light);
|
||||||
// vec3 diffuse_light_point = vec3(0.0);
|
// 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, k_a, vec3(1.0), k_s, alpha, emitted_light, diffuse_light_point);
|
||||||
|
|
||||||
@ -118,9 +143,9 @@ void main() {
|
|||||||
vec4 clouds;
|
vec4 clouds;
|
||||||
vec3 fog_color = get_sky_color(cam_to_frag, time_of_day.x, cam_pos.xyz, f_pos, 0.25, true, clouds);
|
vec3 fog_color = get_sky_color(cam_to_frag, time_of_day.x, cam_pos.xyz, f_pos, 0.25, true, clouds);
|
||||||
|
|
||||||
float passthrough = /*pow(*/dot(faceforward(f_norm, f_norm, cam_to_frag/*view_dir*/), -cam_to_frag/*view_dir*/)/*, 0.5)*/;
|
float passthrough = /*pow(*/dot(cam_norm, -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);
|
vec3 surf_color = illuminate(max_light, view_dir, 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)*/4.0 * 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);
|
tgt_color = mix(mix(color, vec4(fog_color, 0.0), fog_level), vec4(clouds.rgb, 0.0), clouds.a);
|
||||||
|
@ -1,4 +1,22 @@
|
|||||||
#version 330 core
|
#version 400 core
|
||||||
|
|
||||||
|
#include <constants.glsl>
|
||||||
|
|
||||||
|
#define LIGHTING_TYPE (LIGHTING_TYPE_TRANSMISSION | LIGHTING_TYPE_REFLECTION)
|
||||||
|
|
||||||
|
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_SPECULAR
|
||||||
|
|
||||||
|
#if (FLUID_MODE == FLUID_MODE_CHEAP)
|
||||||
|
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
|
||||||
|
#elif (FLUID_MODE == FLUID_MODE_SHINY)
|
||||||
|
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION_SCHEME LIGHTING_DISTRIBUTION_SCHEME_MICROFACET
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION LIGHTING_DISTRIBUTION_BECKMANN
|
||||||
|
|
||||||
|
#define HAS_SHADOW_MAPS
|
||||||
|
|
||||||
// https://www.shadertoy.com/view/XdsyWf
|
// https://www.shadertoy.com/view/XdsyWf
|
||||||
|
|
||||||
@ -119,7 +137,7 @@ void main() {
|
|||||||
vec4 _clouds;
|
vec4 _clouds;
|
||||||
vec3 reflect_ray_dir = reflect(cam_to_frag/*-view_dir*/, norm);
|
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 refract_ray_dir = refract(cam_to_frag/*-view_dir*/, norm, 1.0 / n2);
|
||||||
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 = 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 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;
|
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);
|
/* vec4 reflect_ray_dir4 = view_mat * vec4(reflect_ray_dir, 1.0);
|
||||||
@ -132,7 +150,7 @@ void main() {
|
|||||||
// /*const */vec3 water_color = srgb_to_linear(vec3(0.8, 0.9, 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.
|
// NOTE: Linear RGB, attenuation coefficients for water at roughly R, G, B wavelengths.
|
||||||
// See https://en.wikipedia.org/wiki/Electromagnetic_absorption_by_water
|
// See https://en.wikipedia.org/wiki/Electromagnetic_absorption_by_water
|
||||||
/*const */vec3 water_attenuation = MU_WATER;// 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);
|
// /*const */vec3 water_color = vec3(0.2, 0.95, 0.99);
|
||||||
|
|
||||||
vec3 sun_dir = get_sun_dir(time_of_day.x);
|
vec3 sun_dir = get_sun_dir(time_of_day.x);
|
||||||
@ -167,7 +185,7 @@ void main() {
|
|||||||
|
|
||||||
// // Color goes down with distance...
|
// // Color goes down with distance...
|
||||||
// // See https://en.wikipedia.org/wiki/Beer%E2%80%93Lambert_law.
|
// // See https://en.wikipedia.org/wiki/Beer%E2%80%93Lambert_law.
|
||||||
vec3 water_color_direct = vec3(1.0);//exp(-MU_WATER);//vec3(1.0);
|
// vec3 water_color_direct = exp(-MU_WATER);//exp(-MU_WATER);//vec3(1.0);
|
||||||
// vec3 water_color_direct = exp(-water_attenuation * (water_depth_to_light + water_depth_to_camera));
|
// vec3 water_color_direct = exp(-water_attenuation * (water_depth_to_light + water_depth_to_camera));
|
||||||
// vec3 water_color_ambient = exp(-water_attenuation * (water_depth_to_vertical + water_depth_to_camera));
|
// vec3 water_color_ambient = exp(-water_attenuation * (water_depth_to_vertical + water_depth_to_camera));
|
||||||
vec3 mu = MU_WATER;
|
vec3 mu = MU_WATER;
|
||||||
@ -176,8 +194,8 @@ void main() {
|
|||||||
// float water_depth_to_vertical = max(/*f_alt - f_pos.z*/f_light, 0.0);
|
// 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.
|
// 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.
|
// See https://en.wikipedia.org/wiki/Beer%E2%80%93Lambert_law.
|
||||||
float water_depth_to_vertical = max(fluid_alt - cam_pos.z/*f_light*/, 0.0);
|
// float water_depth_to_vertical = max(fluid_alt - cam_pos.z/*f_light*/, 0.0);
|
||||||
vec3 ambient_attenuation = exp(-mu * water_depth_to_vertical);
|
// vec3 ambient_attenuation = exp(-mu * water_depth_to_vertical);
|
||||||
|
|
||||||
// For ambient reflection, we just take the water
|
// For ambient reflection, we just take the water
|
||||||
|
|
||||||
@ -191,7 +209,7 @@ void main() {
|
|||||||
float point_shadow = shadow_at(f_pos, f_norm);
|
float point_shadow = shadow_at(f_pos, f_norm);
|
||||||
// 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);
|
// 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
|
// 0 = 100% reflection, 1 = translucent water
|
||||||
float passthrough = /*pow(*/dot(faceforward(f_norm, f_norm, cam_to_frag/*view_dir*/), -cam_to_frag/*view_dir*/)/*, 0.5)*/;
|
float passthrough = /*pow(*/dot(faceforward(norm, norm, cam_to_frag/*view_dir*/), -cam_to_frag/*view_dir*/)/*, 0.5)*/;
|
||||||
|
|
||||||
float max_light = 0.0;
|
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, 1.0, 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);
|
||||||
@ -208,7 +226,7 @@ void main() {
|
|||||||
// diffuse_light_point -= specular_light_point;
|
// diffuse_light_point -= specular_light_point;
|
||||||
// max_light += lights_at(f_pos, cam_norm, view_dir, mu, cam_attenuation, fluid_alt, k_a, /*k_d*/vec3(0.0), /*vec3(0.0)*/k_s, alpha, emitted_light, /*diffuse_light*/reflected_light);
|
// max_light += lights_at(f_pos, cam_norm, view_dir, mu, cam_attenuation, fluid_alt, k_a, /*k_d*/vec3(0.0), /*vec3(0.0)*/k_s, alpha, emitted_light, /*diffuse_light*/reflected_light);
|
||||||
|
|
||||||
max_light += lights_at(f_pos, cam_norm, view_dir, mu, cam_attenuation, fluid_alt, k_a, /*k_d*//*vec3(0.0)*/k_d, /*vec3(0.0)*/k_s, alpha, emitted_light, /*diffuse_light*/reflected_light);
|
max_light += lights_at(f_pos, cam_norm, view_dir, mu, cam_attenuation, fluid_alt, k_a, /*k_d*//*vec3(0.0)*/k_d, /*vec3(0.0)*/k_s, alpha, 1.0, emitted_light, /*diffuse_light*/reflected_light);
|
||||||
|
|
||||||
float reflected_light_point = length(reflected_light);///*length*/(diffuse_light_point.r) + f_light * point_shadow;
|
float reflected_light_point = length(reflected_light);///*length*/(diffuse_light_point.r) + f_light * point_shadow;
|
||||||
// TODO: See if we can be smarter about this using point light distances.
|
// TODO: See if we can be smarter about this using point light distances.
|
||||||
@ -226,7 +244,7 @@ void main() {
|
|||||||
// diffuse_light += point_light;
|
// diffuse_light += point_light;
|
||||||
// reflected_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;
|
// vec3 surf_color = srgb_to_linear(vec3(0.2, 0.5, 1.0)) * light * diffuse_light * ambient_light;
|
||||||
vec3 surf_color = illuminate(max_light, emitted_light/* * log(1.0 - MU_WATER)*/, /*water_color * */reflected_light/* * log(1.0 - MU_WATER)*/);
|
vec3 surf_color = illuminate(max_light, view_dir, emitted_light/* * log(1.0 - MU_WATER)*/, /*cam_attenuation * *//*water_color * */reflected_light/* * log(1.0 - MU_WATER)*/);
|
||||||
|
|
||||||
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
|
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
|
||||||
vec4 clouds;
|
vec4 clouds;
|
||||||
@ -254,8 +272,9 @@ void main() {
|
|||||||
//vec4 color = vec4(surf_color, 1.0);
|
//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 = 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);
|
||||||
|
|
||||||
float log_cam = log(min(cam_attenuation.r, min(cam_attenuation.g, cam_attenuation.b)));
|
// 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)));
|
float min_refl = min(emitted_light.r, min(emitted_light.g, emitted_light.b));
|
||||||
|
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, 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, 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));
|
// vec4 color = vec4(surf_color, mix(1.0, length(cam_attenuation), passthrough));
|
||||||
|
|
||||||
|
@ -1,7 +1,24 @@
|
|||||||
#version 330 core
|
#version 330 core
|
||||||
|
|
||||||
|
#include <constants.glsl>
|
||||||
|
|
||||||
|
#define LIGHTING_TYPE (LIGHTING_TYPE_TRANSMISSION | LIGHTING_TYPE_REFLECTION)
|
||||||
|
|
||||||
|
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_SPECULAR
|
||||||
|
|
||||||
|
#if (FLUID_MODE == FLUID_MODE_CHEAP)
|
||||||
|
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
|
||||||
|
#elif (FLUID_MODE == FLUID_MODE_SHINY)
|
||||||
|
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION_SCHEME LIGHTING_DISTRIBUTION_SCHEME_MICROFACET
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION LIGHTING_DISTRIBUTION_BECKMANN
|
||||||
|
|
||||||
#include <globals.glsl>
|
#include <globals.glsl>
|
||||||
#include <srgb.glsl>
|
#include <srgb.glsl>
|
||||||
|
#include <random.glsl>
|
||||||
|
|
||||||
in uint v_pos_norm;
|
in uint v_pos_norm;
|
||||||
in uint v_col_light;
|
in uint v_col_light;
|
||||||
@ -26,7 +43,11 @@ void main() {
|
|||||||
|
|
||||||
// Small waves
|
// Small waves
|
||||||
f_pos.xy += 0.01; // Avoid z-fighting
|
f_pos.xy += 0.01; // Avoid z-fighting
|
||||||
f_pos.z -= 0.1 + 0.1 * (sin(tick.x * 2.0 + f_pos.x * 2.0 + f_pos.y * 2.0) + 1.0) * 0.5;
|
// 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)
|
||||||
|
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
|
||||||
|
|
||||||
f_col = vec3(
|
f_col = vec3(
|
||||||
float((v_col_light >> 8) & 0xFFu),
|
float((v_col_light >> 8) & 0xFFu),
|
||||||
|
@ -63,11 +63,11 @@ vec4 get_cloud_color(vec3 dir, vec3 origin, float time_of_day, float max_dist, f
|
|||||||
dist += fuzz * 0.01 * min(pow(dist * 0.005, 2.0), 1.0);
|
dist += fuzz * 0.01 * min(pow(dist * 0.005, 2.0), 1.0);
|
||||||
|
|
||||||
vec3 pos = origin + dir * min(dist, max_dist);
|
vec3 pos = origin + dir * min(dist, max_dist);
|
||||||
vec2 sample = cloud_at(pos);
|
vec2 sample_ = cloud_at(pos);
|
||||||
|
|
||||||
float integral = sample.y * INCR;
|
float integral = sample_.y * INCR;
|
||||||
passthrough *= 1.0 - integral;
|
passthrough *= 1.0 - integral;
|
||||||
cloud_shade = mix(cloud_shade, sample.x, passthrough * integral);
|
cloud_shade = mix(cloud_shade, sample_.x, passthrough * integral);
|
||||||
dist += INCR * delta;
|
dist += INCR * delta;
|
||||||
|
|
||||||
if (passthrough < 0.1) {
|
if (passthrough < 0.1) {
|
||||||
|
58
assets/voxygen/shaders/include/constants.glsl
Normal file
58
assets/voxygen/shaders/include/constants.glsl
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/* NOTE: When included, this file will contain values for the automatically defined settings specified below. */
|
||||||
|
|
||||||
|
/* TODO: Add the ability to control the tendency to do stuff in the vertex vs. fragment shader.
|
||||||
|
* Currently this flag is ignored and always set to prefer fragment, but this tradeoff is not correct on all
|
||||||
|
* machines in all cases (mine, for instance). */
|
||||||
|
#define VOXYGEN_COMPUTATION_PREERENCE_FRAGMENT 0u
|
||||||
|
#define VOXYGEN_COMPUTATION_PREERENCE_VERTEX 1u
|
||||||
|
|
||||||
|
#define FLUID_MODE_CHEAP 0u
|
||||||
|
#define FLUID_MODE_SHINY 1u
|
||||||
|
|
||||||
|
#define CLOUD_MODE_NONE 0u
|
||||||
|
#define CLOUD_MODE_REGULAR 1u
|
||||||
|
|
||||||
|
#define LIGHTING_ALGORITHM_LAMBERTIAN 0u
|
||||||
|
#define LIGHTING_ALGORITHM_BLINN_PHONG 1u
|
||||||
|
#define LIGHTING_ALGORITHM_ASHIKHMIN 2u
|
||||||
|
|
||||||
|
/* Unlike the other flags (for now anyway), these are bitmask values */
|
||||||
|
#define LIGHTING_TYPE_REFLECTION 0x01u
|
||||||
|
#define LIGHTING_TYPE_TRANSMISSION 0x02u
|
||||||
|
|
||||||
|
/* Currently ignored, but ideally shoud be helpful for determining light transport properties. */
|
||||||
|
#define LIGHTING_REFLECTION_KIND_DIFFUSE 0u
|
||||||
|
#define LIGHTING_REFLECTION_KIND_GLOSSY 1u
|
||||||
|
#define LIGHTING_REFLECTION_KIND_SPECULAR 2u
|
||||||
|
|
||||||
|
#define LIGHTING_TRANSPORT_MODE_IMPORTANCE 0u
|
||||||
|
/* Radiance mode is currently used as a proxy for "attenuation and medium materials
|
||||||
|
* matter," but we may make it more granular. */
|
||||||
|
#define LIGHTING_TRANSPORT_MODE_RADIANCE 1u
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION_SCHEME_MICROFACET 0u
|
||||||
|
#define LIGHTING_DISTRIBUTION_SCHEME_VOXEL 1u
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION_BECKMANN 0u
|
||||||
|
#define LIGHTING_DISTRIBUTION_TROWBRIDGE 1u
|
||||||
|
|
||||||
|
/* Constants expected to be defined automatically by configuration: */
|
||||||
|
|
||||||
|
/*
|
||||||
|
#define VOXYGEN_COMPUTATION_PREERENCE <preference>
|
||||||
|
#define FLUID_MODE <mode>
|
||||||
|
#define CLOUD_MODE <mode>
|
||||||
|
#define LIGHTING_ALGORITHM <algorithm>
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Constants expected to be defined by any shader that needs to perform lighting calculations
|
||||||
|
* (but whose values may take automatically defined constants into account): */
|
||||||
|
|
||||||
|
/*
|
||||||
|
// At least one of LIGHTING_TYPE_REFLECTION or LIGHTING_TYPE_TRANSMISSION should be set.
|
||||||
|
#define LIGHTING_TYPE <type bitmask>
|
||||||
|
#define LIGHTING_REFLECTION_KIND <kind>
|
||||||
|
#define LIGHTING_TRANSPORT_MODE <mode>
|
||||||
|
#define LIGHTING_DISTRIBUTION_SCHEME <scheme>
|
||||||
|
#define LIGHTING_DISTRIBUTION <distribution>
|
||||||
|
*/
|
@ -25,9 +25,32 @@ float attenuation_strength(vec3 rpos) {
|
|||||||
return max(2.0 / pow(d2 + 10, 0.35) - pow(d2 / 50000.0, 0.8), 0.0);
|
return max(2.0 / pow(d2 + 10, 0.35) - pow(d2 / 50000.0, 0.8), 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Linear RGB, attenuation coefficients for water at roughly R, G, B wavelengths.
|
#ifdef HAS_SHADOW_MAPS
|
||||||
// See https://en.wikipedia.org/wiki/Electromagnetic_absorption_by_water
|
uniform samplerCubeArrayShadow t_shadow_maps;
|
||||||
const vec3 MU_WATER = vec3(0.6, 0.04, 0.01);
|
|
||||||
|
float ShadowCalculation(uint lightIndex, vec3 fragToLight, float currentDepth)
|
||||||
|
{
|
||||||
|
// return 1.0;
|
||||||
|
// use the light to fragment vector to sample from the depth map
|
||||||
|
float bias = 0.0;// 0.05;
|
||||||
|
// float closestDepth = texture(t_shadow_maps, vec4(fragToLight, lightIndex)/*, 0.0*//*, 0.0*//*, bias*/).r;
|
||||||
|
// // float closestDepth = texture(t_shadow_maps, vec4(fragToLight, lightIndex), bias);
|
||||||
|
// // it is currently in linear range between [0,1]. Re-transform back to original value
|
||||||
|
// closestDepth *= screen_res.w; // far plane
|
||||||
|
// // now test for shadows
|
||||||
|
// // float shadow = /*currentDepth*/(screen_res.w - bias) > closestDepth ? 1.0 : 0.0;
|
||||||
|
// float shadow = currentDepth - bias > closestDepth ? 1.0 : 0.0;
|
||||||
|
// float visibility = textureProj(t_shadow_maps, vec4(fragToLight, lightIndex), bias);
|
||||||
|
float visibility = texture(t_shadow_maps, vec4(fragToLight, lightIndex), (currentDepth/* + screen_res.z*/) / screen_res.w);// / (screen_res.w/* - screen_res.z*/)/*1.0 -bias*//*-(currentDepth - bias) / screen_res.w*//*-screen_res.w*/);
|
||||||
|
|
||||||
|
return visibility;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
float ShadowCalculation(uint lightIndex, vec3 fragToLight, float currentDepth)
|
||||||
|
{
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// // Compute attenuation due to light passing through a substance that fills an area below a horizontal plane
|
// // Compute attenuation due to light passing through a substance that fills an area below a horizontal plane
|
||||||
// // (e.g. in most cases, water below the water surface depth).
|
// // (e.g. in most cases, water below the water surface depth).
|
||||||
@ -114,15 +137,15 @@ float shadow_at(vec3 wpos, vec3 wnorm) {
|
|||||||
// mu is the attenuation coefficient for any substance on a horizontal plane.
|
// 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.
|
// 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.
|
// surface_alt is the altitude of the attenuating surface.
|
||||||
float lights_at(vec3 wpos, vec3 wnorm, vec3 cam_to_frag, vec3 mu, vec3 cam_attenuation, float surface_alt, vec3 k_a, vec3 k_d, vec3 k_s, float alpha, inout vec3 emitted_light, inout vec3 reflected_light/*, out float shadow*/) {
|
float lights_at(vec3 wpos, vec3 wnorm, vec3 /*cam_to_frag*/view_dir, vec3 mu, vec3 cam_attenuation, float surface_alt, vec3 k_a, vec3 k_d, vec3 k_s, float alpha, float voxel_lighting, inout vec3 emitted_light, inout vec3 reflected_light/*, out float shadow*/) {
|
||||||
// shadow = 0.0;
|
// shadow = 0.0;
|
||||||
vec3 ambient_light = vec3(0.0);
|
vec3 ambient_light = vec3(0.0);
|
||||||
vec3 directed_light = vec3(0.0);
|
vec3 directed_light = vec3(0.0);
|
||||||
vec3 max_light = vec3(0.0);
|
vec3 max_light = vec3(0.0);
|
||||||
|
|
||||||
const float LIGHT_AMBIENCE = 0.5;
|
const float LIGHT_AMBIENCE = 0.015625;
|
||||||
|
|
||||||
for (uint i = 0u; i < light_shadow_count.x; i ++) {
|
for (uint i = 0u; i < light_shadow_count.x/*32u*/; i ++) {
|
||||||
|
|
||||||
// Only access the array once
|
// Only access the array once
|
||||||
Light L = lights[i];
|
Light L = lights[i];
|
||||||
@ -160,19 +183,25 @@ float lights_at(vec3 wpos, vec3 wnorm, vec3 cam_to_frag, vec3 mu, vec3 cam_atten
|
|||||||
// shadow = min(shadow, shade);
|
// shadow = min(shadow, shade);
|
||||||
|
|
||||||
// Compute reflectance.
|
// Compute reflectance.
|
||||||
vec3 light_dir = -difference / sqrt(distance_2); // normalize(-difference);
|
float light_distance = sqrt(distance_2);
|
||||||
|
vec3 light_dir = -difference / light_distance; // normalize(-difference);
|
||||||
// light_dir = faceforward(light_dir, wnorm, light_dir);
|
// light_dir = faceforward(light_dir, wnorm, light_dir);
|
||||||
bool is_direct = dot(-light_dir, wnorm) > 0.0;
|
bool is_direct = dot(-light_dir, wnorm) > 0.0;
|
||||||
// reflected_light += color * (distance_2 == 0.0 ? vec3(1.0) : light_reflection_factor(wnorm, cam_to_frag, light_dir, k_d, k_s, alpha));
|
// reflected_light += color * (distance_2 == 0.0 ? vec3(1.0) : light_reflection_factor(wnorm, cam_to_frag, light_dir, k_d, k_s, alpha));
|
||||||
vec3 direct_light_dir = is_direct ? light_dir : -light_dir;
|
vec3 direct_light_dir = is_direct ? light_dir : -light_dir;
|
||||||
|
// vec3 direct_norm_dir = is_direct ? wnorm : -wnorm;
|
||||||
// Compute attenuation due to fluid.
|
// Compute attenuation due to fluid.
|
||||||
// Default is light_pos, so we take the whole segment length for this beam if it never intersects the surface, unlesss the beam itself
|
// Default is light_pos, so we take the whole segment length for this beam if it never intersects the surface, unlesss the beam itself
|
||||||
// is above the surface, in which case we take zero (wpos).
|
// is above the surface, in which case we take zero (wpos).
|
||||||
color *= cam_attenuation * compute_attenuation_point(wpos, -direct_light_dir, mu, surface_alt, light_pos.z < surface_alt ? light_pos : wpos);
|
color *= cam_attenuation * compute_attenuation_point(wpos, -direct_light_dir, mu, surface_alt, light_pos.z < surface_alt ? light_pos : wpos);
|
||||||
|
|
||||||
vec3 direct_light = PI * color * strength * square_factor * light_reflection_factor(wnorm, cam_to_frag, direct_light_dir, k_d, k_s, alpha);
|
#if (LIGHTING_TYPE & LIGHTING_TYPE_TRANSMISSION) != 0
|
||||||
directed_light += is_direct ? direct_light * square_factor : vec3(0.0);
|
is_direct = true;
|
||||||
ambient_light += is_direct ? vec3(0.0) : direct_light * LIGHT_AMBIENCE;
|
#endif
|
||||||
|
vec3 direct_light = PI * color * strength * square_factor * light_reflection_factor(/*direct_norm_dir*/wnorm, /*cam_to_frag*/view_dir, direct_light_dir, k_d, k_s, alpha, voxel_lighting);
|
||||||
|
float computed_shadow = ShadowCalculation(i, -difference, light_distance);
|
||||||
|
directed_light += /*is_direct ? */max(computed_shadow, /*LIGHT_AMBIENCE*/0.0) * direct_light * square_factor/* : vec3(0.0)*/;
|
||||||
|
ambient_light += is_direct ? vec3(0.0) : vec3(0.0); // direct_light * square_factor * LIGHT_AMBIENCE;
|
||||||
|
|
||||||
vec3 cam_light_diff = light_pos - focus_pos.xyz;
|
vec3 cam_light_diff = light_pos - focus_pos.xyz;
|
||||||
float cam_distance_2 = dot(cam_light_diff, cam_light_diff);// + 0.0001;
|
float cam_distance_2 = dot(cam_light_diff, cam_light_diff);// + 0.0001;
|
||||||
@ -193,7 +222,7 @@ float lights_at(vec3 wpos, vec3 wnorm, vec3 cam_to_frag, vec3 mu, vec3 cam_atten
|
|||||||
// mix(cam_strength, strength, cam_distance_2 / (cam_distance_2 + distance_2));
|
// mix(cam_strength, strength, cam_distance_2 / (cam_distance_2 + distance_2));
|
||||||
// max(cam_strength, strength);//mix(cam_strength, strength, clamp(distance_2 / /*pos_distance_2*/cam_distance_2, 0.0, 1.0));
|
// max(cam_strength, strength);//mix(cam_strength, strength, clamp(distance_2 / /*pos_distance_2*/cam_distance_2, 0.0, 1.0));
|
||||||
// float both_strength = mix(cam_strength, strength, cam_distance_2 / sqrt(cam_distance_2 + distance_2));
|
// float both_strength = mix(cam_strength, strength, cam_distance_2 / sqrt(cam_distance_2 + distance_2));
|
||||||
max_light += /*max(1.0, cam_strength)*//*min(cam_strength, 1.0)*//*max*//*max(both_strength, 1.0) * *//*cam_strength*/both_strength * square_factor * square_factor * PI * color;
|
max_light += /*max(1.0, cam_strength)*//*min(cam_strength, 1.0)*//*max*//*max(both_strength, 1.0) * *//*cam_strength*/computed_shadow * both_strength * square_factor * square_factor * PI * color;
|
||||||
// max_light += /*max(1.0, cam_strength)*//*min(cam_strength, 1.0)*//*max*/max(cam_strength, 1.0/*, strength*//*1.0*/) * square_factor * square_factor * PI * color;
|
// max_light += /*max(1.0, cam_strength)*//*min(cam_strength, 1.0)*//*max*/max(cam_strength, 1.0/*, strength*//*1.0*/) * square_factor * square_factor * PI * color;
|
||||||
// light += color * (max(0, max(dot(normalize(difference), wnorm), 0.15)) + LIGHT_AMBIENCE);
|
// light += color * (max(0, max(dot(normalize(difference), wnorm), 0.15)) + LIGHT_AMBIENCE);
|
||||||
// Compute emiittance.
|
// Compute emiittance.
|
||||||
@ -211,6 +240,6 @@ float lights_at(vec3 wpos, vec3 wnorm, vec3 cam_to_frag, vec3 mu, vec3 cam_atten
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Same as lights_at, but with no assumed attenuation due to fluid.
|
// Same as lights_at, but with no assumed attenuation due to fluid.
|
||||||
float lights_at(vec3 wpos, vec3 wnorm, vec3 cam_to_frag, vec3 k_a, vec3 k_d, vec3 k_s, float alpha, inout vec3 emitted_light, inout vec3 reflected_light) {
|
float lights_at(vec3 wpos, vec3 wnorm, vec3 view_dir, vec3 k_a, vec3 k_d, vec3 k_s, float alpha, inout vec3 emitted_light, inout vec3 reflected_light) {
|
||||||
return lights_at(wpos, wnorm, cam_to_frag, vec3(0.0), vec3(1.0), 0.0, k_a, k_d, k_s, alpha, emitted_light, reflected_light);
|
return lights_at(wpos, wnorm, view_dir, vec3(0.0), vec3(1.0), 0.0, k_a, k_d, k_s, alpha, 1.0, emitted_light, reflected_light);
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ vec4 textureBicubic(sampler2D sampler, vec2 texCoords) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
float alt_at(vec2 pos) {
|
float alt_at(vec2 pos) {
|
||||||
return texture/*textureBicubic*/(t_map, pos_to_uv(t_map, pos)).a * (/*1300.0*//*1278.7266845703125*/view_distance.w) + /*140.0*/view_distance.z;
|
return (texture/*textureBicubic*/(t_map, pos_to_uv(t_map, pos)).a * (/*1300.0*//*1278.7266845703125*/view_distance.w) + /*140.0*/view_distance.z);
|
||||||
//+ (texture(t_noise, pos * 0.002).x - 0.5) * 64.0;
|
//+ (texture(t_noise, pos * 0.002).x - 0.5) * 64.0;
|
||||||
|
|
||||||
// return 0.0
|
// return 0.0
|
||||||
@ -83,7 +83,12 @@ float alt_at(vec2 pos) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
float alt_at_real(vec2 pos) {
|
float alt_at_real(vec2 pos) {
|
||||||
return textureBicubic(t_map, pos_to_tex(pos)).a * (/*1300.0*//*1278.7266845703125*/view_distance.w) + /*140.0*/view_distance.z;
|
// 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)
|
||||||
|
// return alt_at(pos);
|
||||||
|
// #elif (FLUID_MODE == FLUID_MODE_SHINY)
|
||||||
|
return (textureBicubic(t_map, pos_to_tex(pos)).a * (/*1300.0*//*1278.7266845703125*/view_distance.w) + /*140.0*/view_distance.z);
|
||||||
|
// #endif
|
||||||
//+ (texture(t_noise, pos * 0.002).x - 0.5) * 64.0;
|
//+ (texture(t_noise, pos * 0.002).x - 0.5) * 64.0;
|
||||||
|
|
||||||
// return 0.0
|
// return 0.0
|
||||||
@ -271,6 +276,6 @@ vec3 lod_pos(vec2 pos, vec2 focus_pos) {
|
|||||||
vec3 lod_col(vec2 pos) {
|
vec3 lod_col(vec2 pos) {
|
||||||
//return vec3(0, 0.5, 0);
|
//return vec3(0, 0.5, 0);
|
||||||
return /*linear_to_srgb*/(textureBicubic(t_map, pos_to_tex(pos)).rgb)
|
return /*linear_to_srgb*/(textureBicubic(t_map, pos_to_tex(pos)).rgb)
|
||||||
+ (texture(t_noise, pos * 0.04 + texture(t_noise, pos * 0.005).xy * 2.0 + texture(t_noise, pos * 0.06).xy * 0.6).x - 0.5) * 0.1;
|
;//+ (texture(t_noise, pos * 0.04 + texture(t_noise, pos * 0.005).xy * 2.0 + texture(t_noise, pos * 0.06).xy * 0.6).x - 0.5) * 0.1;
|
||||||
//+ (texture(t_noise, pos * 0.04 + texture(t_noise, pos * 0.005).xy * 2.0 + texture(t_noise, pos * 0.06).xy * 0.6).x - 0.5) * 0.1;
|
//+ (texture(t_noise, pos * 0.04 + texture(t_noise, pos * 0.005).xy * 2.0 + texture(t_noise, pos * 0.06).xy * 0.6).x - 0.5) * 0.1;
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ const float PI = 3.141592;
|
|||||||
const vec3 SKY_DAY_TOP = vec3(0.1, 0.5, 0.9);
|
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.02, 0.28, 0.8);
|
||||||
const vec3 SKY_DAY_BOT = vec3(0.1, 0.2, 0.3);
|
const vec3 SKY_DAY_BOT = vec3(0.1, 0.2, 0.3);
|
||||||
const vec3 DAY_LIGHT = vec3(1.5, 1.4, 1.0);
|
const vec3 DAY_LIGHT = vec3(1.5, 1.4, 1.0);//vec3(1.5, 1.4, 1.0);
|
||||||
const vec3 SUN_HALO_DAY = vec3(0.35, 0.35, 0.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_TOP = vec3(0.06, 0.1, 0.20);
|
||||||
@ -26,9 +26,9 @@ const vec3 NIGHT_LIGHT = vec3(0.002, 0.02, 0.02);
|
|||||||
// Linear RGB, scattering coefficients for atmosphere at roughly R, G, B wavelengths.
|
// Linear RGB, scattering coefficients for atmosphere at roughly R, G, B wavelengths.
|
||||||
//
|
//
|
||||||
// See https://en.wikipedia.org/wiki/Diffuse_sky_radiation
|
// See https://en.wikipedia.org/wiki/Diffuse_sky_radiation
|
||||||
const vec3 MU_SCATTER = vec3(0.05, 0.10, 0.23);
|
const vec3 MU_SCATTER = vec3(0.05, 0.10, 0.23) * 2.0;
|
||||||
|
|
||||||
const float SUN_COLOR_FACTOR = 6.0;//1.8;
|
const float SUN_COLOR_FACTOR = 6.0;//6.0;// * 1.5;//1.8;
|
||||||
|
|
||||||
const float UNDERWATER_MIST_DIST = 100.0;
|
const float UNDERWATER_MIST_DIST = 100.0;
|
||||||
|
|
||||||
@ -423,12 +423,16 @@ float fog(vec3 f_pos, vec3 focus_pos, uint medium) {
|
|||||||
float avg_col = (color.r + color.g + color.b) / 3.0;
|
float avg_col = (color.r + color.g + color.b) / 3.0;
|
||||||
return ((color - avg_col) * light + (diffuse + ambience) * avg_col) * (diffuse + ambience);
|
return ((color - avg_col) * light + (diffuse + ambience) * avg_col) * (diffuse + ambience);
|
||||||
} */
|
} */
|
||||||
vec3 illuminate(float max_light, /*vec3 max_light, */vec3 emitted, vec3 reflected) {
|
vec3 illuminate(float max_light, vec3 view_dir, /*vec3 max_light, */vec3 emitted, vec3 reflected) {
|
||||||
const float NIGHT_EXPOSURE = 10.0;
|
const float NIGHT_EXPOSURE = 10.0;
|
||||||
const float DUSK_EXPOSURE = 2.0;//0.8;
|
const float DUSK_EXPOSURE = 2.0;//0.8;
|
||||||
const float DAY_EXPOSURE = 1.0;//0.7;
|
const float DAY_EXPOSURE = 1.0;//0.7;
|
||||||
|
|
||||||
|
#if (LIGHTING_ALGORITHM == LIGHTING_ALGORITHM_ASHIKHMIN)
|
||||||
const float DAY_SATURATION = 1.1;
|
const float DAY_SATURATION = 1.1;
|
||||||
|
#else
|
||||||
|
const float DAY_SATURATION = 1.0;
|
||||||
|
#endif
|
||||||
const float DUSK_SATURATION = 0.6;
|
const float DUSK_SATURATION = 0.6;
|
||||||
const float NIGHT_SATURATION = 0.1;
|
const float NIGHT_SATURATION = 0.1;
|
||||||
|
|
||||||
@ -460,6 +464,10 @@ vec3 illuminate(float max_light, /*vec3 max_light, */vec3 emitted, vec3 reflecte
|
|||||||
DAY_EXPOSURE,
|
DAY_EXPOSURE,
|
||||||
max(-sun_dir.z, 0)
|
max(-sun_dir.z, 0)
|
||||||
);
|
);
|
||||||
|
vec3 now_light = moon_dir.z < 0 ? moon_dir : sun_dir;
|
||||||
|
float cos_view_light = dot(-now_light, view_dir);
|
||||||
|
// alpha *= exp(1.0 - cos_view_light);
|
||||||
|
// sky_light *= 1.0 - log(1.0 + view_dir.z);
|
||||||
float alph = sky_light > 0.0 && max_light > 0.0 ? mix(1.0 / log(/*1.0*//*1.0 + *//*lum_sky + */1.0 + max_light / (0.0 + sky_light)), 1.0, clamp(max_light - sky_light, 0.0, 1.0)) : 1.0;
|
float alph = sky_light > 0.0 && max_light > 0.0 ? mix(1.0 / log(/*1.0*//*1.0 + *//*lum_sky + */1.0 + max_light / (0.0 + sky_light)), 1.0, clamp(max_light - sky_light, 0.0, 1.0)) : 1.0;
|
||||||
alpha = alpha * min(alph, 1.0);//((max_light > 0.0 && max_light > sky_light /* && sky_light > 0.0*/) ? /*1.0*/1.0 / log(/*1.0*//*1.0 + *//*lum_sky + */1.0 + max_light - (0.0 + sky_light)) : 1.0);
|
alpha = alpha * min(alph, 1.0);//((max_light > 0.0 && max_light > sky_light /* && sky_light > 0.0*/) ? /*1.0*/1.0 / log(/*1.0*//*1.0 + *//*lum_sky + */1.0 + max_light - (0.0 + sky_light)) : 1.0);
|
||||||
// alpha = alpha * min(1.0, (max_light == 0.0 ? 1.0 : (1.0 + abs(lum_sky)) / /*(1.0 + max_light)*/max_light));
|
// alpha = alpha * min(1.0, (max_light == 0.0 ? 1.0 : (1.0 + abs(lum_sky)) / /*(1.0 + max_light)*/max_light));
|
||||||
@ -505,7 +513,8 @@ vec3 illuminate(float max_light, /*vec3 max_light, */vec3 emitted, vec3 reflecte
|
|||||||
// vec3 c = sqrt(col_adjusted) * T;
|
// vec3 c = sqrt(col_adjusted) * T;
|
||||||
// vec3 c = /*col_adjusted * */col_adjusted * T;
|
// vec3 c = /*col_adjusted * */col_adjusted * T;
|
||||||
|
|
||||||
return c;
|
return color;
|
||||||
|
// return c;
|
||||||
// float sum_col = color.r + color.g + color.b;
|
// float sum_col = color.r + color.g + color.b;
|
||||||
// return /*srgb_to_linear*/(/*0.5*//*0.125 * */vec3(pow(color.x, gamma), pow(color.y, gamma), pow(color.z, gamma)));
|
// return /*srgb_to_linear*/(/*0.5*//*0.125 * */vec3(pow(color.x, gamma), pow(color.y, gamma), pow(color.z, gamma)));
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
// Linear RGB, attenuation coefficients for water at roughly R, G, B wavelengths.
|
||||||
|
// See https://en.wikipedia.org/wiki/Electromagnetic_absorption_by_water
|
||||||
|
const vec3 MU_WATER = vec3(0.6, 0.04, 0.01);
|
||||||
|
|
||||||
//https://gamedev.stackexchange.com/questions/92015/optimized-linear-to-srgb-glsl
|
//https://gamedev.stackexchange.com/questions/92015/optimized-linear-to-srgb-glsl
|
||||||
vec3 srgb_to_linear(vec3 srgb) {
|
vec3 srgb_to_linear(vec3 srgb) {
|
||||||
bvec3 cutoff = lessThan(srgb, vec3(0.04045));
|
bvec3 cutoff = lessThan(srgb, vec3(0.04045));
|
||||||
@ -54,7 +58,7 @@ float BeckmannDistribution_D_Voxel(vec3 wh, vec3 norm, float alpha) {
|
|||||||
// vec3 cos_sides_i = /*sides * */sides * norm;
|
// vec3 cos_sides_i = /*sides * */sides * norm;
|
||||||
// vec3 cos_sides_o = max(sides * view_dir, 0.0);
|
// 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);
|
vec3 NdotH = wh * sides;//max(wh * sides, 0.0);/*cos_sides_i*///max(sides * wh, 0.0);
|
||||||
|
|
||||||
const float PI = 3.1415926535897932384626433832795;
|
const float PI = 3.1415926535897932384626433832795;
|
||||||
vec3 NdotH2 = NdotH * NdotH;
|
vec3 NdotH2 = NdotH * NdotH;
|
||||||
@ -96,6 +100,27 @@ float BeckmannDistribution_D_Voxel(vec3 wh, vec3 norm, float alpha) {
|
|||||||
// return voxel_norm;
|
// return voxel_norm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float TrowbridgeReitzDistribution_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 = wh * sides;//max(wh * sides, 0.0);/*cos_sides_i*///max(sides * wh, 0.0);
|
||||||
|
|
||||||
|
const float PI = 3.1415926535897932384626433832795;
|
||||||
|
vec3 NdotH2 = NdotH * NdotH;
|
||||||
|
// vec3 m2 = alpha * alpha;
|
||||||
|
// vec3 NdotH2m2 = NdotH2 * m2;
|
||||||
|
vec3 NdotH2m2 = NdotH2 * alpha * alpha;
|
||||||
|
// vec3 Tan2Theta = (1 - NdotH2) / NdotH2;
|
||||||
|
// vec3 e = (NdotH2 / m2 + (1 - NdotH2) / m2) * Tan2Theta;
|
||||||
|
// vec3 e = 1 / m2 * (1 - NdotH2) / NdotH2;
|
||||||
|
vec3 e = (1 - NdotH2) / NdotH2m2;
|
||||||
|
vec3 k_spec = 1.0 / (PI * NdotH2m2 * NdotH2 * (1 + e) * (1 + e));
|
||||||
|
// 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));
|
||||||
|
}
|
||||||
|
|
||||||
float BeckmannDistribution_Lambda(vec3 norm, vec3 dir, float alpha) {
|
float BeckmannDistribution_Lambda(vec3 norm, vec3 dir, float alpha) {
|
||||||
float CosTheta = /*max(dot(norm, dir), 0.0);*/dot(norm, dir);
|
float CosTheta = /*max(dot(norm, dir), 0.0);*/dot(norm, dir);
|
||||||
/* if (CosTheta == 0.0) {
|
/* if (CosTheta == 0.0) {
|
||||||
@ -162,7 +187,12 @@ vec3 FresnelBlend_f(vec3 norm, vec3 dir, vec3 light_dir, vec3 R_d, vec3 R_s, flo
|
|||||||
(1 - pow5(1 - .5f * AbsCosTheta(wo))); */
|
(1 - pow5(1 - .5f * AbsCosTheta(wo))); */
|
||||||
// Vector3f wh = wi + wo;
|
// Vector3f wh = wi + wo;
|
||||||
vec3 wh = -light_dir + dir;
|
vec3 wh = -light_dir + dir;
|
||||||
if (cos_wi <= 0.0 || cos_wo <= 0.0) {
|
#if (LIGHTING_TYPE & LIGHTING_TYPE_TRANSMISSION) != 0
|
||||||
|
bool is_blocked = cos_wi == 0.0 || cos_wo == 0.0;
|
||||||
|
#else
|
||||||
|
bool is_blocked = cos_wi <= 0.0 || cos_wo <= 0.0;
|
||||||
|
#endif
|
||||||
|
if (is_blocked) {
|
||||||
return vec3(/*diffuse*/0.0);
|
return vec3(/*diffuse*/0.0);
|
||||||
}
|
}
|
||||||
// if (cos_wo < 0.0) {
|
// if (cos_wo < 0.0) {
|
||||||
@ -178,8 +208,8 @@ vec3 FresnelBlend_f(vec3 norm, vec3 dir, vec3 light_dir, vec3 R_d, vec3 R_s, flo
|
|||||||
wh = normalize(wh);//mix(normalize(wh), vec3(0.0), equal(light_dir, dir));
|
wh = normalize(wh);//mix(normalize(wh), vec3(0.0), equal(light_dir, dir));
|
||||||
float dot_wi_wh = dot(-light_dir, wh);
|
float dot_wi_wh = dot(-light_dir, wh);
|
||||||
vec3 specular = BeckmannDistribution_D(dot(wh, norm), alpha) /
|
vec3 specular = BeckmannDistribution_D(dot(wh, norm), alpha) /
|
||||||
(4 * abs(dot_wi_wh)) *
|
(4 * abs(dot_wi_wh) *
|
||||||
max(abs(cos_wi), abs(cos_wo)) *
|
max(abs(cos_wi), abs(cos_wo))) *
|
||||||
schlick_fresnel(R_s, dot_wi_wh);
|
schlick_fresnel(R_s, dot_wi_wh);
|
||||||
// Spectrum specular = distribution->D(wh) /
|
// Spectrum specular = distribution->D(wh) /
|
||||||
// (4 * AbsDot(wi, wh) *
|
// (4 * AbsDot(wi, wh) *
|
||||||
@ -199,26 +229,71 @@ vec3 FresnelBlend_Voxel_f(vec3 norm, vec3 dir, vec3 light_dir, vec3 R_d, vec3 R_
|
|||||||
float cos_wi = /*max(*/dot(-light_dir, norm)/*, 0.0)*/;
|
float cos_wi = /*max(*/dot(-light_dir, norm)/*, 0.0)*/;
|
||||||
float cos_wo = /*max(*/dot(dir, norm)/*, 0.0)*/;
|
float cos_wo = /*max(*/dot(dir, norm)/*, 0.0)*/;
|
||||||
|
|
||||||
|
#if (LIGHTING_TYPE & LIGHTING_TYPE_TRANSMISSION) != 0
|
||||||
|
vec4 AbsNdotL = abs(vec4(light_dir, cos_wi));
|
||||||
|
vec4 AbsNdotV = abs(vec4(dir, cos_wo));
|
||||||
|
#else
|
||||||
vec3 sides = sign(norm);
|
vec3 sides = sign(norm);
|
||||||
vec4 diffuse_factor =
|
vec4 AbsNdotL = vec4(max(-light_dir * sides, 0.0), abs(cos_wi));
|
||||||
(1.0 - pow5(1.0 - 0.5 * max(vec4(-light_dir * sides, abs(cos_wi)), 0.0))) *
|
vec4 AbsNdotV = vec4(max(dir * sides, 0.0), abs(cos_wo));
|
||||||
(1.0 - pow5(1.0 - 0.5 * max(vec4(dir * sides, abs(cos_wo)), 0.0)));
|
#endif
|
||||||
|
|
||||||
vec3 diffuse = (28.0 / (23.0 * PI)) * R_d *
|
// float R_r = 1.0 - R_s;
|
||||||
|
// float R_r = 1.0 - schlick_fresnel(R_s, cos_wi);
|
||||||
|
// // Rs + pow5(1.0 - cosTheta) * (1.0 - Rs)
|
||||||
|
// vec4 R_r = 1.0 - (R_s + (1.0 - R_s) * schlick_fresnel(R_s, cos_wi));
|
||||||
|
// mat4 R_r = 1.0 - (vec4(R_s, 0.0) + vec4(1.0 - R_s, 0.0) * pow5(1.0 - AbsNdotL));
|
||||||
|
// vec4 AbsNdotL5 = pow5(1.0 - AbsNdotL);
|
||||||
|
// vec4 R_s4 = vec4(R_s, 0.0);
|
||||||
|
// mat4 R_r =
|
||||||
|
// // mat4(1.0 - (R_s.r + (1.0 - R_s.r) * AbsNdotL5),
|
||||||
|
// // 1.0 - (R_s.g + (1.0 - R_s.g) * AbsNdotL5),
|
||||||
|
// // 1.0 - (R_s.b + (1.0 - R_s.b) * AbsNdotL5),
|
||||||
|
// // vec4(0.0)
|
||||||
|
// // );
|
||||||
|
// mat4(1.0 - (R_s4 + (1.0 - R_s4) * AbsNdotL5.x),
|
||||||
|
// 1.0 - (R_s4 + (1.0 - R_s4) * AbsNdotL5.y),
|
||||||
|
// 1.0 - (R_s4 + (1.0 - R_s4) * AbsNdotL5.z),
|
||||||
|
// 1.0 - (R_s4 + (1.0 - R_s4) * AbsNdotL5.w)
|
||||||
|
// );
|
||||||
|
// * ) (R1.0 - R_s.r) 1.0 - (vec4(R_s, 0.0) + vec4(1.0 - R_s, 0.0) * pow5(1.0 - AbsNdotL));
|
||||||
|
|
||||||
|
vec4 diffuse_factor =
|
||||||
|
// vec4(abs(vec4(-light_dir * sides, cos_wi)))
|
||||||
|
(1.0 - pow5(1.0 - 0.5 * AbsNdotL)) *
|
||||||
|
// (1.0 - pow5(1.0 - 0.5 * abs(vec4(-light_dir * sides, cos_wi)))) *
|
||||||
|
// (1.0 - pow5(1.0 - 0.5 * abs(vec4(dir * sides, cos_wo))))
|
||||||
|
(1.0 - pow5(1.0 - 0.5 * AbsNdotV))
|
||||||
|
// vec4(1.0)
|
||||||
|
;
|
||||||
|
/* 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))/*(1.0 / PI)*/ * R_d *
|
||||||
(1.0 - R_s) *
|
(1.0 - R_s) *
|
||||||
dot(diffuse_factor, vec4(abs(norm) * (1.0 - dist), dist));
|
//vec3(
|
||||||
|
dot(diffuse_factor, /*R_r * */vec4(abs(norm) * (1.0 - dist), dist))
|
||||||
|
//)
|
||||||
|
;
|
||||||
|
|
||||||
vec3 wh = -light_dir + dir;
|
vec3 wh = -light_dir + dir;
|
||||||
if (cos_wi <= 0.0 || cos_wo <= 0.0) {
|
#if (LIGHTING_TYPE & LIGHTING_TYPE_TRANSMISSION) != 0
|
||||||
|
bool is_blocked = cos_wi == 0.0 || cos_wo == 0.0;
|
||||||
|
#else
|
||||||
|
bool is_blocked = cos_wi <= 0.0 || cos_wo <= 0.0;
|
||||||
|
#endif
|
||||||
|
if (is_blocked) {
|
||||||
return vec3(/*diffuse*/0.0);
|
return vec3(/*diffuse*/0.0);
|
||||||
}
|
}
|
||||||
wh = normalize(wh);//mix(normalize(wh), vec3(0.0), equal(light_dir, dir));
|
wh = normalize(wh);//mix(normalize(wh), vec3(0.0), equal(light_dir, dir));
|
||||||
float dot_wi_wh = dot(-light_dir, wh);
|
float dot_wi_wh = dot(-light_dir, wh);
|
||||||
|
// float distr = TrowbridgeReitzDistribution_D_Voxel(wh, norm, alpha);
|
||||||
float distr = BeckmannDistribution_D_Voxel(wh, norm, alpha);
|
float distr = BeckmannDistribution_D_Voxel(wh, norm, alpha);
|
||||||
// float distr = BeckmannDistribution_D(dot(wh, norm), alpha);
|
// float distr = BeckmannDistribution_D(dot(wh, norm), alpha);
|
||||||
vec3 specular = distr /
|
vec3 specular = distr /
|
||||||
(4 * abs(dot_wi_wh)) *
|
(4 * abs(dot_wi_wh) *
|
||||||
max(abs(cos_wi), abs(cos_wo)) *
|
max(abs(cos_wi), abs(cos_wo))) *
|
||||||
schlick_fresnel(R_s, dot_wi_wh);
|
schlick_fresnel(R_s, dot_wi_wh);
|
||||||
return mix(/*diffuse*//* + specular*/diffuse + specular, vec3(0.0), bvec3(all(equal(light_dir, dir))));
|
return mix(/*diffuse*//* + specular*/diffuse + specular, vec3(0.0), bvec3(all(equal(light_dir, dir))));
|
||||||
}
|
}
|
||||||
@ -226,7 +301,7 @@ vec3 FresnelBlend_Voxel_f(vec3 norm, vec3 dir, vec3 light_dir, vec3 R_d, vec3 R_
|
|||||||
// Phong reflection.
|
// Phong reflection.
|
||||||
//
|
//
|
||||||
// Note: norm, dir, light_dir must all be normalizd.
|
// Note: norm, dir, light_dir must all be normalizd.
|
||||||
vec3 light_reflection_factor(vec3 norm, vec3 dir, vec3 light_dir, vec3 k_d, vec3 k_s, float alpha) {
|
vec3 light_reflection_factor2(vec3 norm, vec3 dir, vec3 light_dir, vec3 k_d, vec3 k_s, float alpha) {
|
||||||
// TODO: These are supposed to be the differential changes in the point location p, in tangent space.
|
// TODO: These are supposed to be the differential changes in the point location p, in tangent space.
|
||||||
// That is, assuming we can parameterize a 2D surface by some function p : R² → R³, mapping from
|
// That is, assuming we can parameterize a 2D surface by some function p : R² → R³, mapping from
|
||||||
// points in a plane to 3D points on the surface, we can define
|
// points in a plane to 3D points on the surface, we can define
|
||||||
@ -291,11 +366,67 @@ vec3 light_reflection_factor(vec3 norm, vec3 dir, vec3 light_dir, vec3 k_d, vec3
|
|||||||
}
|
}
|
||||||
|
|
||||||
vec3 light_reflection_factor(vec3 norm, vec3 dir, vec3 light_dir, vec3 k_d, vec3 k_s, float alpha, float voxel_lighting) {
|
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) {
|
#if (LIGHTING_ALGORITHM == LIGHTING_ALGORITHM_LAMBERTIAN)
|
||||||
|
const float PI = 3.141592;
|
||||||
|
#if (LIGHTING_DISTRIBUTION_SCHEME == LIGHTING_DISTRIBUTION_SCHEME_VOXEL)
|
||||||
|
#if (LIGHTING_TYPE & LIGHTING_TYPE_TRANSMISSION) != 0
|
||||||
|
vec4 AbsNdotL = abs(vec4(light_dir, dot(norm, light_dir)));
|
||||||
|
#else
|
||||||
|
vec3 sides = sign(norm);
|
||||||
|
vec4 AbsNdotL = max(vec4(-light_dir * sides, dot(norm, -light_dir)), 0.0);
|
||||||
|
#endif
|
||||||
|
float diffuse = dot(AbsNdotL, vec4(abs(norm) * (1.0 - voxel_lighting), voxel_lighting));
|
||||||
|
#elif (LIGHTING_DISTRIBUTION_SCHEME == LIGHTING_DISTRIBUTION_SCHEME_MICROFACET)
|
||||||
|
#if (LIGHTING_TYPE & LIGHTING_TYPE_TRANSMISSION) != 0
|
||||||
|
float diffuse = abs(dot(norm, light_dir));
|
||||||
|
#else
|
||||||
|
float diffuse = max(dot(norm, -light_dir), 0.0);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
return k_d / PI * diffuse;
|
||||||
|
#elif (LIGHTING_ALGORITHM == LIGHTING_ALGORITHM_BLINN_PHONG)
|
||||||
|
const float PI = 3.141592;
|
||||||
|
alpha = alpha * sqrt(2.0);
|
||||||
|
#if (LIGHTING_TYPE & LIGHTING_TYPE_TRANSMISSION) != 0
|
||||||
|
float ndotL = abs(dot(norm, light_dir));
|
||||||
|
#else
|
||||||
|
float ndotL = max(dot(norm, -light_dir), 0.0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (ndotL > 0.0) {
|
||||||
|
#if (LIGHTING_DISTRIBUTION_SCHEME == LIGHTING_DISTRIBUTION_SCHEME_VOXEL)
|
||||||
|
#if (LIGHTING_TYPE & LIGHTING_TYPE_TRANSMISSION) != 0
|
||||||
|
vec4 AbsNdotL = abs(vec4(light_dir, ndotL));
|
||||||
|
#else
|
||||||
|
vec3 sides = sign(norm);
|
||||||
|
vec4 AbsNdotL = max(vec4(-light_dir * sides, ndotL), 0.0);
|
||||||
|
#endif
|
||||||
|
float diffuse = dot(AbsNdotL, vec4(abs(norm) * (1.0 - voxel_lighting), voxel_lighting));
|
||||||
|
#elif (LIGHTING_DISTRIBUTION_SCHEME == LIGHTING_DISTRIBUTION_SCHEME_MICROFACET)
|
||||||
|
float diffuse = ndotL;
|
||||||
|
#endif
|
||||||
|
vec3 H = normalize(-light_dir + dir);
|
||||||
|
|
||||||
|
#if (LIGHTING_TYPE & LIGHTING_TYPE_TRANSMISSION) != 0
|
||||||
|
float NdotH = abs(dot(norm, H));
|
||||||
|
#else
|
||||||
|
float NdotH = max(dot(norm, H), 0.0);
|
||||||
|
#endif
|
||||||
|
return (1.0 - k_s) / PI * k_d * diffuse + k_s * pow(NdotH, alpha/* * 4.0*/);
|
||||||
|
}
|
||||||
|
|
||||||
|
return vec3(0.0);
|
||||||
|
#elif (LIGHTING_ALGORITHM == LIGHTING_ALGORITHM_ASHIKHMIN)
|
||||||
|
#if (LIGHTING_DISTRIBUTION_SCHEME == LIGHTING_DISTRIBUTION_SCHEME_VOXEL)
|
||||||
return FresnelBlend_Voxel_f(norm, dir, light_dir, k_d/* * max(dot(norm, -light_dir), 0.0)*/, k_s, alpha, voxel_lighting);
|
return FresnelBlend_Voxel_f(norm, dir, light_dir, k_d/* * max(dot(norm, -light_dir), 0.0)*/, k_s, alpha, voxel_lighting);
|
||||||
|
#elif (LIGHTING_DISTRIBUTION_SCHEME == LIGHTING_DISTRIBUTION_SCHEME_MICROFACET)
|
||||||
|
//if (voxel_lighting < 1.0) {
|
||||||
|
return FresnelBlend_f(norm, dir, light_dir, k_d/* * max(dot(norm, -light_dir), 0.0)*/, k_s, alpha);
|
||||||
//} else {
|
//} else {
|
||||||
// return FresnelBlend_f(norm, dir, light_dir, k_d/* * max(dot(norm, -light_dir), 0.0)*/, k_s, alpha);
|
// return FresnelBlend_f(norm, dir, light_dir, k_d/* * max(dot(norm, -light_dir), 0.0)*/, k_s, alpha);
|
||||||
//}
|
//}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
float rel_luminance(vec3 rgb)
|
float rel_luminance(vec3 rgb)
|
||||||
@ -338,6 +469,9 @@ bool IntersectRayPlane(vec3 rayOrigin, vec3 rayDirection, vec3 posOnPlane, vec3
|
|||||||
//
|
//
|
||||||
// Ideally, defaultpos is set so we can avoid branching on error.
|
// 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) {
|
vec3 compute_attenuation(vec3 wpos, vec3 ray_dir, vec3 mu, float surface_alt, vec3 defaultpos) {
|
||||||
|
#if (LIGHTING_TRANSPORT_MODE == LIGHTING_TRANSPORT_MODE_IMPORTANCE)
|
||||||
|
return vec3(1.0);
|
||||||
|
#elif (LIGHTING_TRANSPORT_MODE == LIGHTING_TRANSPORT_MODE_RADIANCE)
|
||||||
// return vec3(1.0);
|
// return vec3(1.0);
|
||||||
/*if (mu == vec3(0.0)) {
|
/*if (mu == vec3(0.0)) {
|
||||||
return vec3(1.0);
|
return vec3(1.0);
|
||||||
@ -345,17 +479,41 @@ vec3 compute_attenuation(vec3 wpos, vec3 ray_dir, vec3 mu, float surface_alt, ve
|
|||||||
return vec3(0.0);
|
return vec3(0.0);
|
||||||
}*/
|
}*/
|
||||||
// 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(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(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 = 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));
|
// 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);
|
bool _intersects_surface = IntersectRayPlane(wpos, ray_dir, vec3(0.0, 0.0, surface_alt), surface_dir, defaultpos);
|
||||||
float depth = length(defaultpos - wpos);
|
float depth = length(defaultpos - wpos);
|
||||||
return exp(-mu * depth);
|
return exp(-mu * depth);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 compute_attenuation2(vec3 wpos, vec3 ray_dir, vec3 mu, float surface_alt, vec3 defaultpos) {
|
||||||
|
#if (LIGHTING_TRANSPORT_MODE == LIGHTING_TRANSPORT_MODE_IMPORTANCE)
|
||||||
|
return vec3(1.0);
|
||||||
|
#elif (LIGHTING_TRANSPORT_MODE == LIGHTING_TRANSPORT_MODE_RADIANCE)
|
||||||
|
// return vec3(1.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(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);
|
||||||
|
return exp(-mu * depth);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Same as compute_attenuation but since both point are known, set a maximum to make sure we don't exceed the length
|
// Same as compute_attenuation but since both point are known, set a maximum to make sure we don't exceed the length
|
||||||
// from the default point.
|
// from the default point.
|
||||||
vec3 compute_attenuation_point(vec3 wpos, vec3 ray_dir, vec3 mu, float surface_alt, vec3 defaultpos) {
|
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);
|
||||||
|
#elif (LIGHTING_TRANSPORT_MODE == LIGHTING_TRANSPORT_MODE_RADIANCE)
|
||||||
// return vec3(1.0);
|
// return vec3(1.0);
|
||||||
/*if (mu == vec3(0.0)) {
|
/*if (mu == vec3(0.0)) {
|
||||||
return vec3(1.0);
|
return vec3(1.0);
|
||||||
@ -370,4 +528,5 @@ vec3 compute_attenuation_point(vec3 wpos, vec3 ray_dir, vec3 mu, float surface_a
|
|||||||
bool _intersects_surface = IntersectRayPlane(wpos, ray_dir, vec3(0.0, 0.0, surface_alt), surface_dir, defaultpos);
|
bool _intersects_surface = IntersectRayPlane(wpos, ray_dir, vec3(0.0, 0.0, surface_alt), surface_dir, defaultpos);
|
||||||
float depth2 = min(max_length, dot(defaultpos - wpos, defaultpos - wpos));
|
float depth2 = min(max_length, dot(defaultpos - wpos, defaultpos - wpos));
|
||||||
return exp(-mu * sqrt(depth2));
|
return exp(-mu * sqrt(depth2));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
41
assets/voxygen/shaders/light-shadows-frag.glsl
Normal file
41
assets/voxygen/shaders/light-shadows-frag.glsl
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
// NOTE: We currently do nothing, and just rely on the default shader behavior.
|
||||||
|
//
|
||||||
|
// However, in the future we might apply some depth transforms here.
|
||||||
|
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
#include <constants.glsl>
|
||||||
|
|
||||||
|
#define LIGHTING_TYPE LIGHTING_TYPE_REFLECTION
|
||||||
|
|
||||||
|
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_GLOSSY
|
||||||
|
|
||||||
|
#if (FLUID_MODE == FLUID_MODE_CHEAP)
|
||||||
|
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
|
||||||
|
#elif (FLUID_MODE == FLUID_MODE_SHINY)
|
||||||
|
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION_SCHEME LIGHTING_DISTRIBUTION_SCHEME_MICROFACET
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION LIGHTING_DISTRIBUTION_BECKMANN
|
||||||
|
|
||||||
|
// Currently, we only need globals for the far plane.
|
||||||
|
#include <globals.glsl>
|
||||||
|
// Currently, we only need lights for the light position
|
||||||
|
#include <light.glsl>
|
||||||
|
|
||||||
|
in vec4 FragPos; // FragPos from GS (output per emitvertex)
|
||||||
|
flat in int FragLayer;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// get distance between fragment and light source
|
||||||
|
float lightDistance = length(FragPos.xyz - lights[FragLayer & 31].light_pos.xyz);
|
||||||
|
|
||||||
|
// map to [0;1] range by dividing by far_plane
|
||||||
|
lightDistance = lightDistance / /*FragPos.w;*/screen_res.w;
|
||||||
|
|
||||||
|
// write this as modified depth
|
||||||
|
gl_FragDepth = lightDistance;
|
||||||
|
}
|
198
assets/voxygen/shaders/light-shadows-geom.glsl
Normal file
198
assets/voxygen/shaders/light-shadows-geom.glsl
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
// Adapted from https://learnopengl.com/Advanced-Lighting/Shadows/Point-Shadows
|
||||||
|
|
||||||
|
// NOTE: We only technically need this for cube map arrays and geometry shader
|
||||||
|
// instancing.
|
||||||
|
#version 400 core
|
||||||
|
|
||||||
|
// Currently, we only need globals for the max light count (light_shadow_count.x).
|
||||||
|
#include <globals.glsl>
|
||||||
|
|
||||||
|
// Since our output primitive is a triangle strip, we have to render three vertices
|
||||||
|
// each.
|
||||||
|
#define VERTICES_PER_FACE 3
|
||||||
|
|
||||||
|
// Since we render our depth texture to a cube map, we need to render each face
|
||||||
|
// six times. If we used other shadow mapping methods with fewer outputs, this would
|
||||||
|
// shrink considerably.
|
||||||
|
#define FACES_PER_POINT_LIGHT 6
|
||||||
|
|
||||||
|
// If MAX_VERTEX_UNIFORM_COMPONENTS_ARB = 512 on many platforms, and we want a mat4
|
||||||
|
// for each of 6 directions for each light, 20 is close to the maximum allowable
|
||||||
|
// size. We could add a final matrix for the directional light of the sun or moon
|
||||||
|
// to bring us to 126 matrices, which is just 2 off.
|
||||||
|
//
|
||||||
|
// To improve this limit, we could do many things, such as:
|
||||||
|
// - choose an implementation that isn't cube maps (e.g. tetrahedrons or curves;
|
||||||
|
// if there were an easy way to sample from tetrahedrons, we'd be at 32 * 4 = 128
|
||||||
|
// exactly, leaving no room for a solar body, though).
|
||||||
|
// - Do more work in the geometry shader (e.g. just have a single projection
|
||||||
|
// matrix per light, and derive the different-facing components; or there may be
|
||||||
|
// other ways of greatly simplifying this). The tradeoff would be losing performance
|
||||||
|
// here.
|
||||||
|
// - Use ARB_instanced_arrays and switch lights with indexing, instead of a uniform
|
||||||
|
// buffer. This would probably work fine (and ARB_instanced_arrays is supported on
|
||||||
|
// pretty much every platform), but AFAIK it's possible that instanced arrays are
|
||||||
|
// slower than uniform arraay access on many platforms.
|
||||||
|
// - Don't try to do everything in one call (break this out into multiple passes).
|
||||||
|
//
|
||||||
|
// Actually, according to what I'm reading, MAX_GEOM_UNIFORM_COMPONENTS = 1024, and
|
||||||
|
// gl_MaxGeometryUniformComponents = 1024.
|
||||||
|
//
|
||||||
|
// Also, this only applies to uniforms defined *outside* of uniform blocks, of which
|
||||||
|
// there can be up to 12 (14 in OpenGL 4.3, which we definitely can't support).
|
||||||
|
// GL_MAX_UNIFORM_BLOCK_SIZE has a minimum of 16384, which *easily* exceeds our usage
|
||||||
|
// constraints. So this part might not matter.
|
||||||
|
//
|
||||||
|
// Other restrictions are easy to satisfy:
|
||||||
|
//
|
||||||
|
// gl_MaxGeometryVaryingComponents has a minimum of 64 and is the maximum number of
|
||||||
|
// varying components; I think this is the number of out components per vertex, which
|
||||||
|
// is technically 0, but would be 4 if we wrote FragPos. But it might also
|
||||||
|
// be the *total* number of varying components, in which case if we wrote FragPos
|
||||||
|
// it would be 4 * 20 * 6 * 3 = 1440, which would blow it out of the water. However,
|
||||||
|
// I kind of doubt this interpretation because writing FragPos for each of 18 vertices,
|
||||||
|
// as the original shader did, already yields 4 * 18 = 72, and it seems unlikely that
|
||||||
|
// the original example exceeds OpenGL limits.
|
||||||
|
//
|
||||||
|
// gl_MaxGeometryOutputComponents has a minimum of 128 and is the maximum number of
|
||||||
|
// components allowed in out variables; we easily fall under this since we actually
|
||||||
|
// have 0 of these. However, if we were to write FragPos for each vertex, it *might*
|
||||||
|
// cause us to exceed this limit, depending on whether it refers to the total output
|
||||||
|
// component count *including* varying components, or not. See the previous
|
||||||
|
// discussion; since 72 < 128 it's more plausible that this interpretation might be
|
||||||
|
// correct, but hopefully it's not.
|
||||||
|
//
|
||||||
|
// gl_MaxGeometryInputComponents has a minimum of 64 and we easily fall under that
|
||||||
|
// limit (I'm actually not sure we even have any user-defined input components?).
|
||||||
|
//
|
||||||
|
// gl_MaxGeometryTextureImageUnits = 16 and we have no texture image units (or maybe
|
||||||
|
// 1, the one we bound?). This might come into play if we were to have attached
|
||||||
|
// cubemaps instead of a single cubemap array, in which case it would limit us to
|
||||||
|
// 16 lights *regardless* of any of the fixes mentioned above (i.e., we'd just have
|
||||||
|
// to split up draw calls, I think).
|
||||||
|
//
|
||||||
|
// ---
|
||||||
|
//
|
||||||
|
// However, there is another limit to consider: GL_MAX_GEOMETRY_OUTPUT_VERTICES. Its
|
||||||
|
// minimum is 256, and 20 * 6 * 3 = 360, which exceeds that. This introduces a new
|
||||||
|
// limit of at most 14 point lights.
|
||||||
|
//
|
||||||
|
// Another, related limit is GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS. This counts
|
||||||
|
// every component output ("component" is usually a 4-byte field of a vector, but maybe
|
||||||
|
// this would improve with something like half-floats?), and has a minimum (as of
|
||||||
|
// OpenGL 3.3) of 1024. Since even builtin outputs gl_Layer count against this total,
|
||||||
|
// this means we issue 5 components per vertex, and 14 * 6 * 3 * 5 = 1260 > 1024.
|
||||||
|
//
|
||||||
|
// Ultimately, we find our maximum output limit of 11, ≤ 1024/5/3/6.
|
||||||
|
//
|
||||||
|
// If we choose to reserve a slot for a non-point light (and/or other uniforms), it
|
||||||
|
// is just 10, or half what we got from VERTICES_PER_FACE (we could also round down to
|
||||||
|
// 8 as a power of 2, if we had to).
|
||||||
|
//
|
||||||
|
// Unlike the input limits, whwich we can get around with "clever" solutions, it seems
|
||||||
|
// likely that the only real way to defeat the vertex limits is to use instancing of
|
||||||
|
// some sort (be it geometry shader or otherwise). This would restrict us to OpenGL
|
||||||
|
// 4.0 or above.
|
||||||
|
//
|
||||||
|
// A further consideration (were we to switch to OpenGL 4.1-supported features, but
|
||||||
|
// actually it is often supported on 3.3 hardware with ARB_viewport_array--whereas
|
||||||
|
// geometry shader instancing is *not* supported on any 3.3 hardware, so would actually
|
||||||
|
// require us to upgrade) would be setting gl_ViewportIndex. The main reason to consider
|
||||||
|
// this is that it allows specifying a separate scissor rectangle per viewport. This
|
||||||
|
// introduces two new constraints. Firstly, it adds an extra component to each vertex
|
||||||
|
// (lowering our maximum to 9 faces per light ≤ 1024/6/3/6, or 8 if we want to support a
|
||||||
|
// directional light).
|
||||||
|
//
|
||||||
|
// Secondly, a new constant (MAX_VIEWPORTS) is introduced, which would restrict the
|
||||||
|
// total number of active viewports; the minimum value for this is 16. While this may
|
||||||
|
// not seem all that relevant since our current hard limit is 11, the difference is that
|
||||||
|
// this limit would apply *across* instanced calls (since it may be a "global"
|
||||||
|
// restriction, tied to the OpenGL context; this means it couldn't even be a multiple
|
||||||
|
// frame buffer thing, as there is usually one per window). This would also tie in
|
||||||
|
// with gl_MaxGeometryTextureImageUnits, I guess.
|
||||||
|
//
|
||||||
|
// --
|
||||||
|
//
|
||||||
|
// I just realized tht using cube map arrays at all bumps our required OpenGL
|
||||||
|
// version to 4.0, so let's just do instancing...
|
||||||
|
//
|
||||||
|
// The instancing limit on MAX_GEOMETRY_SHADER_INVOCATIONS has a minimum of 32, which
|
||||||
|
// would be sufficient to run through all 32 lights with a different cube map and
|
||||||
|
// completely removes any imits on ight count.
|
||||||
|
//
|
||||||
|
// This should instantly bring us below all relevant limits in all cases considered
|
||||||
|
// except for the two that would require 16. Unfortunately, 32 is also the *maximum*
|
||||||
|
// number of point lights, which is much higher than the usual value, and the instance
|
||||||
|
// count has to be a constant. If we were to instead geometry-shader-instance each
|
||||||
|
// *face*, we'd get a maximum light count of 56 ≤ 1024/6/3, which is not as elegant
|
||||||
|
// but is easily higher than 32. So, let's try using that instead.
|
||||||
|
//
|
||||||
|
// It is *possible* that using instancing on the *vertex* shader with the (dynamically
|
||||||
|
// uniform) total number of instances set to the actual number of point lights, would
|
||||||
|
// improve performance, since it would give us a 1:1 vertex input:output ratio, which
|
||||||
|
// might be optimized in hardware.
|
||||||
|
//
|
||||||
|
// It also seems plausible that constructing a separate geometry shader with values
|
||||||
|
// from 1 to 32 would be worthwhile, but that seems a little extreme.
|
||||||
|
//
|
||||||
|
// ---
|
||||||
|
//
|
||||||
|
// Since wgpu doesn't support geometry shaders anyway, it seems likely that we'll have
|
||||||
|
// to do the multiple draw calls, anyway... I don't think gl_Layer can be set from
|
||||||
|
// outside a geometry shader. But in wgpu, such a thing is much cheaper, anyway.
|
||||||
|
#define MAX_POINT_LIGHTS 32
|
||||||
|
|
||||||
|
// We use geometry shader instancing to construct each face separately.
|
||||||
|
#define MAX_LAYER_VERTICES_PER_FACE (MAX_POINT_LIGHTS * VERTICES_PER_FACE)
|
||||||
|
|
||||||
|
#define MAX_LAYER_FACES (MAX_POINT_LIGHTS * FACES_PER_POINT_LIGHT)
|
||||||
|
|
||||||
|
layout (triangles, invocations = 6) in;
|
||||||
|
|
||||||
|
layout (triangle_strip, max_vertices = /*MAX_LAYER_VERTICES_PER_FACE*/96) out;
|
||||||
|
|
||||||
|
struct ShadowLocals {
|
||||||
|
mat4 shadowMatrices;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout (std140)
|
||||||
|
uniform u_light_shadows {
|
||||||
|
ShadowLocals shadowMats[/*MAX_LAYER_FACES*/192];
|
||||||
|
};
|
||||||
|
|
||||||
|
// NOTE: We choose not to output FragPos currently to save on space limitations
|
||||||
|
// (see extensive documentation above). However, as these limitations have been
|
||||||
|
// relaxed (unless the total of all our varying output components can't exceed
|
||||||
|
// 128, which would mean FragPos would sum to 4 * 3 * 32 = 384; this could be
|
||||||
|
// remedied only by setting MAX_POINT_LIGHTS to ), we might enable it again soon.
|
||||||
|
//
|
||||||
|
out vec4 FragPos; // FragPos from GS (output per emitvertex)
|
||||||
|
flat out int FragLayer; // Current layer
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
// NOTE: Assuming that light_shadow_count.x < MAX_POINT_LIGHTS. We could min
|
||||||
|
// it, but that might make this less optimized, and I'd like to keep this loop as
|
||||||
|
// optimized as is reasonably possible.
|
||||||
|
int face = gl_InvocationID;
|
||||||
|
|
||||||
|
for (int layer = 0; layer < light_shadow_count.x; ++layer)
|
||||||
|
{
|
||||||
|
// We use instancing here in order to increase the number of emitted vertices.
|
||||||
|
// int face = gl_InvocationID;
|
||||||
|
// for(int face = 0; face < FACES_PER_POINT_LIGHT; ++face)
|
||||||
|
// {
|
||||||
|
int layer_face = layer * FACES_PER_POINT_LIGHT + face;
|
||||||
|
for(int i = 0; i < VERTICES_PER_FACE; ++i) // for each triangle vertex
|
||||||
|
{
|
||||||
|
// NOTE: See above, we don't make FragPos a uniform.
|
||||||
|
FragPos = gl_in[i].gl_Position;
|
||||||
|
FragLayer = layer;
|
||||||
|
// vec4 FragPos = gl_in[i].gl_Position;
|
||||||
|
gl_Layer = layer_face; // built-in variable that specifies to which face we render.
|
||||||
|
gl_Position = shadowMats[layer_face].shadowMatrices * FragPos;
|
||||||
|
EmitVertex();
|
||||||
|
}
|
||||||
|
EndPrimitive();
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
51
assets/voxygen/shaders/light-shadows-vert.glsl
Normal file
51
assets/voxygen/shaders/light-shadows-vert.glsl
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#version 330 core
|
||||||
|
|
||||||
|
#include <constants.glsl>
|
||||||
|
|
||||||
|
#define LIGHTING_TYPE LIGHTING_TYPE_REFLECTION
|
||||||
|
|
||||||
|
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_GLOSSY
|
||||||
|
|
||||||
|
#if (FLUID_MODE == FLUID_MODE_CHEAP)
|
||||||
|
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
|
||||||
|
#elif (FLUID_MODE == FLUID_MODE_SHINY)
|
||||||
|
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION_SCHEME LIGHTING_DISTRIBUTION_SCHEME_MICROFACET
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION LIGHTING_DISTRIBUTION_BECKMANN
|
||||||
|
|
||||||
|
// Currently, we only need globals for the all_mat matrix.
|
||||||
|
#include <globals.glsl>
|
||||||
|
|
||||||
|
/* Accurate packed shadow maps for many lights at once!
|
||||||
|
*
|
||||||
|
* Ideally, we would just write to a bitmask...
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
|
||||||
|
in uint v_pos_norm;
|
||||||
|
in uint v_col_light;
|
||||||
|
|
||||||
|
// Light projection matrices.
|
||||||
|
layout (std140)
|
||||||
|
uniform u_locals {
|
||||||
|
vec3 model_offs;
|
||||||
|
float load_time;
|
||||||
|
};
|
||||||
|
|
||||||
|
// out vec4 shadowMapCoord;
|
||||||
|
|
||||||
|
const int EXTRA_NEG_Z = 32768;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec3 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;
|
||||||
|
// f_pos = v_pos;
|
||||||
|
vec3 f_pos = f_chunk_pos + model_offs;
|
||||||
|
|
||||||
|
gl_Position = /*all_mat * */vec4(f_pos, 1.0);
|
||||||
|
// shadowMapCoord = lights[gl_InstanceID].light_pos * gl_Vertex;
|
||||||
|
// vec4(v_pos, 0.0, 1.0);
|
||||||
|
}
|
@ -1,5 +1,21 @@
|
|||||||
#version 330 core
|
#version 330 core
|
||||||
|
|
||||||
|
#include <constants.glsl>
|
||||||
|
|
||||||
|
#define LIGHTING_TYPE LIGHTING_TYPE_REFLECTION
|
||||||
|
|
||||||
|
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_GLOSSY
|
||||||
|
|
||||||
|
#if (FLUID_MODE == FLUID_MODE_CHEAP)
|
||||||
|
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
|
||||||
|
#elif (FLUID_MODE == FLUID_MODE_SHINY)
|
||||||
|
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION_SCHEME LIGHTING_DISTRIBUTION_SCHEME_VOXEL
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION LIGHTING_DISTRIBUTION_BECKMANN
|
||||||
|
|
||||||
#include <globals.glsl>
|
#include <globals.glsl>
|
||||||
#include <sky.glsl>
|
#include <sky.glsl>
|
||||||
#include <lod.glsl>
|
#include <lod.glsl>
|
||||||
@ -83,10 +99,6 @@ void main() {
|
|||||||
// vec3 f_up = faceforward(cam_pos.xyz - f_pos, vec3(0.0, 0.0, -1.0), cam_pos.xyz - f_pos);
|
// vec3 f_up = faceforward(cam_pos.xyz - f_pos, vec3(0.0, 0.0, -1.0), cam_pos.xyz - f_pos);
|
||||||
// vec3 f_norm = faceforward(f_norm, /*vec3(cam_pos.xyz - f_pos.xyz)*/vec3(0.0, 0.0, -1.0), f_norm);
|
// vec3 f_norm = faceforward(f_norm, /*vec3(cam_pos.xyz - f_pos.xyz)*/vec3(0.0, 0.0, -1.0), f_norm);
|
||||||
|
|
||||||
vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz);
|
|
||||||
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 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);
|
// const mat3 side_norms = vec3(1, 0, 0), vec3(0, 1, 0), vec3(0, 0, 1);
|
||||||
// mat3 sides = mat3(
|
// mat3 sides = mat3(
|
||||||
@ -156,11 +168,138 @@ void main() {
|
|||||||
// }
|
// }
|
||||||
// voxel_norm = normalize(voxel_norm); */
|
// 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);
|
float dist_lerp = clamp(pow(max(distance(focus_pos.xy, f_pos.xy) - view_distance.x, 0.0) / 4096.0, 2.0), 0, 1);
|
||||||
// dist_lerp = 0.0;
|
// dist_lerp = 0.0;
|
||||||
// voxel_norm = normalize(mix(voxel_norm, f_norm, /*pow(dist_lerp, 1.0)*/dist_lerp));
|
// voxel_norm = normalize(mix(voxel_norm, f_norm, /*pow(dist_lerp, 1.0)*/dist_lerp));
|
||||||
|
|
||||||
vec3 voxel_norm = f_norm;
|
// IDEA:
|
||||||
|
// We can represent three faces as sign(voxel_norm).
|
||||||
|
vec3 sides = sign(f_norm);
|
||||||
|
// There are three relevant vectors: normal, tangent, and bitangent.
|
||||||
|
// We say normal is the z component, tangent the x component, bitangent the y.
|
||||||
|
// A blocking side is in the reverse direction of each.
|
||||||
|
// So -sides is the *direction* of the next block.
|
||||||
|
// Now, we want to multiply this by the *distance* to the nearest integer in that direction.
|
||||||
|
// If sides.x is -1, the direction is 1, so the distance is 1.0 - fract(f_pos.x) and the delta is 1.0 - fract(f_pos.x).
|
||||||
|
// If sides.x is 1, the direction is -1, so the distance is fract(f_pos.x) and the delta is -fract(f_pos.x) = 1.0 + fract(-f_pos.x).
|
||||||
|
// If sides.x is 0, the direction is 0, so the distance is 0.0 and the delta is 0.0 = 0.0 + fract(0.0 * f_pos.x).
|
||||||
|
// (we ignore f_pos < 0 for the time being).
|
||||||
|
// Then this is 1.0 + sides.x * fract(-sides.x * f_pos.x);
|
||||||
|
// We repeat this for y.
|
||||||
|
//
|
||||||
|
// We treat z as the dependent variable.
|
||||||
|
// IF voxel_norm.x > 0.0, z should increase by voxel_norm.z / voxel_norm.x * delta_sides.x in the x direction;
|
||||||
|
// IF voxel_norm.y > 0.0, z should increase by voxel_norm.z / voxel_norm.y * delta_sides.y in the y direction;
|
||||||
|
// IF voxel_norm.x = 0.0, z should not increase in the x direction;
|
||||||
|
// IF voxel_norm.y = 0.0, z should not increase in the y direction;
|
||||||
|
// we assume that ¬(voxel_norm.z = 0).
|
||||||
|
//
|
||||||
|
// Now observe that we can rephrase this as saying, given a desired change in z (to get to the next integer), how far must
|
||||||
|
// we travel along x and y?
|
||||||
|
//
|
||||||
|
// TODO: Handle negative numbers.
|
||||||
|
vec3 delta_sides = mix(-fract(f_pos), 1.0 - fract(f_pos), lessThan(sides, vec3(0.0)));
|
||||||
|
// vec3 delta_sides = mix(1.0 - fract(f_pos), -fract(f_pos), lessThan(sides, vec3(0.0)));
|
||||||
|
// vec3 delta_sides = 1.0 + sides * fract(-sides * f_pos);
|
||||||
|
// Three faces: xy, xz, and yz.
|
||||||
|
// TODO: Handle zero slopes (for xz and yz).
|
||||||
|
vec2 corner_xy = min(abs(f_norm.xy / f_norm.z * delta_sides.z), 1.0);
|
||||||
|
vec2 corner_yz = min(abs(f_norm.yz / f_norm.x * delta_sides.x), 1.0);
|
||||||
|
vec2 corner_xz = min(abs(f_norm.xz / f_norm.y * delta_sides.y), 1.0);
|
||||||
|
// vec3 corner_delta = vec3(voxel_norm.xy / voxel_norm.z * delta_sides.z, delta_sides.z);
|
||||||
|
// Now we just compute an (upper bounded) distance to the corner in each direction.
|
||||||
|
// vec3 corner_distance = min(abs(corner_delta), 1.0);
|
||||||
|
// Now, if both sides hit something, lerp to 0.0. If one side hits something, lerp to 0.4. And if no sides hit something,
|
||||||
|
// lerp to 1.0.
|
||||||
|
// Bilinear interpolation on each plane:
|
||||||
|
float ao_xy = dot(vec2(1.0 - corner_xy.x, corner_xy.x), mat2(vec2(corner_xy.x < 1.00 ? corner_xy.y < 1.00 ? 0.0 : 0.25 : corner_xy.y < 1.00 ? 0.25 : 1.0, corner_xy.x < 1.00 ? 0.25 : 1.0), vec2(corner_xy.y < 1.00 ? 0.25 : 1.0, 1.0)) * vec2(1.0 - corner_xy.y, corner_xy.y));
|
||||||
|
float ao_yz = dot(vec2(1.0 - corner_yz.x, corner_yz.x), mat2(vec2(corner_yz.x < 1.00 ? corner_yz.y < 1.00 ? 0.0 : 0.25 : corner_yz.y < 1.00 ? 0.25 : 1.0, corner_yz.x < 1.00 ? 0.25 : 1.0), vec2(corner_yz.y < 1.00 ? 0.25 : 1.0, 1.0)) * vec2(1.0 - corner_yz.y, corner_yz.y));
|
||||||
|
float ao_xz = dot(vec2(1.0 - corner_xz.x, corner_xz.x), mat2(vec2(corner_xz.x < 1.00 ? corner_xz.y < 1.00 ? 0.0 : 0.25 : corner_xz.y < 1.00 ? 0.25 : 1.0, corner_xz.x < 1.00 ? 0.25 : 1.0), vec2(corner_xz.y < 1.00 ? 0.25 : 1.0, 1.0)) * vec2(1.0 - corner_xz.y, corner_xz.y));
|
||||||
|
// Now, multiply each component by the face "share" which is just the absolute value of its normal for that plane...
|
||||||
|
// vec3 f_ao_vec = mix(abs(vec3(ao_yz, ao_xz, ao_xy)), vec3(1.0), bvec3(f_norm.yz == vec2(0.0), f_norm.xz == vec2(0.0), f_norm.xy == vec2(0.0)));
|
||||||
|
// vec3 f_ao_vec = mix(abs(vec3(ao_yz, ao_xz, ao_xy)), vec3(1.0), bvec3(length(f_norm.yz) <= 0.0, length(f_norm.xz) <= 0.0, length(f_norm.xy) <= 0.0));
|
||||||
|
// vec3 f_ao_vec = mix(abs(vec3(ao_yz, ao_xz, ao_xy)), vec3(1.0), bvec3(abs(f_norm.x) <= 0.0, abs(f_norm.y) <= 0.0, abs(f_norm.z) <= 0.0));
|
||||||
|
vec3 f_ao_vec = mix(/*abs(voxel_norm)*/vec3(1.0, 1.0, 1.0), /*abs(voxel_norm) * */vec3(ao_yz, ao_xz, ao_xy), /*abs(voxel_norm)*/vec3(length(f_norm.yz), length(f_norm.xz), length(f_norm.xy))/*vec3(1.0)*//*sign(max(view_dir * sides, 0.0))*/);
|
||||||
|
// f_ao_vec *= sign(max(view_dir * sides, 0.0));
|
||||||
|
// vec3 f_ao_view = max(vec3(dot(view_dir.yz, sides.yz), dot(view_dir.xz, sides.xz), dot(view_dir.xy, sides.xy)), 0.0);
|
||||||
|
// delta_sides *= sqrt(1.0 - f_ao_view * f_ao_view);
|
||||||
|
// delta_sides *= 1.0 - mix(view_dir / f_ao_view, vec3(0.0), equal(f_ao_view, vec3(0.0)));// sqrt(1.0 - f_ao_view * f_ao_view);
|
||||||
|
// delta_sides *= 1.0 - /*sign*/(max(vec3(dot(view_dir.yz, sides.yz), dot(view_dir.xz, sides.xz), dot(view_dir.xy, sides.xy)), 0.0));
|
||||||
|
// f_ao = length(f_ao_vec);
|
||||||
|
// f_ao = dot(f_ao_vec, vec3(1.0)) / 3.0;
|
||||||
|
// f_ao = 1.0 / sqrt(3.0) * sqrt(dot(f_ao_vec, vec3(1.0)));
|
||||||
|
// f_ao = pow(f_ao_vec.x * f_ao_vec.y * f_ao_vec.z * 3.0, 1.0 / 2.0); // 1.0 / sqrt(3.0) * sqrt(dot(f_ao_vec, vec3(1.0)));
|
||||||
|
// f_ao = pow(f_ao_vec.x * f_ao_vec.y * f_ao_vec.z, 1.0 / 3.0); // 1.0 / sqrt(3.0) * sqrt(dot(f_ao_vec, vec3(1.0)));
|
||||||
|
// f_ao = f_ao_vec.x * f_ao_vec.y * f_ao_vec.z + (1.0 - f_ao_vec.x) * (1.0 - f_ao_vec.y) * (1.0 - f_ao_vec.z);
|
||||||
|
// f_ao = sqrt((f_ao_vec.x + f_ao_vec.y + f_ao_vec.z) / 3.0); // 1.0 / sqrt(3.0) * sqrt(dot(f_ao_vec, vec3(1.0)));
|
||||||
|
// f_ao = sqrt(dot(f_ao_vec, abs(voxel_norm)));
|
||||||
|
// f_ao = 3.0 / (1.0 / f_ao_vec.x + 1.0 / f_ao_vec.y + 1.0 / f_ao_vec.z);
|
||||||
|
// f_ao = min(ao_yz, min(ao_xz, ao_xy));
|
||||||
|
// f_ao = max(f_ao_vec.x, max(f_ao_vec.y, f_ao_vec.z));
|
||||||
|
// f_ao = min(f_ao_vec.x, min(f_ao_vec.y, f_ao_vec.z));
|
||||||
|
// f_ao = sqrt(dot(f_ao_vec * abs(voxel_norm), sqrt(1.0 - delta_sides * delta_sides)) / 3.0);
|
||||||
|
// f_ao = dot(f_ao_vec, sqrt(1.0 - delta_sides * delta_sides));
|
||||||
|
// f_ao = dot(f_ao_vec, 1.0 - abs(delta_sides));
|
||||||
|
// f_ao =
|
||||||
|
// f_ao_vec.x < 1.0 ?
|
||||||
|
// f_ao_vec.y < 1.0 ?
|
||||||
|
// abs(delta_sides.x) < abs(delta_sides.y) ?
|
||||||
|
// f_ao_vec.z < 1.0 ? abs(delta_sides.x) < abs(delta_sides.z) ? f_ao_vec.x : f_ao_vec.z : f_ao_vec.x :
|
||||||
|
// f_ao_vec.z < 1.0 ? abs(delta_sides.y) < abs(delta_sides.z) ? f_ao_vec.y : f_ao_vec.z : f_ao_vec.y :
|
||||||
|
// f_ao_vec.z < 1.0 ? abs(delta_sides.x) < abs(delta_sides.z) ? f_ao_vec.x : f_ao_vec.z : f_ao_vec.x :
|
||||||
|
// f_ao_vec.y < 1.0 ?
|
||||||
|
// f_ao_vec.z < 1.0 ? abs(delta_sides.y) < abs(delta_sides.z) ? f_ao_vec.y : f_ao_vec.z : f_ao_vec.y :
|
||||||
|
// f_ao_vec.z;
|
||||||
|
// f_ao = abs(delta_sides.x) < abs(delta_sides.y) ? abs(delta_sides.x) < abs(delta_sides.z) ? f_ao_vec.x : f_ao_vec.z :
|
||||||
|
// abs(delta_sides.y) < abs(delta_sides.z) ? f_ao_vec.y : f_ao_vec.z;
|
||||||
|
// f_ao = abs(delta_sides.x) * f_ao_vec.x < abs(delta_sides.y) * f_ao_vec.y ? abs(delta_sides.x) * f_ao_vec.x < abs(delta_sides.z) * f_ao_vec.z ? f_ao_vec.x : f_ao_vec.z :
|
||||||
|
// abs(delta_sides.y) * f_ao_vec.y < abs(delta_sides.z) * f_ao_vec.z ? f_ao_vec.y : f_ao_vec.z;
|
||||||
|
// f_ao = dot(abs(voxel_norm), abs(voxel_norm) * f_ao_vec)/* / 3.0*/;
|
||||||
|
// f_ao = sqrt(dot(abs(voxel_norm), f_ao_vec) / 3.0);
|
||||||
|
// f_ao = /*abs(sides)*/max(sign(1.0 + view_dir * sides), 0.0) * f_ao);
|
||||||
|
// f_ao = mix(f_ao, 1.0, dist_lerp);
|
||||||
|
|
||||||
|
// vec3 voxel_norm = f_norm;
|
||||||
|
// vec3 voxel_norm =
|
||||||
|
// /*f_ao_vec.x < 1.0*/true ?
|
||||||
|
// /*f_ao_vec.y < 1.0*/true ?
|
||||||
|
// abs(delta_sides.x) < abs(delta_sides.y) ?
|
||||||
|
// /*f_ao_vec.z < 1.0 */true ? abs(delta_sides.x) < abs(delta_sides.z) ? vec3(sides.x, 0.0, 0.0) : vec3(0.0, 0.0, sides.z) : vec3(sides.x, 0.0, 0.0) :
|
||||||
|
// /*f_ao_vec.z < 1.0*/true ? abs(delta_sides.y) < abs(delta_sides.z) ? vec3(0.0, sides.y, 0.0) : vec3(0.0, 0.0, sides.z) : vec3(0.0, sides.y, 0.0) :
|
||||||
|
// /*f_ao_vec.z < 1.0*/true ? abs(delta_sides.x) < abs(delta_sides.z) ? vec3(sides.x, 0.0, 0.0) : vec3(0.0, 0.0, sides.z) : vec3(sides.x, 0.0, 0.0) :
|
||||||
|
// /*f_ao_vec.y < 1.0*/true ?
|
||||||
|
// /*f_ao_vec.z < 1.0*/true ? abs(delta_sides.y) < abs(delta_sides.z) ? vec3(0.0, sides.y, 0.0) : vec3(0.0, 0.0, sides.z) : vec3(0.0, sides.y, 0.0) :
|
||||||
|
// vec3(0.0, 0.0, sides.z);
|
||||||
|
/* vec3 voxel_norm =
|
||||||
|
f_ao_vec.x < 1.0 ?
|
||||||
|
f_ao_vec.y < 1.0 ?
|
||||||
|
abs(delta_sides.x) < abs(delta_sides.y) ?
|
||||||
|
f_ao_vec.z < 1.0 ? abs(delta_sides.x) < abs(delta_sides.z) ? vec3(sides.x, 0.0, 0.0) : vec3(0.0, 0.0, sides.z) : vec3(sides.x, 0.0, 0.0) :
|
||||||
|
f_ao_vec.z < 1.0 ? abs(delta_sides.y) < abs(delta_sides.z) ? vec3(0.0, sides.y, 0.0) : vec3(0.0, 0.0, sides.z) : vec3(0.0, sides.y, 0.0) :
|
||||||
|
f_ao_vec.z < 1.0 ? abs(delta_sides.x) < abs(delta_sides.z) ? vec3(sides.x, 0.0, 0.0) : vec3(0.0, 0.0, sides.z) : vec3(sides.x, 0.0, 0.0) :
|
||||||
|
f_ao_vec.y < 1.0 ?
|
||||||
|
f_ao_vec.z < 1.0 ? abs(delta_sides.y) < abs(delta_sides.z) ? vec3(0.0, sides.y, 0.0) : vec3(0.0, 0.0, sides.z) : vec3(0.0, sides.y, 0.0) :
|
||||||
|
f_ao_vec.z < 1.0 ? vec3(0.0, 0.0, sides.z) : vec3(0.0, 0.0, 0.0); */
|
||||||
|
// vec3 voxel_norm =
|
||||||
|
// f_ao_vec.x < 1.0 ?
|
||||||
|
// f_ao_vec.y < 1.0 ?
|
||||||
|
// abs(delta_sides.x) * f_ao_vec.x < abs(delta_sides.y) * f_ao_vec.y ?
|
||||||
|
// f_ao_vec.z < 1.0 ? abs(delta_sides.x) * f_ao_vec.x < abs(delta_sides.z) * f_ao_vec.z ? vec3(sides.x, 0.0, 0.0) : vec3(0.0, 0.0, sides.z) : vec3(sides.x, 0.0, 0.0) :
|
||||||
|
// f_ao_vec.z < 1.0 ? abs(delta_sides.y) * f_ao_vec.y < abs(delta_sides.z) * f_ao_vec.z ? vec3(0.0, sides.y, 0.0) : vec3(0.0, 0.0, sides.z) : vec3(0.0, sides.y, 0.0) :
|
||||||
|
// f_ao_vec.z < 1.0 ? abs(delta_sides.x) * f_ao_vec.x < abs(delta_sides.z) * f_ao_vec.z ? vec3(sides.x, 0.0, 0.0) : vec3(0.0, 0.0, sides.z) : vec3(sides.x, 0.0, 0.0) :
|
||||||
|
// f_ao_vec.y < 1.0 ?
|
||||||
|
// f_ao_vec.z < 1.0 ? abs(delta_sides.y) * f_ao_vec.y < abs(delta_sides.z) * f_ao_vec.z ? vec3(0.0, sides.y, 0.0) : vec3(0.0, 0.0, sides.z) : vec3(0.0, sides.y, 0.0) :
|
||||||
|
// f_ao_vec.z < 1.0 ? vec3(0.0, 0.0, sides.z) : vec3(0.0, 0.0, 0.0);
|
||||||
|
vec3 voxel_norm = vec3(0.0);
|
||||||
|
// voxel_norm = mix(voxel_norm, f_norm, dist_lerp);
|
||||||
|
|
||||||
|
f_pos.xyz -= abs(voxel_norm) * delta_sides;
|
||||||
|
voxel_norm = voxel_norm == vec3(0.0) ? f_norm : voxel_norm;
|
||||||
|
|
||||||
|
// f_ao = 1.0;
|
||||||
|
// f_ao = dot(f_ao_vec, sqrt(1.0 - delta_sides * delta_sides));
|
||||||
|
f_ao = sqrt(dot(f_ao_vec * abs(voxel_norm), sqrt(1.0 - delta_sides * delta_sides)) / 3.0);
|
||||||
|
// f_ao = dot(abs(voxel_norm), f_ao_vec);
|
||||||
// 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.
|
// Note: because voxels, we reduce the normal for reflections to just its z component, dpendng on distance to camera.
|
||||||
@ -188,6 +327,10 @@ void main() {
|
|||||||
mix(-1.0, 1.0, clamp(pow(f_norm.y * 0.5, 64), 0, 1)),
|
mix(-1.0, 1.0, clamp(pow(f_norm.y * 0.5, 64), 0, 1)),
|
||||||
mix(-1.0, 1.0, clamp(pow(f_norm.z * 0.5, 64), 0, 1))
|
mix(-1.0, 1.0, clamp(pow(f_norm.z * 0.5, 64), 0, 1))
|
||||||
)); */
|
)); */
|
||||||
|
vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz);
|
||||||
|
vec3 view_dir = -cam_to_frag;
|
||||||
|
// vec3 view_dir = normalize(f_pos - cam_pos.xyz);
|
||||||
|
|
||||||
|
|
||||||
vec3 sun_dir = get_sun_dir(time_of_day.x);
|
vec3 sun_dir = get_sun_dir(time_of_day.x);
|
||||||
vec3 moon_dir = get_moon_dir(time_of_day.x);
|
vec3 moon_dir = get_moon_dir(time_of_day.x);
|
||||||
@ -212,27 +355,70 @@ void main() {
|
|||||||
// float brightness_denominator = (ambient_sides + vec3(SUN_AMBIANCE * sun_light + moon_light);
|
// float brightness_denominator = (ambient_sides + vec3(SUN_AMBIANCE * sun_light + moon_light);
|
||||||
|
|
||||||
float alpha = 1.0;//0.1;//0.2;///1.0;//sqrt(2.0);
|
float alpha = 1.0;//0.1;//0.2;///1.0;//sqrt(2.0);
|
||||||
const float n2 = 1.01;
|
const float n2 = 1.5;
|
||||||
const float R_s2s0 = pow((1.0 - n2) / (1.0 + n2), 2);
|
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_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_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);
|
const float R_s1s2 = pow((1.3325 - 1.0) / (1.3325 + 1.0), 2);
|
||||||
|
float cam_alt = alt_at(cam_pos.xy);
|
||||||
|
float fluid_alt = medium.x == 1u ? max(cam_alt + 1, floor(shadow_alt)) : view_distance.w;
|
||||||
float R_s = (f_pos.z < my_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 < my_alt) ? mix(R_s2s1 * R_s1s0, R_s1s0, medium.x) : mix(R_s2s0, R_s1s2 * R_s2s0, medium.x);
|
||||||
|
|
||||||
vec3 emitted_light, reflected_light;
|
vec3 emitted_light, reflected_light;
|
||||||
|
|
||||||
|
vec3 mu = medium.x == 1u/* && 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(cam_pos.xyz, view_dir, mu, fluid_alt, /*cam_pos.z <= fluid_alt ? cam_pos.xyz : f_pos*/f_pos);
|
||||||
// Use f_norm here for better shadows.
|
// 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);
|
// 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);
|
||||||
|
|
||||||
// vec3 light, diffuse_light, ambient_light;
|
// 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);
|
// 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;
|
float max_light = 0.0;
|
||||||
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);
|
max_light += get_sun_diffuse2(/*f_norm*/voxel_norm/*l_norm*/, sun_dir, moon_dir, view_dir, f_pos, vec3(0.0), cam_attenuation, fluid_alt, 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 = vec3(1.0);
|
||||||
emitted_light *= max(shade_frac, MIN_SHADOW);
|
emitted_light *= max(shade_frac, MIN_SHADOW);
|
||||||
reflected_light *= shade_frac;
|
reflected_light *= shade_frac;
|
||||||
max_light *= shade_frac;
|
max_light *= shade_frac;
|
||||||
// reflected_light = vec3(0.0);
|
// reflected_light = vec3(0.0);
|
||||||
|
|
||||||
|
// dot(diffuse_factor, /*R_r * */vec4(abs(norm) * (1.0 - dist), dist))
|
||||||
|
|
||||||
|
// corner_xy = mix(all(lessThan(corner_xy, 1.0)) ? vec2(0.0) : 0.4 * (), 1.0
|
||||||
|
//
|
||||||
|
// TODO: Handle similar logic for z.
|
||||||
|
|
||||||
|
// So we repeat this for all three sides to find the "next" position on each side.
|
||||||
|
// vec3 delta_sides = 1.0 + sides * fract(-sides * f_pos);
|
||||||
|
// Now, we
|
||||||
|
// Now, all we have to do is find out whether (again, assuming f_pos is positive) next_sides represents a new integer.
|
||||||
|
// We currently just treat this as "new floor != old floor".
|
||||||
|
|
||||||
|
// So to find the position at the nearest voxel, we just subtract voxel_norm * fract(sides * ) from f_pos.z.
|
||||||
|
// Then to find out whether we meet a new "block" in 1 voxel, we just
|
||||||
|
// on the "other" side can be found (according to my temporary theory) as the cross product
|
||||||
|
// vec3 norm = normalize(cross(
|
||||||
|
// vec3(/*2.0 * SAMPLE_W*/square.z - square.x, 0.0, altx1 - altx0),
|
||||||
|
// vec3(0.0, /*2.0 * SAMPLE_W*/square.w - square.y, alty1 - alty0)
|
||||||
|
// ));
|
||||||
|
// vec3 norm = normalize(vec3(
|
||||||
|
// (altx0 - altx1) / (square.z - square.x),
|
||||||
|
// (alty0 - alty1) / (square.w - square.y),
|
||||||
|
// 1.0
|
||||||
|
// //(abs(square.w - square.y) + abs(square.z - square.x)) / (slope + 0.00001) // Avoid NaN
|
||||||
|
// ));
|
||||||
|
//
|
||||||
|
// If a side coordinate is 0, then it counts as no AO;
|
||||||
|
// otherwise, it counts as fractional AO. So what we need is to know whether the fractional AO to the next block in that direction pushes us to a new integer.
|
||||||
|
//
|
||||||
|
// vec3 ao_pos_z = floor(f_pos + f_norm);
|
||||||
|
// vec3 ao_pos_z = corner_distance;
|
||||||
|
// vec3 ao_pos = 0.5 - clamp(min(fract(abs(f_pos)), 1.0 - fract(abs(f_pos))), 0.0, 0.5);
|
||||||
|
//
|
||||||
|
// f_ao = /*sqrt*/1.0 - 2.0 * sqrt(dot(ao_pos, ao_pos) / 2.0);
|
||||||
|
// f_ao = /*sqrt*/1.0 - (dot(ao_pos, ao_pos)/* / 2.0*/);
|
||||||
|
// f_ao = /*sqrt*/1.0 - 2.0 * (dot(ao_pos, ao_pos)/* / 2.0*/);
|
||||||
|
// f_ao = /*sqrt*/1.0 - 2.0 * sqrt(dot(ao_pos, ao_pos) / 2.0);
|
||||||
float ao = /*pow(f_ao, 0.5)*/f_ao * 0.9 + 0.1;
|
float ao = /*pow(f_ao, 0.5)*/f_ao * 0.9 + 0.1;
|
||||||
emitted_light *= ao;
|
emitted_light *= ao;
|
||||||
reflected_light *= ao;
|
reflected_light *= ao;
|
||||||
@ -246,7 +432,7 @@ void main() {
|
|||||||
// get_sun_diffuse(f_norm, time_of_day.x, light, diffuse_light, ambient_light, 1.0);
|
// get_sun_diffuse(f_norm, time_of_day.x, light, diffuse_light, ambient_light, 1.0);
|
||||||
// vec3 surf_color = illuminate(f_col, light, diffuse_light, ambient_light);
|
// 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
|
// 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 = /*illuminate(emitted_light, reflected_light)*/illuminate(max_light, f_col * emitted_light, f_col * reflected_light);
|
vec3 surf_color = /*illuminate(emitted_light, reflected_light)*/illuminate(max_light, view_dir, f_col * emitted_light, f_col * reflected_light);
|
||||||
|
|
||||||
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
|
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
|
||||||
|
|
||||||
|
@ -1,5 +1,21 @@
|
|||||||
#version 330 core
|
#version 330 core
|
||||||
|
|
||||||
|
#include <constants.glsl>
|
||||||
|
|
||||||
|
#define LIGHTING_TYPE LIGHTING_TYPE_REFLECTION
|
||||||
|
|
||||||
|
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_GLOSSY
|
||||||
|
|
||||||
|
#if (FLUID_MODE == FLUID_MODE_CHEAP)
|
||||||
|
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
|
||||||
|
#elif (FLUID_MODE == FLUID_MODE_SHINY)
|
||||||
|
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION_SCHEME LIGHTING_DISTRIBUTION_SCHEME_VOXEL
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION LIGHTING_DISTRIBUTION_BECKMANN
|
||||||
|
|
||||||
#include <globals.glsl>
|
#include <globals.glsl>
|
||||||
#include <srgb.glsl>
|
#include <srgb.glsl>
|
||||||
#include <lod.glsl>
|
#include <lod.glsl>
|
||||||
|
@ -1,5 +1,17 @@
|
|||||||
#version 330 core
|
#version 330 core
|
||||||
|
|
||||||
|
#include <constants.glsl>
|
||||||
|
|
||||||
|
#define LIGHTING_TYPE LIGHTING_TYPE_REFLECTION
|
||||||
|
|
||||||
|
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_GLOSSY
|
||||||
|
|
||||||
|
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION_SCHEME LIGHTING_DISTRIBUTION_SCHEME_MICROFACET
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION LIGHTING_DISTRIBUTION_BECKMANN
|
||||||
|
|
||||||
#include <globals.glsl>
|
#include <globals.glsl>
|
||||||
|
|
||||||
in vec3 f_pos;
|
in vec3 f_pos;
|
||||||
|
@ -1,8 +1,25 @@
|
|||||||
#version 330 core
|
#version 330 core
|
||||||
|
|
||||||
|
#include <constants.glsl>
|
||||||
|
|
||||||
|
#define LIGHTING_TYPE (LIGHTING_TYPE_TRANSMISSION | LIGHTING_TYPE_REFLECTION)
|
||||||
|
|
||||||
|
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_SPECULAR
|
||||||
|
|
||||||
|
#if (FLUID_MODE == FLUID_MODE_CHEAP)
|
||||||
|
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
|
||||||
|
#elif (FLUID_MODE == FLUID_MODE_SHINY)
|
||||||
|
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION_SCHEME LIGHTING_DISTRIBUTION_SCHEME_MICROFACET
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION LIGHTING_DISTRIBUTION_BECKMANN
|
||||||
|
|
||||||
#include <globals.glsl>
|
#include <globals.glsl>
|
||||||
// Note: The sampler uniform is declared here because it differs for MSAA
|
// Note: The sampler uniform is declared here because it differs for MSAA
|
||||||
#include <anti-aliasing.glsl>
|
#include <anti-aliasing.glsl>
|
||||||
|
#include <srgb.glsl>
|
||||||
|
|
||||||
in vec2 f_pos;
|
in vec2 f_pos;
|
||||||
|
|
||||||
@ -29,6 +46,101 @@ vec3 hsv2rgb(vec3 c) {
|
|||||||
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec3 illuminate(float max_light, vec3 view_dir, /*vec3 max_light, */vec3 emitted, vec3 reflected) {
|
||||||
|
const float NIGHT_EXPOSURE = 10.0;
|
||||||
|
const float DUSK_EXPOSURE = 2.0;//0.8;
|
||||||
|
const float DAY_EXPOSURE = 1.0;//0.7;
|
||||||
|
|
||||||
|
const float DAY_SATURATION = 1.0;
|
||||||
|
const float DUSK_SATURATION = 0.6;
|
||||||
|
const float NIGHT_SATURATION = 0.1;
|
||||||
|
|
||||||
|
const float gamma = /*0.5*//*1.*0*/1.0;//1.0;
|
||||||
|
/* float light = length(emitted + reflected);
|
||||||
|
float color = srgb_to_linear(emitted + reflected);
|
||||||
|
float avg_col = (color.r + color.g + color.b) / 3.0;
|
||||||
|
return ((color - avg_col) * light + reflected * avg_col) * (emitted + reflected); */
|
||||||
|
// float max_intensity = vec3(1.0);
|
||||||
|
vec3 color = emitted + reflected;
|
||||||
|
float lum = rel_luminance(color);
|
||||||
|
// float lum_sky = lum - max_light;
|
||||||
|
|
||||||
|
// vec3 sun_dir = get_sun_dir(time_of_day.x);
|
||||||
|
// vec3 moon_dir = get_moon_dir(time_of_day.x);
|
||||||
|
// float sky_light = rel_luminance(
|
||||||
|
// get_sun_color(sun_dir) * get_sun_brightness(sun_dir) * SUN_COLOR_FACTOR +
|
||||||
|
// get_moon_color(moon_dir) * get_moon_brightness(moon_dir));
|
||||||
|
float sky_light = lum;
|
||||||
|
|
||||||
|
// Tone mapped value.
|
||||||
|
// vec3 T = /*color*//*lum*/color;//normalize(color) * lum / (1.0 + lum);
|
||||||
|
// float alpha = 0.5;//2.0;
|
||||||
|
// float alpha = mix(
|
||||||
|
// mix(
|
||||||
|
// DUSK_EXPOSURE,
|
||||||
|
// NIGHT_EXPOSURE,
|
||||||
|
// max(sun_dir.z, 0)
|
||||||
|
// ),
|
||||||
|
// DAY_EXPOSURE,
|
||||||
|
// max(-sun_dir.z, 0)
|
||||||
|
// );
|
||||||
|
float alpha = 1.0;//log(1.0 - lum) / lum;
|
||||||
|
// vec3 now_light = moon_dir.z < 0 ? moon_dir : sun_dir;
|
||||||
|
// float cos_view_light = dot(-now_light, view_dir);
|
||||||
|
// alpha *= exp(1.0 - cos_view_light);
|
||||||
|
// sky_light *= 1.0 - log(1.0 + view_dir.z);
|
||||||
|
float alph = sky_light > 0.0 && max_light > 0.0 ? mix(1.0 / log(/*1.0*//*1.0 + *//*lum_sky + */1.0 + max_light / (0.0 + sky_light)), 1.0, clamp(max_light - sky_light, 0.0, 1.0)) : 1.0;
|
||||||
|
alpha = alpha * alph;// min(alph, 1.0);//((max_light > 0.0 && max_light > sky_light /* && sky_light > 0.0*/) ? /*1.0*/1.0 / log(/*1.0*//*1.0 + *//*lum_sky + */1.0 + max_light - (0.0 + sky_light)) : 1.0);
|
||||||
|
// alpha = alpha * min(1.0, (max_light == 0.0 ? 1.0 : (1.0 + abs(lum_sky)) / /*(1.0 + max_light)*/max_light));
|
||||||
|
|
||||||
|
vec3 col_adjusted = lum == 0.0 ? vec3(0.0) : color / lum;
|
||||||
|
|
||||||
|
// float L = lum == 0.0 ? 0.0 : log(lum);
|
||||||
|
|
||||||
|
|
||||||
|
// // float B = T;
|
||||||
|
// // float B = L + log(alpha);
|
||||||
|
// float B = lum;
|
||||||
|
|
||||||
|
// float D = L - B;
|
||||||
|
|
||||||
|
// float o = 0.0;//log(PERSISTENT_AMBIANCE);
|
||||||
|
// float scale = /*-alpha*/-alpha;//1.0;
|
||||||
|
|
||||||
|
// float B_ = (B - o) * scale;
|
||||||
|
|
||||||
|
// // float T = lum;
|
||||||
|
// float O = exp(B_ + D);
|
||||||
|
|
||||||
|
float T = 1.0 - exp(-alpha * lum);//lum / (1.0 + lum);
|
||||||
|
// float T = lum;
|
||||||
|
|
||||||
|
// Heuristic desaturation
|
||||||
|
// const float s = 0.8;
|
||||||
|
float s = 1.0;
|
||||||
|
// float s = mix(
|
||||||
|
// mix(
|
||||||
|
// DUSK_SATURATION,
|
||||||
|
// NIGHT_SATURATION,
|
||||||
|
// max(sun_dir.z, 0)
|
||||||
|
// ),
|
||||||
|
// DAY_SATURATION,
|
||||||
|
// max(-sun_dir.z, 0)
|
||||||
|
// );
|
||||||
|
// s = max(s, (max_light) / (1.0 + s));
|
||||||
|
// s = max(s, max_light / (1.0 + max_light));
|
||||||
|
// s = max_light / (1.0 + max_light);
|
||||||
|
|
||||||
|
vec3 c = pow(col_adjusted, vec3(s)) * T;
|
||||||
|
// vec3 c = col_adjusted * T;
|
||||||
|
// vec3 c = sqrt(col_adjusted) * T;
|
||||||
|
// vec3 c = /*col_adjusted * */col_adjusted * T;
|
||||||
|
|
||||||
|
return c;
|
||||||
|
// float sum_col = color.r + color.g + color.b;
|
||||||
|
// return /*srgb_to_linear*/(/*0.5*//*0.125 * */vec3(pow(color.x, gamma), pow(color.y, gamma), pow(color.z, gamma)));
|
||||||
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec2 uv = (f_pos + 1.0) * 0.5;
|
vec2 uv = (f_pos + 1.0) * 0.5;
|
||||||
|
|
||||||
@ -36,8 +148,36 @@ void main() {
|
|||||||
uv = clamp(uv + vec2(sin(uv.y * 16.0 + tick.x), sin(uv.x * 24.0 + tick.x)) * 0.005, 0, 1);
|
uv = clamp(uv + vec2(sin(uv.y * 16.0 + tick.x), sin(uv.x * 24.0 + tick.x)) * 0.005, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vec2 c_uv = vec2(0.5);//uv;//vec2(0.5);//uv;
|
||||||
|
vec2 delta = /*sqrt*//*sqrt(2.0) / 2.0*//*sqrt(2.0) / 2.0*//*0.5 - */min(uv, 1.0 - uv);//min(uv * (1.0 - uv), 0.25) * 2.0;
|
||||||
|
// delta = /*sqrt(2.0) / 2.0 - */sqrt(vec2(dot(delta, delta)));
|
||||||
|
// delta = 0.5 - vec2(min(delta.x, delta.y));
|
||||||
|
delta = vec2(0.25);//vec2(dot(/*0.5 - */delta, /*0.5 - */delta));//vec2(min(delta.x, delta.y));//sqrt(2.0) * (0.5 - vec2(min(delta.x, delta.y)));
|
||||||
|
// delta = vec2(sqrt(dot(delta, delta)));
|
||||||
|
// vec2 delta = /*sqrt*//*sqrt(2.0) / 2.0*//*sqrt(2.0) / 2.0*/1.0 - vec2(sqrt(dot(uv, 1.0 - uv)));//min(uv * (1.0 - uv), 0.25) * 2.0;
|
||||||
|
// float delta = /*sqrt*//*sqrt(2.0) / 2.0*//*sqrt(2.0) / 2.0*/1.0 - (dot(uv - 0.5, uv - 0.5));//0.01;//25;
|
||||||
|
// vec2 delta = /*sqrt*//*sqrt(2.0) / 2.0*//*sqrt(2.0) / 2.0*/sqrt(uv * (1.0 - uv));//min(uv * (1.0 - uv), 0.25) * 2.0;
|
||||||
|
|
||||||
|
// float bright_color0 = rel_luminance(texelFetch/*texture*/(src_color, ivec2(clamp(c_uv + vec2(0.0, 0.0), 0.0, 1.0) * screen_res.xy/* / 50*/)/* * 50*/, 0).rgb);
|
||||||
|
// float bright_color1 = rel_luminance(texelFetch/*texture*/(src_color, ivec2(clamp(c_uv + vec2(delta.x, delta.y), 0.0, 1.0) * screen_res.xy/* / 50*/)/* * 50*/, 0).rgb);
|
||||||
|
// float bright_color2 = rel_luminance(texelFetch/*texture*/(src_color, ivec2(clamp(c_uv + vec2(delta.x, -delta.y), 0.0, 1.0) * screen_res.xy/* / 50*/)/* * 50*/, 0).rgb);
|
||||||
|
// float bright_color3 = rel_luminance(texelFetch/*texture*/(src_color, ivec2(clamp(c_uv + vec2(-delta.x, delta.y), 0.0, 1.0) * screen_res.xy/* / 50*/)/* * 50*/, 0).rgb);
|
||||||
|
// float bright_color4 = rel_luminance(texelFetch/*texture*/(src_color, ivec2(clamp(c_uv + vec2(-delta.x, -delta.y), 0.0, 1.0) * screen_res.xy/* / 50*/)/* * 50*/, 0).rgb);
|
||||||
|
|
||||||
|
// float bright_color0 = rel_luminance(texture(src_color, /*ivec2*/(clamp(c_uv + vec2(0.0, 0.0), 0.0, 1.0)/* * screen_res.xy*//* / 50*/)/* * 50*/, 0).rgb);
|
||||||
|
// float bright_color1 = rel_luminance(texture(src_color, /*ivec2*/(clamp(c_uv + vec2(delta, delta), 0.0, 1.0)/* * screen_res.xy*//* / 50*/)/* * 50*/, 0).rgb);
|
||||||
|
// float bright_color2 = rel_luminance(texture(src_color, /*ivec2*/(clamp(c_uv + vec2(delta, -delta), 0.0, 1.0)/* * screen_res.xy*//* / 50*/)/* * 50*/, 0).rgb);
|
||||||
|
// float bright_color3 = rel_luminance(texture(src_color, /*ivec2*/(clamp(c_uv + vec2(-delta, delta), 0.0, 1.0)/* * screen_res.xy*//* / 50*/)/* * 50*/, 0).rgb);
|
||||||
|
// float bright_color4 = rel_luminance(texture(src_color, /*ivec2*/(clamp(c_uv + vec2(-delta, -delta), 0.0, 1.0)/* * screen_res.xy*//* / 50*/)/* * 50*/, 0).rgb);
|
||||||
|
|
||||||
|
// float bright_color = max(bright_color0, max(bright_color1, max(bright_color2, max(bright_color3, bright_color4))));// / 2.0;// / 5.0;
|
||||||
|
|
||||||
|
// float bright_color = (bright_color0 + bright_color1 + bright_color2 + bright_color3 + bright_color4) / 5.0;
|
||||||
|
|
||||||
vec4 aa_color = aa_apply(src_color, uv * screen_res.xy, screen_res.xy);
|
vec4 aa_color = aa_apply(src_color, uv * screen_res.xy, screen_res.xy);
|
||||||
|
|
||||||
|
// aa_color.rgb = illuminate(1.0 - 1.0 / (1.0 + bright_color), normalize(cam_pos.xyz - focus_pos.xyz), /*vec3 max_light, */vec3(0.0), aa_color.rgb);
|
||||||
|
|
||||||
//vec4 hsva_color = vec4(rgb2hsv(fxaa_color.rgb), fxaa_color.a);
|
//vec4 hsva_color = vec4(rgb2hsv(fxaa_color.rgb), fxaa_color.a);
|
||||||
//hsva_color.y *= 1.45;
|
//hsva_color.y *= 1.45;
|
||||||
//hsva_color.z *= 0.85;
|
//hsva_color.z *= 0.85;
|
||||||
|
@ -1,5 +1,21 @@
|
|||||||
#version 330 core
|
#version 330 core
|
||||||
|
|
||||||
|
#include <constants.glsl>
|
||||||
|
|
||||||
|
#define LIGHTING_TYPE (LIGHTING_TYPE_TRANSMISSION | LIGHTING_TYPE_REFLECTION)
|
||||||
|
|
||||||
|
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_SPECULAR
|
||||||
|
|
||||||
|
#if (FLUID_MODE == FLUID_MODE_CHEAP)
|
||||||
|
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
|
||||||
|
#elif (FLUID_MODE == FLUID_MODE_SHINY)
|
||||||
|
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION_SCHEME LIGHTING_DISTRIBUTION_SCHEME_MICROFACET
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION LIGHTING_DISTRIBUTION_BECKMANN
|
||||||
|
|
||||||
#include <globals.glsl>
|
#include <globals.glsl>
|
||||||
|
|
||||||
in vec2 v_pos;
|
in vec2 v_pos;
|
||||||
|
@ -1,7 +1,24 @@
|
|||||||
#version 330 core
|
#version 330 core
|
||||||
|
|
||||||
|
#include <constants.glsl>
|
||||||
|
|
||||||
|
#define LIGHTING_TYPE LIGHTING_TYPE_TRANSMISSION
|
||||||
|
|
||||||
|
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_SPECULAR
|
||||||
|
|
||||||
|
#if (FLUID_MODE == FLUID_MODE_CHEAP)
|
||||||
|
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
|
||||||
|
#elif (FLUID_MODE == FLUID_MODE_SHINY)
|
||||||
|
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION_SCHEME LIGHTING_DISTRIBUTION_SCHEME_MICROFACET
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION LIGHTING_DISTRIBUTION_BECKMANN
|
||||||
|
|
||||||
#include <globals.glsl>
|
#include <globals.glsl>
|
||||||
#include <sky.glsl>
|
#include <sky.glsl>
|
||||||
|
#include <lod.glsl>
|
||||||
|
|
||||||
in vec3 f_pos;
|
in vec3 f_pos;
|
||||||
|
|
||||||
@ -16,6 +33,18 @@ void main() {
|
|||||||
vec4 _clouds;
|
vec4 _clouds;
|
||||||
|
|
||||||
vec3 cam_dir = normalize(f_pos - cam_pos.xyz);
|
vec3 cam_dir = normalize(f_pos - cam_pos.xyz);
|
||||||
|
|
||||||
|
float cam_alt = alt_at(cam_pos.xy);
|
||||||
|
// float f_alt = alt_at(f_pos.xy);
|
||||||
|
float fluid_alt = medium.x == 1u ? floor(cam_alt + 1) : view_distance.w;
|
||||||
|
// float fluid_alt = max(f_pos.z + 1, floor(f_alt));
|
||||||
|
vec3 mu = medium.x == 1u /* && f_pos.z <= fluid_alt*/ ? MU_WATER : vec3(0.0);
|
||||||
|
// vec3 sun_attenuation = compute_attenuation(wpos, -sun_dir, mu, surface_alt, wpos);
|
||||||
|
vec3 cam_attenuation = compute_attenuation(cam_pos.xyz, -cam_dir, mu, fluid_alt, /*cam_pos.z <= fluid_alt ? cam_pos.xyz : f_pos*//*f_pos*//*vec3(f_pos.xy, fluid_alt)*/cam_pos.xyz);
|
||||||
|
// vec3 cam_attenuation = compute_attenuation_point(f_pos, -view_dir, mu, fluid_alt, cam_pos.xyz);
|
||||||
|
// vec3 cam_attenuation = vec3(1.0);
|
||||||
|
|
||||||
|
|
||||||
/* vec3 world_pos = cam_pos.xyz + cam_dir * 500000.0;
|
/* vec3 world_pos = cam_pos.xyz + cam_dir * 500000.0;
|
||||||
tgt_color = vec4(get_sky_color(normalize(f_pos), time_of_day.x, cam_pos.xyz, world_pos, 1.0, true, _clouds), 1.0); */
|
tgt_color = vec4(get_sky_color(normalize(f_pos), time_of_day.x, cam_pos.xyz, world_pos, 1.0, true, _clouds), 1.0); */
|
||||||
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
|
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
|
||||||
@ -28,5 +57,5 @@ void main() {
|
|||||||
} */
|
} */
|
||||||
vec3 wpos = cam_pos.xyz + /*normalize(f_pos)*/cam_dir * 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, refractionIndex, _clouds), 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, _clouds), 1.0);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,21 @@
|
|||||||
#version 330 core
|
#version 330 core
|
||||||
|
|
||||||
|
#include <constants.glsl>
|
||||||
|
|
||||||
|
#define LIGHTING_TYPE LIGHTING_TYPE_TRANSMISSION
|
||||||
|
|
||||||
|
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_SPECULAR
|
||||||
|
|
||||||
|
#if (FLUID_MODE == FLUID_MODE_CHEAP)
|
||||||
|
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
|
||||||
|
#elif (FLUID_MODE == FLUID_MODE_SHINY)
|
||||||
|
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION_SCHEME LIGHTING_DISTRIBUTION_SCHEME_MICROFACET
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION LIGHTING_DISTRIBUTION_BECKMANN
|
||||||
|
|
||||||
#include <globals.glsl>
|
#include <globals.glsl>
|
||||||
|
|
||||||
in vec3 v_pos;
|
in vec3 v_pos;
|
||||||
|
@ -1,4 +1,18 @@
|
|||||||
#version 330 core
|
#version 400 core
|
||||||
|
|
||||||
|
#include <constants.glsl>
|
||||||
|
|
||||||
|
#define LIGHTING_TYPE LIGHTING_TYPE_REFLECTION
|
||||||
|
|
||||||
|
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_GLOSSY
|
||||||
|
|
||||||
|
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION_SCHEME LIGHTING_DISTRIBUTION_SCHEME_MICROFACET
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION LIGHTING_DISTRIBUTION_BECKMANN
|
||||||
|
|
||||||
|
// #define HAS_SHADOW_MAPS
|
||||||
|
|
||||||
#include <globals.glsl>
|
#include <globals.glsl>
|
||||||
|
|
||||||
@ -42,7 +56,7 @@ void main() {
|
|||||||
|
|
||||||
vec3 surf_color = /*srgb_to_linear*//*linear_to_srgb*/(f_col);
|
vec3 surf_color = /*srgb_to_linear*//*linear_to_srgb*/(f_col);
|
||||||
float alpha = 1.0;
|
float alpha = 1.0;
|
||||||
const float n2 = 1.01;
|
const float n2 = 1.5;
|
||||||
const float R_s2s0 = pow((1.0 - n2) / (1.0 + n2), 2);
|
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_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_s2s1 = pow((1.0 - 1.3325) / (1.0 + 1.3325), 2);
|
||||||
@ -92,7 +106,7 @@ void main() {
|
|||||||
emitted_light *= ao;
|
emitted_light *= ao;
|
||||||
reflected_light *= ao;
|
reflected_light *= ao;
|
||||||
|
|
||||||
surf_color = illuminate(max_light, surf_color * emitted_light, surf_color * reflected_light);
|
surf_color = illuminate(max_light, view_dir, surf_color * emitted_light, surf_color * reflected_light);
|
||||||
// vec3 surf_color = illuminate(f_col, light, diffuse_light, ambient_light);
|
// vec3 surf_color = illuminate(f_col, light, diffuse_light, ambient_light);
|
||||||
|
|
||||||
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
|
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
|
||||||
|
@ -1,5 +1,17 @@
|
|||||||
#version 330 core
|
#version 330 core
|
||||||
|
|
||||||
|
#include <constants.glsl>
|
||||||
|
|
||||||
|
#define LIGHTING_TYPE LIGHTING_TYPE_REFLECTION
|
||||||
|
|
||||||
|
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_GLOSSY
|
||||||
|
|
||||||
|
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION_SCHEME LIGHTING_DISTRIBUTION_SCHEME_MICROFACET
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION LIGHTING_DISTRIBUTION_BECKMANN
|
||||||
|
|
||||||
#include <globals.glsl>
|
#include <globals.glsl>
|
||||||
#include <srgb.glsl>
|
#include <srgb.glsl>
|
||||||
|
|
||||||
|
@ -1,4 +1,22 @@
|
|||||||
#version 330 core
|
#version 400 core
|
||||||
|
|
||||||
|
#include <constants.glsl>
|
||||||
|
|
||||||
|
#define LIGHTING_TYPE LIGHTING_TYPE_REFLECTION
|
||||||
|
|
||||||
|
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_GLOSSY
|
||||||
|
|
||||||
|
#if (FLUID_MODE == FLUID_MODE_CHEAP)
|
||||||
|
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
|
||||||
|
#elif (FLUID_MODE == FLUID_MODE_SHINY)
|
||||||
|
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION_SCHEME LIGHTING_DISTRIBUTION_SCHEME_MICROFACET
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION LIGHTING_DISTRIBUTION_BECKMANN
|
||||||
|
|
||||||
|
#define HAS_SHADOW_MAPS
|
||||||
|
|
||||||
#include <globals.glsl>
|
#include <globals.glsl>
|
||||||
#include <random.glsl>
|
#include <random.glsl>
|
||||||
@ -19,13 +37,45 @@ out vec4 tgt_color;
|
|||||||
#include <lod.glsl>
|
#include <lod.glsl>
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
// tgt_color = vec4(0.0, 0.0, 0.0, 1.0);
|
||||||
|
// for (uint i = 0u; i < light_shadow_count.x; i ++) {
|
||||||
|
// // uint i = 1u;
|
||||||
|
// Light L = lights[i];
|
||||||
|
|
||||||
|
// vec4 light_col = vec4(
|
||||||
|
// hash(vec4(1.0, 0.0, 0.0, i)),
|
||||||
|
// hash(vec4(1.0, 1.0, 0.0, i)),
|
||||||
|
// hash(vec4(1.0, 0.0, 1.0, i)),
|
||||||
|
// 1.0
|
||||||
|
// );
|
||||||
|
|
||||||
|
// vec3 light_pos = L.light_pos.xyz;
|
||||||
|
|
||||||
|
// // Pre-calculate difference between light and fragment
|
||||||
|
// vec3 fragToLight = f_pos - light_pos;
|
||||||
|
|
||||||
|
// // use the light to fragment vector to sample from the depth map
|
||||||
|
// float bias = 0.05;//0.05;
|
||||||
|
// // float closestDepth = texture(t_shadow_maps, vec4(fragToLight, i)/*, 0.0*//*, bias*/).r;
|
||||||
|
// // float closestDepth = texture(t_shadow_maps, vec4(fragToLight, lightIndex), bias);
|
||||||
|
// float visibility = texture(t_shadow_maps, vec4(fragToLight, i), (length(fragToLight) - bias)/* / screen_res.w*/);
|
||||||
|
// // it is currently in linear range between [0,1]. Re-transform back to original value
|
||||||
|
// // closestDepth *= screen_res.w; // far plane
|
||||||
|
// // now test for shadows
|
||||||
|
// // float shadow = /*currentDepth*/(screen_res.w - bias) > closestDepth ? 1.0 : 0.0;
|
||||||
|
// // float shadow = currentDepth - bias > closestDepth ? 1.0 : 0.0;
|
||||||
|
|
||||||
|
// tgt_color += light_col * vec4(vec3(/*closestDepth*/visibility/* + bias*//* / screen_res.w */) * 1.0 / light_shadow_count.x, 0.0);
|
||||||
|
// }
|
||||||
|
// return;
|
||||||
|
|
||||||
// First 3 normals are negative, next 3 are positive
|
// First 3 normals are negative, next 3 are positive
|
||||||
vec3 normals[6] = vec3[](vec3(-1,0,0), vec3(1,0,0), vec3(0,-1,0), vec3(0,1,0), vec3(0,0,-1), vec3(0,0,1));
|
vec3 normals[6] = vec3[](vec3(-1,0,0), vec3(1,0,0), vec3(0,-1,0), vec3(0,1,0), vec3(0,0,-1), vec3(0,0,1));
|
||||||
|
|
||||||
// TODO: last 3 bits in v_pos_norm should be a number between 0 and 5, rather than 0-2 and a direction.
|
// TODO: last 3 bits in v_pos_norm should be a number between 0 and 5, rather than 0-2 and a direction.
|
||||||
uint norm_axis = (f_pos_norm >> 30) & 0x3u;
|
// uint norm_axis = (f_pos_norm >> 30) & 0x3u;
|
||||||
// Increase array access by 3 to access positive values
|
// // Increase array access by 3 to access positive values
|
||||||
uint norm_dir = ((f_pos_norm >> 29) & 0x1u) * 3u;
|
// uint norm_dir = ((f_pos_norm >> 29) & 0x1u) * 3u;
|
||||||
// Use an array to avoid conditional branching
|
// Use an array to avoid conditional branching
|
||||||
vec3 f_norm = normals[(f_pos_norm >> 29) & 0x7u];
|
vec3 f_norm = normals[(f_pos_norm >> 29) & 0x7u];
|
||||||
// Whether this face is facing fluid or not.
|
// Whether this face is facing fluid or not.
|
||||||
@ -43,9 +93,9 @@ void main() {
|
|||||||
float f_alt = alt_at(f_pos.xy);
|
float f_alt = alt_at(f_pos.xy);
|
||||||
vec4 f_shadow = textureBicubic(t_horizon, pos_to_tex(f_pos.xy));
|
vec4 f_shadow = textureBicubic(t_horizon, pos_to_tex(f_pos.xy));
|
||||||
|
|
||||||
float alpha = 1.0;
|
float alpha = 1.0;//0.0001;//1.0;
|
||||||
// TODO: Possibly angle with water surface into account? Since we can basically assume it's horizontal.
|
// TODO: Possibly angle with water surface into account? Since we can basically assume it's horizontal.
|
||||||
const float n2 = 1.01;
|
const float n2 = 1.5;//1.01;
|
||||||
const float R_s2s0 = pow((1.0 - n2) / (1.0 + n2), 2);
|
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_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_s2s1 = pow((1.0 - 1.3325) / (1.0 + 1.3325), 2);
|
||||||
@ -84,7 +134,9 @@ void main() {
|
|||||||
// Compute attenuation due to water from the camera.
|
// Compute attenuation due to water from the camera.
|
||||||
vec3 mu = faces_fluid/* && f_pos.z <= fluid_alt*/ ? MU_WATER : vec3(0.0);
|
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.
|
// 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 =
|
||||||
|
medium.x == 1u ? 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);
|
||||||
|
|
||||||
// Computing light attenuation from water.
|
// Computing light attenuation from water.
|
||||||
vec3 emitted_light, reflected_light;
|
vec3 emitted_light, reflected_light;
|
||||||
@ -97,7 +149,7 @@ void main() {
|
|||||||
reflected_light *= f_light * point_shadow * shade_frac;
|
reflected_light *= f_light * point_shadow * shade_frac;
|
||||||
max_light *= f_light * point_shadow * shade_frac;
|
max_light *= f_light * point_shadow * shade_frac;
|
||||||
|
|
||||||
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);
|
max_light += lights_at(f_pos, f_norm, view_dir, mu, cam_attenuation, fluid_alt, k_a, k_d, k_s, alpha, 1.0, emitted_light, reflected_light);
|
||||||
|
|
||||||
// float f_ao = 1.0;
|
// float f_ao = 1.0;
|
||||||
|
|
||||||
@ -127,7 +179,7 @@ void main() {
|
|||||||
|
|
||||||
// vec3 surf_color = illuminate(srgb_to_linear(f_col), light, diffuse_light, ambient_light);
|
// 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
|
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
|
||||||
vec3 surf_color = illuminate(max_light, col * emitted_light, col * reflected_light);
|
vec3 surf_color = illuminate(max_light, view_dir, col * emitted_light, col * reflected_light);
|
||||||
|
|
||||||
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
|
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
|
||||||
vec4 clouds;
|
vec4 clouds;
|
||||||
|
@ -1,5 +1,21 @@
|
|||||||
#version 330 core
|
#version 330 core
|
||||||
|
|
||||||
|
#include <constants.glsl>
|
||||||
|
|
||||||
|
#define LIGHTING_TYPE LIGHTING_TYPE_REFLECTION
|
||||||
|
|
||||||
|
#define LIGHTING_REFLECTION_KIND LIGHTING_REFLECTION_KIND_GLOSSY
|
||||||
|
|
||||||
|
#if (FLUID_MODE == FLUID_MODE_CHEAP)
|
||||||
|
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_IMPORTANCE
|
||||||
|
#elif (FLUID_MODE == FLUID_MODE_SHINY)
|
||||||
|
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION_SCHEME LIGHTING_DISTRIBUTION_SCHEME_MICROFACET
|
||||||
|
|
||||||
|
#define LIGHTING_DISTRIBUTION LIGHTING_DISTRIBUTION_BECKMANN
|
||||||
|
|
||||||
#include <globals.glsl>
|
#include <globals.glsl>
|
||||||
#include <srgb.glsl>
|
#include <srgb.glsl>
|
||||||
#include <lod.glsl>
|
#include <lod.glsl>
|
||||||
|
@ -22,6 +22,7 @@ fn main() {
|
|||||||
render::AaMode::SsaaX4,
|
render::AaMode::SsaaX4,
|
||||||
render::CloudMode::Regular,
|
render::CloudMode::Regular,
|
||||||
render::FluidMode::Shiny,
|
render::FluidMode::Shiny,
|
||||||
|
render::LightingMode::Ashikmin,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ use spell::Spell;
|
|||||||
use crate::{
|
use crate::{
|
||||||
ecs::comp as vcomp,
|
ecs::comp as vcomp,
|
||||||
i18n::{i18n_asset_key, LanguageMetadata, VoxygenLocalization},
|
i18n::{i18n_asset_key, LanguageMetadata, VoxygenLocalization},
|
||||||
render::{AaMode, CloudMode, Consts, FluidMode, Globals, Renderer},
|
render::{AaMode, CloudMode, Consts, FluidMode, Globals, LightingMode, Renderer},
|
||||||
scene::camera::{self, Camera},
|
scene::camera::{self, Camera},
|
||||||
ui::{fonts::ConrodVoxygenFonts, slot, Graphic, Ingameable, ScaleMode, Ui},
|
ui::{fonts::ConrodVoxygenFonts, slot, Graphic, Ingameable, ScaleMode, Ui},
|
||||||
window::{Event as WinEvent, GameInput},
|
window::{Event as WinEvent, GameInput},
|
||||||
@ -246,6 +246,7 @@ pub enum Event {
|
|||||||
ChangeLanguage(LanguageMetadata),
|
ChangeLanguage(LanguageMetadata),
|
||||||
ChangeBinding(GameInput),
|
ChangeBinding(GameInput),
|
||||||
ChangeFreeLookBehavior(PressBehavior),
|
ChangeFreeLookBehavior(PressBehavior),
|
||||||
|
ChangeLightingMode(LightingMode),
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Are these the possible layouts we want?
|
// TODO: Are these the possible layouts we want?
|
||||||
@ -1858,6 +1859,9 @@ impl Hud {
|
|||||||
settings_window::Event::ChangeLanguage(language) => {
|
settings_window::Event::ChangeLanguage(language) => {
|
||||||
events.push(Event::ChangeLanguage(language));
|
events.push(Event::ChangeLanguage(language));
|
||||||
},
|
},
|
||||||
|
settings_window::Event::ChangeLightingMode(new_lighting_mode) => {
|
||||||
|
events.push(Event::ChangeLightingMode(new_lighting_mode));
|
||||||
|
},
|
||||||
settings_window::Event::ToggleFullscreen => {
|
settings_window::Event::ToggleFullscreen => {
|
||||||
events.push(Event::ToggleFullscreen);
|
events.push(Event::ToggleFullscreen);
|
||||||
},
|
},
|
||||||
|
@ -4,7 +4,7 @@ use super::{
|
|||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
i18n::{list_localizations, LanguageMetadata, VoxygenLocalization},
|
i18n::{list_localizations, LanguageMetadata, VoxygenLocalization},
|
||||||
render::{AaMode, CloudMode, FluidMode},
|
render::{AaMode, CloudMode, FluidMode, LightingMode},
|
||||||
ui::{fonts::ConrodVoxygenFonts, ImageSlider, ScaleMode, ToggleButton},
|
ui::{fonts::ConrodVoxygenFonts, ImageSlider, ScaleMode, ToggleButton},
|
||||||
window::GameInput,
|
window::GameInput,
|
||||||
GlobalState,
|
GlobalState,
|
||||||
@ -115,6 +115,8 @@ widget_ids! {
|
|||||||
fluid_mode_list,
|
fluid_mode_list,
|
||||||
fullscreen_button,
|
fullscreen_button,
|
||||||
fullscreen_label,
|
fullscreen_label,
|
||||||
|
lighting_mode_text,
|
||||||
|
lighting_mode_list,
|
||||||
save_window_size_button,
|
save_window_size_button,
|
||||||
audio_volume_slider,
|
audio_volume_slider,
|
||||||
audio_volume_text,
|
audio_volume_text,
|
||||||
@ -228,6 +230,7 @@ pub enum Event {
|
|||||||
ChangeAaMode(AaMode),
|
ChangeAaMode(AaMode),
|
||||||
ChangeCloudMode(CloudMode),
|
ChangeCloudMode(CloudMode),
|
||||||
ChangeFluidMode(FluidMode),
|
ChangeFluidMode(FluidMode),
|
||||||
|
ChangeLightingMode(LightingMode),
|
||||||
AdjustMusicVolume(f32),
|
AdjustMusicVolume(f32),
|
||||||
AdjustSfxVolume(f32),
|
AdjustSfxVolume(f32),
|
||||||
ChangeAudioDevice(String),
|
ChangeAudioDevice(String),
|
||||||
@ -1858,11 +1861,56 @@ impl<'a> Widget for SettingsWindow<'a> {
|
|||||||
events.push(Event::ChangeFluidMode(mode_list[clicked]));
|
events.push(Event::ChangeFluidMode(mode_list[clicked]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LightingMode
|
||||||
|
Text::new(
|
||||||
|
&self
|
||||||
|
.localized_strings
|
||||||
|
.get("hud.settings.lighting_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.lighting_mode_text, ui);
|
||||||
|
|
||||||
|
let mode_list = [
|
||||||
|
LightingMode::Ashikmin,
|
||||||
|
LightingMode::BlinnPhong,
|
||||||
|
LightingMode::Lambertian,
|
||||||
|
];
|
||||||
|
let mode_label_list = [
|
||||||
|
&self
|
||||||
|
.localized_strings
|
||||||
|
.get("hud.settings.lighting_rendering_mode.ashikmin"),
|
||||||
|
&self
|
||||||
|
.localized_strings
|
||||||
|
.get("hud.settings.lighting_rendering_mode.blinnphong"),
|
||||||
|
&self
|
||||||
|
.localized_strings
|
||||||
|
.get("hud.settings.lighting_rendering_mode.lambertian"),
|
||||||
|
];
|
||||||
|
|
||||||
|
// Get which lighting rendering mode is currently active
|
||||||
|
let selected = mode_list
|
||||||
|
.iter()
|
||||||
|
.position(|x| *x == self.global_state.settings.graphics.lighting_mode);
|
||||||
|
|
||||||
|
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.lighting_mode_text, 8.0)
|
||||||
|
.set(state.ids.lighting_mode_list, ui)
|
||||||
|
{
|
||||||
|
events.push(Event::ChangeLightingMode(mode_list[clicked]));
|
||||||
|
}
|
||||||
|
|
||||||
// Fullscreen
|
// Fullscreen
|
||||||
Text::new(&self.localized_strings.get("hud.settings.fullscreen"))
|
Text::new(&self.localized_strings.get("hud.settings.fullscreen"))
|
||||||
.font_size(self.fonts.cyri.scale(14))
|
.font_size(self.fonts.cyri.scale(14))
|
||||||
.font_id(self.fonts.cyri.conrod_id)
|
.font_id(self.fonts.cyri.conrod_id)
|
||||||
.down_from(state.ids.fluid_mode_list, 8.0)
|
.down_from(state.ids.lighting_mode_list, 8.0)
|
||||||
.color(TEXT_COLOR)
|
.color(TEXT_COLOR)
|
||||||
.set(state.ids.fullscreen_label, ui);
|
.set(state.ids.fullscreen_label, ui);
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ pub use self::{
|
|||||||
postprocess::{
|
postprocess::{
|
||||||
create_mesh as create_pp_mesh, Locals as PostProcessLocals, PostProcessPipeline,
|
create_mesh as create_pp_mesh, Locals as PostProcessLocals, PostProcessPipeline,
|
||||||
},
|
},
|
||||||
|
shadow::{Locals as ShadowLocals, ShadowPipeline},
|
||||||
skybox::{create_mesh as create_skybox_mesh, Locals as SkyboxLocals, SkyboxPipeline},
|
skybox::{create_mesh as create_skybox_mesh, Locals as SkyboxLocals, SkyboxPipeline},
|
||||||
sprite::{Instance as SpriteInstance, SpritePipeline},
|
sprite::{Instance as SpriteInstance, SpritePipeline},
|
||||||
terrain::{Locals as TerrainLocals, TerrainPipeline},
|
terrain::{Locals as TerrainLocals, TerrainPipeline},
|
||||||
@ -32,8 +33,8 @@ pub use self::{
|
|||||||
Globals, Light, Shadow,
|
Globals, Light, Shadow,
|
||||||
},
|
},
|
||||||
renderer::{
|
renderer::{
|
||||||
LodColorFmt, LodTextureFmt, Renderer, TgtColorFmt, TgtDepthStencilFmt, WinColorFmt,
|
LodColorFmt, LodTextureFmt, Renderer, ShadowDepthStencilFmt, TgtColorFmt,
|
||||||
WinDepthFmt,
|
TgtDepthStencilFmt, WinColorFmt, WinDepthFmt,
|
||||||
},
|
},
|
||||||
texture::Texture,
|
texture::Texture,
|
||||||
};
|
};
|
||||||
@ -84,3 +85,11 @@ pub enum FluidMode {
|
|||||||
Cheap,
|
Cheap,
|
||||||
Shiny,
|
Shiny,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Lighting modes
|
||||||
|
#[derive(PartialEq, Eq, Clone, Copy, Debug, Serialize, Deserialize)]
|
||||||
|
pub enum LightingMode {
|
||||||
|
Ashikmin,
|
||||||
|
BlinnPhong,
|
||||||
|
Lambertian,
|
||||||
|
}
|
||||||
|
@ -38,6 +38,8 @@ gfx_defines! {
|
|||||||
lights: gfx::ConstantBuffer<Light> = "u_lights",
|
lights: gfx::ConstantBuffer<Light> = "u_lights",
|
||||||
shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
|
shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
|
||||||
|
|
||||||
|
shadow_maps: gfx::TextureSampler<f32> = "t_shadow_maps",
|
||||||
|
|
||||||
map: gfx::TextureSampler<[f32; 4]> = "t_map",
|
map: gfx::TextureSampler<[f32; 4]> = "t_map",
|
||||||
horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
|
horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
|
||||||
|
|
||||||
|
@ -23,6 +23,9 @@ gfx_defines! {
|
|||||||
globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
||||||
lights: gfx::ConstantBuffer<Light> = "u_lights",
|
lights: gfx::ConstantBuffer<Light> = "u_lights",
|
||||||
shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
|
shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
|
||||||
|
|
||||||
|
shadow_maps: gfx::TextureSampler<f32> = "t_shadow_maps",
|
||||||
|
|
||||||
map: gfx::TextureSampler<[f32; 4]> = "t_map",
|
map: gfx::TextureSampler<[f32; 4]> = "t_map",
|
||||||
horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
|
horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ pub mod figure;
|
|||||||
pub mod fluid;
|
pub mod fluid;
|
||||||
pub mod lod_terrain;
|
pub mod lod_terrain;
|
||||||
pub mod postprocess;
|
pub mod postprocess;
|
||||||
|
pub mod shadow;
|
||||||
pub mod skybox;
|
pub mod skybox;
|
||||||
pub mod sprite;
|
pub mod sprite;
|
||||||
pub mod terrain;
|
pub mod terrain;
|
||||||
@ -32,6 +33,8 @@ gfx_defines! {
|
|||||||
view_distance: [f32; 4] = "view_distance",
|
view_distance: [f32; 4] = "view_distance",
|
||||||
time_of_day: [f32; 4] = "time_of_day", // TODO: Make this f64.
|
time_of_day: [f32; 4] = "time_of_day", // TODO: Make this f64.
|
||||||
tick: [f32; 4] = "tick",
|
tick: [f32; 4] = "tick",
|
||||||
|
/// x, y represent the resolution of the screen;
|
||||||
|
/// w, z represent the near and far planes of the shadow map.
|
||||||
screen_res: [f32; 4] = "screen_res",
|
screen_res: [f32; 4] = "screen_res",
|
||||||
light_shadow_count: [u32; 4] = "light_shadow_count",
|
light_shadow_count: [u32; 4] = "light_shadow_count",
|
||||||
medium: [u32; 4] = "medium",
|
medium: [u32; 4] = "medium",
|
||||||
@ -64,6 +67,7 @@ impl Globals {
|
|||||||
time_of_day: f64,
|
time_of_day: f64,
|
||||||
tick: f64,
|
tick: f64,
|
||||||
screen_res: Vec2<u16>,
|
screen_res: Vec2<u16>,
|
||||||
|
shadow_planes: Vec2<f32>,
|
||||||
light_count: usize,
|
light_count: usize,
|
||||||
shadow_count: usize,
|
shadow_count: usize,
|
||||||
medium: BlockKind,
|
medium: BlockKind,
|
||||||
@ -81,7 +85,13 @@ impl Globals {
|
|||||||
view_distance: [view_distance, tgt_detail, map_bounds.x, map_bounds.y],
|
view_distance: [view_distance, tgt_detail, map_bounds.x, map_bounds.y],
|
||||||
time_of_day: [time_of_day as f32; 4],
|
time_of_day: [time_of_day as f32; 4],
|
||||||
tick: [tick as f32; 4],
|
tick: [tick as f32; 4],
|
||||||
screen_res: Vec4::from(screen_res.map(|e| e as f32)).into_array(),
|
// Provide the shadow map far plane as well.
|
||||||
|
screen_res: [
|
||||||
|
screen_res.x as f32,
|
||||||
|
screen_res.y as f32,
|
||||||
|
shadow_planes.x,
|
||||||
|
shadow_planes.y,
|
||||||
|
],
|
||||||
light_shadow_count: [light_count as u32, shadow_count as u32, 0, 0],
|
light_shadow_count: [light_count as u32, shadow_count as u32, 0, 0],
|
||||||
medium: [if medium.is_fluid() { 1 } else { 0 }; 4],
|
medium: [if medium.is_fluid() { 1 } else { 0 }; 4],
|
||||||
select_pos: select_pos
|
select_pos: select_pos
|
||||||
@ -108,6 +118,7 @@ impl Default for Globals {
|
|||||||
0.0,
|
0.0,
|
||||||
0.0,
|
0.0,
|
||||||
Vec2::new(800, 500),
|
Vec2::new(800, 500),
|
||||||
|
Vec2::new(1.0, 25.0),
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
BlockKind::Air,
|
BlockKind::Air,
|
||||||
|
52
voxygen/src/render/pipelines/shadow.rs
Normal file
52
voxygen/src/render/pipelines/shadow.rs
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
use super::{
|
||||||
|
super::{util::arr_to_mat, Pipeline, ShadowDepthStencilFmt, TerrainLocals},
|
||||||
|
terrain::Vertex,
|
||||||
|
Globals, Light, Shadow,
|
||||||
|
};
|
||||||
|
use gfx::{
|
||||||
|
self, gfx_constant_struct_meta, gfx_defines, gfx_impl_struct_meta, gfx_pipeline,
|
||||||
|
gfx_pipeline_inner,
|
||||||
|
};
|
||||||
|
use vek::*;
|
||||||
|
|
||||||
|
gfx_defines! {
|
||||||
|
constant Locals {
|
||||||
|
shadow_matrices: [[f32; 4]; 4] = "shadowMatrices",
|
||||||
|
}
|
||||||
|
|
||||||
|
pipeline pipe {
|
||||||
|
// Terrain vertex stuff
|
||||||
|
vbuf: gfx::VertexBuffer<Vertex> = (),
|
||||||
|
|
||||||
|
locals: gfx::ConstantBuffer<TerrainLocals> = "u_locals",
|
||||||
|
globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
||||||
|
lights: gfx::ConstantBuffer<Light> = "u_lights",
|
||||||
|
shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
|
||||||
|
|
||||||
|
map: gfx::TextureSampler<[f32; 4]> = "t_map",
|
||||||
|
horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
|
||||||
|
|
||||||
|
noise: gfx::TextureSampler<f32> = "t_noise",
|
||||||
|
|
||||||
|
// Shadow stuff
|
||||||
|
light_shadows: gfx::ConstantBuffer<Locals> = "u_light_shadows",
|
||||||
|
|
||||||
|
tgt_depth_stencil: gfx::DepthTarget<ShadowDepthStencilFmt> = gfx::preset::depth::LESS_EQUAL_TEST,//,Stencil::new(Comparison::Always,0xff,(StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Locals {
|
||||||
|
pub fn new(shadow_mat: Mat4<f32>) -> Self {
|
||||||
|
Self {
|
||||||
|
shadow_matrices: arr_to_mat(shadow_mat.into_col_array()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn default() -> Self { Self::new(Mat4::identity()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ShadowPipeline;
|
||||||
|
|
||||||
|
impl Pipeline for ShadowPipeline {
|
||||||
|
type Vertex = Vertex;
|
||||||
|
}
|
@ -23,6 +23,9 @@ gfx_defines! {
|
|||||||
locals: gfx::ConstantBuffer<Locals> = "u_locals",
|
locals: gfx::ConstantBuffer<Locals> = "u_locals",
|
||||||
globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
||||||
|
|
||||||
|
map: gfx::TextureSampler<[f32; 4]> = "t_map",
|
||||||
|
horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
|
||||||
|
|
||||||
noise: gfx::TextureSampler<f32> = "t_noise",
|
noise: gfx::TextureSampler<f32> = "t_noise",
|
||||||
|
|
||||||
tgt_color: gfx::RenderTarget<TgtColorFmt> = "tgt_color",
|
tgt_color: gfx::RenderTarget<TgtColorFmt> = "tgt_color",
|
||||||
|
@ -37,6 +37,8 @@ gfx_defines! {
|
|||||||
lights: gfx::ConstantBuffer<Light> = "u_lights",
|
lights: gfx::ConstantBuffer<Light> = "u_lights",
|
||||||
shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
|
shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
|
||||||
|
|
||||||
|
shadow_maps: gfx::TextureSampler<f32> = "t_shadow_maps",
|
||||||
|
|
||||||
map: gfx::TextureSampler<[f32; 4]> = "t_map",
|
map: gfx::TextureSampler<[f32; 4]> = "t_map",
|
||||||
horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
|
horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
|
||||||
|
|
||||||
|
@ -29,6 +29,8 @@ gfx_defines! {
|
|||||||
lights: gfx::ConstantBuffer<Light> = "u_lights",
|
lights: gfx::ConstantBuffer<Light> = "u_lights",
|
||||||
shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
|
shadows: gfx::ConstantBuffer<Shadow> = "u_shadows",
|
||||||
|
|
||||||
|
shadow_maps: gfx::TextureSampler<f32> = "t_shadow_maps",
|
||||||
|
|
||||||
map: gfx::TextureSampler<[f32; 4]> = "t_map",
|
map: gfx::TextureSampler<[f32; 4]> = "t_map",
|
||||||
horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
|
horizon: gfx::TextureSampler<[f32; 4]> = "t_horizon",
|
||||||
|
|
||||||
|
@ -5,11 +5,11 @@ use super::{
|
|||||||
mesh::Mesh,
|
mesh::Mesh,
|
||||||
model::{DynamicModel, Model},
|
model::{DynamicModel, Model},
|
||||||
pipelines::{
|
pipelines::{
|
||||||
figure, fluid, lod_terrain, postprocess, skybox, sprite, terrain, ui, Globals, Light,
|
figure, fluid, lod_terrain, postprocess, shadow, skybox, sprite, terrain, ui, Globals,
|
||||||
Shadow,
|
Light, Shadow,
|
||||||
},
|
},
|
||||||
texture::Texture,
|
texture::Texture,
|
||||||
AaMode, CloudMode, FilterMethod, FluidMode, Pipeline, RenderError, WrapMode,
|
AaMode, CloudMode, FilterMethod, FluidMode, LightingMode, Pipeline, RenderError, WrapMode,
|
||||||
};
|
};
|
||||||
use common::assets::{self, watch::ReloadIndicator};
|
use common::assets::{self, watch::ReloadIndicator};
|
||||||
use gfx::{
|
use gfx::{
|
||||||
@ -23,7 +23,7 @@ use log::error;
|
|||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
/// Represents the format of the pre-processed color target.
|
/// Represents the format of the pre-processed color target.
|
||||||
pub type TgtColorFmt = gfx::format::Srgba8;
|
pub type TgtColorFmt = gfx::format::Rgba16F;
|
||||||
/// Represents the format of the pre-processed depth and stencil target.
|
/// Represents the format of the pre-processed depth and stencil target.
|
||||||
pub type TgtDepthStencilFmt = gfx::format::DepthStencil;
|
pub type TgtDepthStencilFmt = gfx::format::DepthStencil;
|
||||||
|
|
||||||
@ -32,6 +32,9 @@ pub type WinColorFmt = gfx::format::Srgba8;
|
|||||||
/// Represents the format of the window's depth target.
|
/// Represents the format of the window's depth target.
|
||||||
pub type WinDepthFmt = gfx::format::Depth;
|
pub type WinDepthFmt = gfx::format::Depth;
|
||||||
|
|
||||||
|
/// Represents the format of the pre-processed shadow depth target.
|
||||||
|
pub type ShadowDepthStencilFmt = gfx::format::Depth32F;
|
||||||
|
|
||||||
/// A handle to a pre-processed color target.
|
/// A handle to a pre-processed color target.
|
||||||
pub type TgtColorView = gfx::handle::RenderTargetView<gfx_backend::Resources, TgtColorFmt>;
|
pub type TgtColorView = gfx::handle::RenderTargetView<gfx_backend::Resources, TgtColorFmt>;
|
||||||
/// A handle to a pre-processed depth target.
|
/// A handle to a pre-processed depth target.
|
||||||
@ -49,12 +52,33 @@ pub type LodTextureFmt = (gfx::format::R8_G8_B8_A8, gfx::format::Unorm); //[gfx:
|
|||||||
/// Represents the format of LOD map color targets.
|
/// Represents the format of LOD map color targets.
|
||||||
pub type LodColorFmt = (gfx::format::R8_G8_B8_A8, gfx::format::Srgb); //[gfx::format::U8Norm; 4];
|
pub type LodColorFmt = (gfx::format::R8_G8_B8_A8, gfx::format::Srgb); //[gfx::format::U8Norm; 4];
|
||||||
|
|
||||||
|
/// A handle to a shadow depth target.
|
||||||
|
pub type ShadowDepthStencilView =
|
||||||
|
gfx::handle::DepthStencilView<gfx_backend::Resources, ShadowDepthStencilFmt>;
|
||||||
|
/// A handle to a shadow depth target as a resource.
|
||||||
|
pub type ShadowResourceView = gfx::handle::ShaderResourceView<
|
||||||
|
gfx_backend::Resources,
|
||||||
|
<ShadowDepthStencilFmt as gfx::format::Formatted>::View,
|
||||||
|
>;
|
||||||
|
|
||||||
/// A handle to a render color target as a resource.
|
/// A handle to a render color target as a resource.
|
||||||
pub type TgtColorRes = gfx::handle::ShaderResourceView<
|
pub type TgtColorRes = gfx::handle::ShaderResourceView<
|
||||||
gfx_backend::Resources,
|
gfx_backend::Resources,
|
||||||
<TgtColorFmt as gfx::format::Formatted>::View,
|
<TgtColorFmt as gfx::format::Formatted>::View,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
|
/// A type that holds shadow map data. Since shadow mapping may not be
|
||||||
|
/// supported on all platforms, we try to keep it separate.
|
||||||
|
pub struct ShadowMapRenderer {
|
||||||
|
encoder: gfx::Encoder<gfx_backend::Resources, gfx_backend::CommandBuffer>,
|
||||||
|
|
||||||
|
depth_stencil_view: ShadowDepthStencilView,
|
||||||
|
res: ShadowResourceView,
|
||||||
|
sampler: Sampler<gfx_backend::Resources>,
|
||||||
|
|
||||||
|
pipeline: GfxPipeline<shadow::pipe::Init<'static>>,
|
||||||
|
}
|
||||||
|
|
||||||
/// A type that encapsulates rendering state. `Renderer` is central to Voxygen's
|
/// A type that encapsulates rendering state. `Renderer` is central to Voxygen's
|
||||||
/// rendering subsystem and contains any state necessary to interact with the
|
/// rendering subsystem and contains any state necessary to interact with the
|
||||||
/// GPU, along with pipeline state objects (PSOs) needed to renderer different
|
/// GPU, along with pipeline state objects (PSOs) needed to renderer different
|
||||||
@ -74,6 +98,8 @@ pub struct Renderer {
|
|||||||
|
|
||||||
sampler: Sampler<gfx_backend::Resources>,
|
sampler: Sampler<gfx_backend::Resources>,
|
||||||
|
|
||||||
|
shadow_map: Option<ShadowMapRenderer>,
|
||||||
|
|
||||||
skybox_pipeline: GfxPipeline<skybox::pipe::Init<'static>>,
|
skybox_pipeline: GfxPipeline<skybox::pipe::Init<'static>>,
|
||||||
figure_pipeline: GfxPipeline<figure::pipe::Init<'static>>,
|
figure_pipeline: GfxPipeline<figure::pipe::Init<'static>>,
|
||||||
terrain_pipeline: GfxPipeline<terrain::pipe::Init<'static>>,
|
terrain_pipeline: GfxPipeline<terrain::pipe::Init<'static>>,
|
||||||
@ -91,6 +117,7 @@ pub struct Renderer {
|
|||||||
aa_mode: AaMode,
|
aa_mode: AaMode,
|
||||||
cloud_mode: CloudMode,
|
cloud_mode: CloudMode,
|
||||||
fluid_mode: FluidMode,
|
fluid_mode: FluidMode,
|
||||||
|
lighting_mode: LightingMode,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Renderer {
|
impl Renderer {
|
||||||
@ -104,6 +131,7 @@ impl Renderer {
|
|||||||
aa_mode: AaMode,
|
aa_mode: AaMode,
|
||||||
cloud_mode: CloudMode,
|
cloud_mode: CloudMode,
|
||||||
fluid_mode: FluidMode,
|
fluid_mode: FluidMode,
|
||||||
|
lighting_mode: LightingMode,
|
||||||
) -> Result<Self, RenderError> {
|
) -> Result<Self, RenderError> {
|
||||||
let mut shader_reload_indicator = ReloadIndicator::new();
|
let mut shader_reload_indicator = ReloadIndicator::new();
|
||||||
|
|
||||||
@ -117,11 +145,13 @@ impl Renderer {
|
|||||||
lod_terrain_pipeline,
|
lod_terrain_pipeline,
|
||||||
postprocess_pipeline,
|
postprocess_pipeline,
|
||||||
player_shadow_pipeline,
|
player_shadow_pipeline,
|
||||||
|
shadow_pipeline,
|
||||||
) = create_pipelines(
|
) = create_pipelines(
|
||||||
&mut factory,
|
&mut factory,
|
||||||
aa_mode,
|
aa_mode,
|
||||||
cloud_mode,
|
cloud_mode,
|
||||||
fluid_mode,
|
fluid_mode,
|
||||||
|
lighting_mode,
|
||||||
&mut shader_reload_indicator,
|
&mut shader_reload_indicator,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
@ -129,6 +159,24 @@ impl Renderer {
|
|||||||
let (tgt_color_view, tgt_depth_stencil_view, tgt_color_res) =
|
let (tgt_color_view, tgt_depth_stencil_view, tgt_color_res) =
|
||||||
Self::create_rt_views(&mut factory, (dims.0, dims.1), aa_mode)?;
|
Self::create_rt_views(&mut factory, (dims.0, dims.1), aa_mode)?;
|
||||||
|
|
||||||
|
let shadow_map = shadow_pipeline.and_then(|pipeline| {
|
||||||
|
match Self::create_shadow_views(&mut factory, dims.0.max(dims.1)) {
|
||||||
|
Ok((depth_stencil_view, res, sampler)) => Some(ShadowMapRenderer {
|
||||||
|
encoder: factory.create_command_buffer().into(),
|
||||||
|
|
||||||
|
depth_stencil_view,
|
||||||
|
res,
|
||||||
|
sampler,
|
||||||
|
|
||||||
|
pipeline,
|
||||||
|
}),
|
||||||
|
Err(err) => {
|
||||||
|
log::warn!("Could not create shadow map views: {:?}", err);
|
||||||
|
None
|
||||||
|
},
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
let sampler = factory.create_sampler_linear();
|
let sampler = factory.create_sampler_linear();
|
||||||
|
|
||||||
let noise_tex = Texture::new(
|
let noise_tex = Texture::new(
|
||||||
@ -151,8 +199,11 @@ impl Renderer {
|
|||||||
tgt_depth_stencil_view,
|
tgt_depth_stencil_view,
|
||||||
|
|
||||||
tgt_color_res,
|
tgt_color_res,
|
||||||
|
|
||||||
sampler,
|
sampler,
|
||||||
|
|
||||||
|
shadow_map,
|
||||||
|
|
||||||
skybox_pipeline,
|
skybox_pipeline,
|
||||||
figure_pipeline,
|
figure_pipeline,
|
||||||
terrain_pipeline,
|
terrain_pipeline,
|
||||||
@ -170,6 +221,7 @@ impl Renderer {
|
|||||||
aa_mode,
|
aa_mode,
|
||||||
cloud_mode,
|
cloud_mode,
|
||||||
fluid_mode,
|
fluid_mode,
|
||||||
|
lighting_mode,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,6 +292,19 @@ impl Renderer {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Change the lighting mode.
|
||||||
|
pub fn set_lighting_mode(&mut self, lighting_mode: LightingMode) -> Result<(), RenderError> {
|
||||||
|
self.lighting_mode = lighting_mode;
|
||||||
|
|
||||||
|
// Recreate render target
|
||||||
|
self.on_resize()?;
|
||||||
|
|
||||||
|
// Recreate pipelines with the new lighting mode
|
||||||
|
self.recreate_pipelines();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Resize internal render targets to match window render target dimensions.
|
/// Resize internal render targets to match window render target dimensions.
|
||||||
pub fn on_resize(&mut self) -> Result<(), RenderError> {
|
pub fn on_resize(&mut self) -> Result<(), RenderError> {
|
||||||
let dims = self.win_color_view.get_dimensions();
|
let dims = self.win_color_view.get_dimensions();
|
||||||
@ -311,6 +376,87 @@ impl Renderer {
|
|||||||
Ok((tgt_color_view, tgt_depth_stencil_view, tgt_color_res))
|
Ok((tgt_color_view, tgt_depth_stencil_view, tgt_color_res))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create textures and views for shadow maps.
|
||||||
|
fn create_shadow_views(
|
||||||
|
factory: &mut gfx_device_gl::Factory,
|
||||||
|
size: u16,
|
||||||
|
) -> Result<
|
||||||
|
(
|
||||||
|
ShadowDepthStencilView,
|
||||||
|
ShadowResourceView,
|
||||||
|
Sampler<gfx_backend::Resources>,
|
||||||
|
),
|
||||||
|
RenderError,
|
||||||
|
> {
|
||||||
|
let levels = 1;
|
||||||
|
|
||||||
|
/* let color_cty = <<TgtColorFmt as gfx::format::Formatted>::Channel as gfx::format::ChannelTyped
|
||||||
|
>::get_channel_type();
|
||||||
|
let tgt_color_tex = factory.create_texture(
|
||||||
|
kind,
|
||||||
|
levels,
|
||||||
|
gfx::memory::Bind::SHADER_RESOURCE | gfx::memory::Bind::RENDER_TARGET,
|
||||||
|
gfx::memory::Usage::Data,
|
||||||
|
Some(color_cty),
|
||||||
|
)?;
|
||||||
|
let tgt_color_res = factory.view_texture_as_shader_resource::<TgtColorFmt>(
|
||||||
|
&tgt_color_tex,
|
||||||
|
(0, levels - 1),
|
||||||
|
gfx::format::Swizzle::new(),
|
||||||
|
)?;
|
||||||
|
let tgt_color_view = factory.view_texture_as_render_target(&tgt_color_tex, 0, None)?;
|
||||||
|
|
||||||
|
let depth_stencil_cty = <<TgtDepthStencilFmt as gfx::format::Formatted>::Channel as gfx::format::ChannelTyped>::get_channel_type();
|
||||||
|
let tgt_depth_stencil_tex = factory.create_texture(
|
||||||
|
kind,
|
||||||
|
levels,
|
||||||
|
gfx::memory::Bind::DEPTH_STENCIL,
|
||||||
|
gfx::memory::Usage::Data,
|
||||||
|
Some(depth_stencil_cty),
|
||||||
|
)?;
|
||||||
|
let tgt_depth_stencil_view =
|
||||||
|
factory.view_texture_as_depth_stencil_trivial(&tgt_depth_stencil_tex)?; */
|
||||||
|
let depth_stencil_cty = <<ShadowDepthStencilFmt as gfx::format::Formatted>::Channel as gfx::format::ChannelTyped>::get_channel_type();
|
||||||
|
let shadow_tex = factory
|
||||||
|
.create_texture(
|
||||||
|
gfx::texture::Kind::CubeArray(size / 4, 32),
|
||||||
|
1 as gfx::texture::Level,
|
||||||
|
gfx::memory::Bind::SHADER_RESOURCE | gfx::memory::Bind::DEPTH_STENCIL,
|
||||||
|
gfx::memory::Usage::Data,
|
||||||
|
Some(depth_stencil_cty),
|
||||||
|
/* Some(<<F as gfx::format::Formatted>::Channel as
|
||||||
|
* gfx::format::ChannelTyped>::get_channel_type()), */
|
||||||
|
)
|
||||||
|
.map_err(|err| RenderError::CombinedError(gfx::CombinedError::Texture(err)))?;
|
||||||
|
|
||||||
|
let mut sampler_info = gfx::texture::SamplerInfo::new(
|
||||||
|
gfx::texture::FilterMethod::Bilinear,
|
||||||
|
gfx::texture::WrapMode::Border,
|
||||||
|
);
|
||||||
|
sampler_info.comparison = Some(Comparison::LessEqual);
|
||||||
|
sampler_info.border = [1.0; 4].into();
|
||||||
|
let shadow_tex_sampler = factory.create_sampler(sampler_info);
|
||||||
|
|
||||||
|
let tgt_shadow_view = factory.view_texture_as_depth_stencil_trivial(&shadow_tex)?;
|
||||||
|
/* let tgt_shadow_res = factory.view_texture_as_shader_resource::<TgtColorFmt>(
|
||||||
|
&tgt_color_tex,
|
||||||
|
(0, levels - 1),
|
||||||
|
gfx::format::Swizzle::new(),
|
||||||
|
)?; */
|
||||||
|
|
||||||
|
// let tgt_shadow_view =
|
||||||
|
// factory.view_texture_as_depth_stencil_trivial(&tgt_color_tex)?;
|
||||||
|
// let tgt_shadow_view = factory.view_texture_as_shader_resource(&tgt_color_tex,
|
||||||
|
// 0, None)?;
|
||||||
|
let tgt_shadow_res = factory.view_texture_as_shader_resource::<ShadowDepthStencilFmt>(
|
||||||
|
&shadow_tex,
|
||||||
|
(0, levels - 1),
|
||||||
|
gfx::format::Swizzle::new(),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok((tgt_shadow_view, tgt_shadow_res, shadow_tex_sampler))
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the resolution of the render target.
|
/// Get the resolution of the render target.
|
||||||
pub fn get_resolution(&self) -> Vec2<u16> {
|
pub fn get_resolution(&self) -> Vec2<u16> {
|
||||||
Vec2::new(
|
Vec2::new(
|
||||||
@ -322,14 +468,29 @@ impl Renderer {
|
|||||||
/// Queue the clearing of the depth target ready for a new frame to be
|
/// Queue the clearing of the depth target ready for a new frame to be
|
||||||
/// rendered.
|
/// rendered.
|
||||||
pub fn clear(&mut self) {
|
pub fn clear(&mut self) {
|
||||||
|
if let Some(shadow_map) = self.shadow_map.as_mut() {
|
||||||
|
shadow_map
|
||||||
|
.encoder
|
||||||
|
.clear_depth(&shadow_map.depth_stencil_view, 1.0);
|
||||||
|
}
|
||||||
self.encoder.clear_depth(&self.tgt_depth_stencil_view, 1.0);
|
self.encoder.clear_depth(&self.tgt_depth_stencil_view, 1.0);
|
||||||
self.encoder.clear_stencil(&self.tgt_depth_stencil_view, 0);
|
self.encoder.clear_stencil(&self.tgt_depth_stencil_view, 0);
|
||||||
self.encoder.clear_depth(&self.win_depth_view, 1.0);
|
self.encoder.clear_depth(&self.win_depth_view, 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Perform all queued draw calls for shadows.
|
||||||
|
pub fn flush_shadows(&mut self) {
|
||||||
|
if let Some(shadow_map) = self.shadow_map.as_mut() {
|
||||||
|
shadow_map.encoder.flush(&mut self.device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Perform all queued draw calls for this frame and clean up discarded
|
/// Perform all queued draw calls for this frame and clean up discarded
|
||||||
/// items.
|
/// items.
|
||||||
pub fn flush(&mut self) {
|
pub fn flush(&mut self) {
|
||||||
|
if let Some(shadow_map) = self.shadow_map.as_mut() {
|
||||||
|
shadow_map.encoder.flush(&mut self.device);
|
||||||
|
}
|
||||||
self.encoder.flush(&mut self.device);
|
self.encoder.flush(&mut self.device);
|
||||||
self.device.cleanup();
|
self.device.cleanup();
|
||||||
|
|
||||||
@ -346,6 +507,7 @@ impl Renderer {
|
|||||||
self.aa_mode,
|
self.aa_mode,
|
||||||
self.cloud_mode,
|
self.cloud_mode,
|
||||||
self.fluid_mode,
|
self.fluid_mode,
|
||||||
|
self.lighting_mode,
|
||||||
&mut self.shader_reload_indicator,
|
&mut self.shader_reload_indicator,
|
||||||
) {
|
) {
|
||||||
Ok((
|
Ok((
|
||||||
@ -358,6 +520,7 @@ impl Renderer {
|
|||||||
lod_terrain_pipeline,
|
lod_terrain_pipeline,
|
||||||
postprocess_pipeline,
|
postprocess_pipeline,
|
||||||
player_shadow_pipeline,
|
player_shadow_pipeline,
|
||||||
|
shadow_pipeline,
|
||||||
)) => {
|
)) => {
|
||||||
self.skybox_pipeline = skybox_pipeline;
|
self.skybox_pipeline = skybox_pipeline;
|
||||||
self.figure_pipeline = figure_pipeline;
|
self.figure_pipeline = figure_pipeline;
|
||||||
@ -368,6 +531,11 @@ impl Renderer {
|
|||||||
self.lod_terrain_pipeline = lod_terrain_pipeline;
|
self.lod_terrain_pipeline = lod_terrain_pipeline;
|
||||||
self.postprocess_pipeline = postprocess_pipeline;
|
self.postprocess_pipeline = postprocess_pipeline;
|
||||||
self.player_shadow_pipeline = player_shadow_pipeline;
|
self.player_shadow_pipeline = player_shadow_pipeline;
|
||||||
|
if let (Some(pipeline), Some(shadow_map)) =
|
||||||
|
(shadow_pipeline, self.shadow_map.as_mut())
|
||||||
|
{
|
||||||
|
shadow_map.pipeline = pipeline;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
Err(e) => error!(
|
Err(e) => error!(
|
||||||
"Could not recreate shaders from assets due to an error: {:#?}",
|
"Could not recreate shaders from assets due to an error: {:#?}",
|
||||||
@ -516,6 +684,8 @@ impl Renderer {
|
|||||||
model: &Model<skybox::SkyboxPipeline>,
|
model: &Model<skybox::SkyboxPipeline>,
|
||||||
globals: &Consts<Globals>,
|
globals: &Consts<Globals>,
|
||||||
locals: &Consts<skybox::Locals>,
|
locals: &Consts<skybox::Locals>,
|
||||||
|
map: &Texture<LodColorFmt>,
|
||||||
|
horizon: &Texture<LodTextureFmt>,
|
||||||
) {
|
) {
|
||||||
self.encoder.draw(
|
self.encoder.draw(
|
||||||
&gfx::Slice {
|
&gfx::Slice {
|
||||||
@ -531,6 +701,8 @@ impl Renderer {
|
|||||||
locals: locals.buf.clone(),
|
locals: locals.buf.clone(),
|
||||||
globals: globals.buf.clone(),
|
globals: globals.buf.clone(),
|
||||||
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||||
|
map: (map.srv.clone(), map.sampler.clone()),
|
||||||
|
horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
||||||
tgt_color: self.tgt_color_view.clone(),
|
tgt_color: self.tgt_color_view.clone(),
|
||||||
tgt_depth_stencil: (self.tgt_depth_stencil_view.clone(), (1, 1)),
|
tgt_depth_stencil: (self.tgt_depth_stencil_view.clone(), (1, 1)),
|
||||||
},
|
},
|
||||||
@ -549,6 +721,12 @@ impl Renderer {
|
|||||||
map: &Texture<LodColorFmt>,
|
map: &Texture<LodColorFmt>,
|
||||||
horizon: &Texture<LodTextureFmt>,
|
horizon: &Texture<LodTextureFmt>,
|
||||||
) {
|
) {
|
||||||
|
let shadow_maps = if let Some(shadow_map) = &mut self.shadow_map {
|
||||||
|
(shadow_map.res.clone(), shadow_map.sampler.clone())
|
||||||
|
} else {
|
||||||
|
(self.noise_tex.srv.clone(), self.noise_tex.sampler.clone())
|
||||||
|
};
|
||||||
|
|
||||||
self.encoder.draw(
|
self.encoder.draw(
|
||||||
&gfx::Slice {
|
&gfx::Slice {
|
||||||
start: model.vertex_range().start,
|
start: model.vertex_range().start,
|
||||||
@ -565,6 +743,7 @@ impl Renderer {
|
|||||||
bones: bones.buf.clone(),
|
bones: bones.buf.clone(),
|
||||||
lights: lights.buf.clone(),
|
lights: lights.buf.clone(),
|
||||||
shadows: shadows.buf.clone(),
|
shadows: shadows.buf.clone(),
|
||||||
|
shadow_maps,
|
||||||
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||||
map: (map.srv.clone(), map.sampler.clone()),
|
map: (map.srv.clone(), map.sampler.clone()),
|
||||||
horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
||||||
@ -586,6 +765,12 @@ impl Renderer {
|
|||||||
map: &Texture<LodColorFmt>,
|
map: &Texture<LodColorFmt>,
|
||||||
horizon: &Texture<LodTextureFmt>,
|
horizon: &Texture<LodTextureFmt>,
|
||||||
) {
|
) {
|
||||||
|
let shadow_maps = if let Some(shadow_map) = &mut self.shadow_map {
|
||||||
|
(shadow_map.res.clone(), shadow_map.sampler.clone())
|
||||||
|
} else {
|
||||||
|
(self.noise_tex.srv.clone(), self.noise_tex.sampler.clone())
|
||||||
|
};
|
||||||
|
|
||||||
self.encoder.draw(
|
self.encoder.draw(
|
||||||
&gfx::Slice {
|
&gfx::Slice {
|
||||||
start: model.vertex_range().start,
|
start: model.vertex_range().start,
|
||||||
@ -602,6 +787,7 @@ impl Renderer {
|
|||||||
bones: bones.buf.clone(),
|
bones: bones.buf.clone(),
|
||||||
lights: lights.buf.clone(),
|
lights: lights.buf.clone(),
|
||||||
shadows: shadows.buf.clone(),
|
shadows: shadows.buf.clone(),
|
||||||
|
shadow_maps,
|
||||||
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||||
map: (map.srv.clone(), map.sampler.clone()),
|
map: (map.srv.clone(), map.sampler.clone()),
|
||||||
horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
||||||
@ -623,6 +809,12 @@ impl Renderer {
|
|||||||
map: &Texture<LodColorFmt>,
|
map: &Texture<LodColorFmt>,
|
||||||
horizon: &Texture<LodTextureFmt>,
|
horizon: &Texture<LodTextureFmt>,
|
||||||
) {
|
) {
|
||||||
|
let shadow_maps = if let Some(shadow_map) = &mut self.shadow_map {
|
||||||
|
(shadow_map.res.clone(), shadow_map.sampler.clone())
|
||||||
|
} else {
|
||||||
|
(self.noise_tex.srv.clone(), self.noise_tex.sampler.clone())
|
||||||
|
};
|
||||||
|
|
||||||
self.encoder.draw(
|
self.encoder.draw(
|
||||||
&gfx::Slice {
|
&gfx::Slice {
|
||||||
start: model.vertex_range().start,
|
start: model.vertex_range().start,
|
||||||
@ -639,6 +831,7 @@ impl Renderer {
|
|||||||
bones: bones.buf.clone(),
|
bones: bones.buf.clone(),
|
||||||
lights: lights.buf.clone(),
|
lights: lights.buf.clone(),
|
||||||
shadows: shadows.buf.clone(),
|
shadows: shadows.buf.clone(),
|
||||||
|
shadow_maps,
|
||||||
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||||
map: (map.srv.clone(), map.sampler.clone()),
|
map: (map.srv.clone(), map.sampler.clone()),
|
||||||
horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
||||||
@ -660,6 +853,12 @@ impl Renderer {
|
|||||||
map: &Texture<LodColorFmt>,
|
map: &Texture<LodColorFmt>,
|
||||||
horizon: &Texture<LodTextureFmt>,
|
horizon: &Texture<LodTextureFmt>,
|
||||||
) {
|
) {
|
||||||
|
let shadow_maps = if let Some(shadow_map) = &mut self.shadow_map {
|
||||||
|
(shadow_map.res.clone(), shadow_map.sampler.clone())
|
||||||
|
} else {
|
||||||
|
(self.noise_tex.srv.clone(), self.noise_tex.sampler.clone())
|
||||||
|
};
|
||||||
|
|
||||||
self.encoder.draw(
|
self.encoder.draw(
|
||||||
&gfx::Slice {
|
&gfx::Slice {
|
||||||
start: model.vertex_range().start,
|
start: model.vertex_range().start,
|
||||||
@ -675,6 +874,7 @@ impl Renderer {
|
|||||||
globals: globals.buf.clone(),
|
globals: globals.buf.clone(),
|
||||||
lights: lights.buf.clone(),
|
lights: lights.buf.clone(),
|
||||||
shadows: shadows.buf.clone(),
|
shadows: shadows.buf.clone(),
|
||||||
|
shadow_maps,
|
||||||
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||||
map: (map.srv.clone(), map.sampler.clone()),
|
map: (map.srv.clone(), map.sampler.clone()),
|
||||||
horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
||||||
@ -684,6 +884,53 @@ impl Renderer {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Queue the rendering of the player silhouette in the upcoming frame.
|
||||||
|
pub fn render_shadow(
|
||||||
|
&mut self,
|
||||||
|
model: &Model<terrain::TerrainPipeline>,
|
||||||
|
globals: &Consts<Globals>,
|
||||||
|
terrain_locals: &Consts<terrain::Locals>,
|
||||||
|
locals: &Consts<shadow::Locals>,
|
||||||
|
lights: &Consts<Light>,
|
||||||
|
shadows: &Consts<Shadow>,
|
||||||
|
map: &Texture<LodColorFmt>,
|
||||||
|
horizon: &Texture<LodTextureFmt>,
|
||||||
|
) {
|
||||||
|
// NOTE: Don't render shadows if the shader is not supported.
|
||||||
|
let shadow_map = if let Some(shadow_map) = &mut self.shadow_map {
|
||||||
|
shadow_map
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
shadow_map.encoder.draw(
|
||||||
|
&gfx::Slice {
|
||||||
|
start: model.vertex_range().start,
|
||||||
|
end: model.vertex_range().end,
|
||||||
|
base_vertex: 0,
|
||||||
|
instances: None,
|
||||||
|
buffer: gfx::IndexBuffer::Auto,
|
||||||
|
},
|
||||||
|
&shadow_map.pipeline.pso,
|
||||||
|
&shadow::pipe::Data {
|
||||||
|
// Terrain vertex stuff
|
||||||
|
vbuf: model.vbuf.clone(),
|
||||||
|
locals: terrain_locals.buf.clone(),
|
||||||
|
globals: globals.buf.clone(),
|
||||||
|
lights: lights.buf.clone(),
|
||||||
|
shadows: shadows.buf.clone(),
|
||||||
|
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||||
|
map: (map.srv.clone(), map.sampler.clone()),
|
||||||
|
horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
||||||
|
|
||||||
|
// Shadow stuff
|
||||||
|
light_shadows: locals.buf.clone(),
|
||||||
|
tgt_depth_stencil: shadow_map.depth_stencil_view.clone(),
|
||||||
|
/* tgt_depth_stencil: (self.shadow_depth_stencil_view.clone(), (1, 1)),
|
||||||
|
* shadow_tex: (self.shadow_res.clone(), self.shadow_sampler.clone()), */
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// Queue the rendering of the provided terrain chunk model in the upcoming
|
/// Queue the rendering of the provided terrain chunk model in the upcoming
|
||||||
/// frame.
|
/// frame.
|
||||||
pub fn render_fluid_chunk(
|
pub fn render_fluid_chunk(
|
||||||
@ -697,6 +944,11 @@ impl Renderer {
|
|||||||
horizon: &Texture<LodTextureFmt>,
|
horizon: &Texture<LodTextureFmt>,
|
||||||
waves: &Texture,
|
waves: &Texture,
|
||||||
) {
|
) {
|
||||||
|
let shadow_maps = if let Some(shadow_map) = &mut self.shadow_map {
|
||||||
|
(shadow_map.res.clone(), shadow_map.sampler.clone())
|
||||||
|
} else {
|
||||||
|
(self.noise_tex.srv.clone(), self.noise_tex.sampler.clone())
|
||||||
|
};
|
||||||
self.encoder.draw(
|
self.encoder.draw(
|
||||||
&gfx::Slice {
|
&gfx::Slice {
|
||||||
start: model.vertex_range().start,
|
start: model.vertex_range().start,
|
||||||
@ -712,6 +964,7 @@ impl Renderer {
|
|||||||
globals: globals.buf.clone(),
|
globals: globals.buf.clone(),
|
||||||
lights: lights.buf.clone(),
|
lights: lights.buf.clone(),
|
||||||
shadows: shadows.buf.clone(),
|
shadows: shadows.buf.clone(),
|
||||||
|
shadow_maps,
|
||||||
map: (map.srv.clone(), map.sampler.clone()),
|
map: (map.srv.clone(), map.sampler.clone()),
|
||||||
horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
||||||
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||||
@ -734,6 +987,11 @@ impl Renderer {
|
|||||||
map: &Texture<LodColorFmt>,
|
map: &Texture<LodColorFmt>,
|
||||||
horizon: &Texture<LodTextureFmt>,
|
horizon: &Texture<LodTextureFmt>,
|
||||||
) {
|
) {
|
||||||
|
let shadow_maps = if let Some(shadow_map) = &mut self.shadow_map {
|
||||||
|
(shadow_map.res.clone(), shadow_map.sampler.clone())
|
||||||
|
} else {
|
||||||
|
(self.noise_tex.srv.clone(), self.noise_tex.sampler.clone())
|
||||||
|
};
|
||||||
self.encoder.draw(
|
self.encoder.draw(
|
||||||
&gfx::Slice {
|
&gfx::Slice {
|
||||||
start: model.vertex_range().start,
|
start: model.vertex_range().start,
|
||||||
@ -749,6 +1007,7 @@ impl Renderer {
|
|||||||
globals: globals.buf.clone(),
|
globals: globals.buf.clone(),
|
||||||
lights: lights.buf.clone(),
|
lights: lights.buf.clone(),
|
||||||
shadows: shadows.buf.clone(),
|
shadows: shadows.buf.clone(),
|
||||||
|
shadow_maps,
|
||||||
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
noise: (self.noise_tex.srv.clone(), self.noise_tex.sampler.clone()),
|
||||||
map: (map.srv.clone(), map.sampler.clone()),
|
map: (map.srv.clone(), map.sampler.clone()),
|
||||||
horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
horizon: (horizon.srv.clone(), horizon.sampler.clone()),
|
||||||
@ -867,6 +1126,7 @@ fn create_pipelines(
|
|||||||
aa_mode: AaMode,
|
aa_mode: AaMode,
|
||||||
cloud_mode: CloudMode,
|
cloud_mode: CloudMode,
|
||||||
fluid_mode: FluidMode,
|
fluid_mode: FluidMode,
|
||||||
|
lighting_mode: LightingMode,
|
||||||
shader_reload_indicator: &mut ReloadIndicator,
|
shader_reload_indicator: &mut ReloadIndicator,
|
||||||
) -> Result<
|
) -> Result<
|
||||||
(
|
(
|
||||||
@ -879,9 +1139,15 @@ fn create_pipelines(
|
|||||||
GfxPipeline<lod_terrain::pipe::Init<'static>>,
|
GfxPipeline<lod_terrain::pipe::Init<'static>>,
|
||||||
GfxPipeline<postprocess::pipe::Init<'static>>,
|
GfxPipeline<postprocess::pipe::Init<'static>>,
|
||||||
GfxPipeline<figure::pipe::Init<'static>>,
|
GfxPipeline<figure::pipe::Init<'static>>,
|
||||||
|
Option<GfxPipeline<shadow::pipe::Init<'static>>>,
|
||||||
),
|
),
|
||||||
RenderError,
|
RenderError,
|
||||||
> {
|
> {
|
||||||
|
let constants = assets::load_watched::<String>(
|
||||||
|
"voxygen.shaders.include.constants",
|
||||||
|
shader_reload_indicator,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
let globals =
|
let globals =
|
||||||
assets::load_watched::<String>("voxygen.shaders.include.globals", shader_reload_indicator)
|
assets::load_watched::<String>("voxygen.shaders.include.globals", shader_reload_indicator)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -901,6 +1167,35 @@ fn create_pipelines(
|
|||||||
assets::load_watched::<String>("voxygen.shaders.include.lod", shader_reload_indicator)
|
assets::load_watched::<String>("voxygen.shaders.include.lod", shader_reload_indicator)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
// We dynamically add extra configuration settings to the constants file.
|
||||||
|
let constants = format!(
|
||||||
|
r#"
|
||||||
|
{}
|
||||||
|
|
||||||
|
#define VOXYGEN_COMPUTATION_PREERENCE {}
|
||||||
|
#define FLUID_MODE {}
|
||||||
|
#define CLOUD_MODE {}
|
||||||
|
#define LIGHTING_ALGORITHM {}
|
||||||
|
|
||||||
|
"#,
|
||||||
|
constants,
|
||||||
|
// TODO: Configurable vertex/fragment shader preference.
|
||||||
|
"VOXYGEN_COMPUTATION_PREERENCE_FRAGMENT",
|
||||||
|
match fluid_mode {
|
||||||
|
FluidMode::Cheap => "FLUID_MODE_CHEAP",
|
||||||
|
FluidMode::Shiny => "FLUID_MODE_SHINY",
|
||||||
|
},
|
||||||
|
match cloud_mode {
|
||||||
|
CloudMode::None => "CLOUD_MODE_NONE",
|
||||||
|
CloudMode::Regular => "CLOUD_MODE_REGULAR",
|
||||||
|
},
|
||||||
|
match lighting_mode {
|
||||||
|
LightingMode::Ashikmin => "LIGHTING_ALGORITHM_ASHIKHMIN",
|
||||||
|
LightingMode::BlinnPhong => "LIGHTING_ALGORITHM_BLINN_PHONG",
|
||||||
|
LightingMode::Lambertian => "CLOUD_MODE_NONE",
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
let anti_alias = assets::load_watched::<String>(
|
let anti_alias = assets::load_watched::<String>(
|
||||||
&["voxygen.shaders.antialias.", match aa_mode {
|
&["voxygen.shaders.antialias.", match aa_mode {
|
||||||
AaMode::None | AaMode::SsaaX4 => "none",
|
AaMode::None | AaMode::SsaaX4 => "none",
|
||||||
@ -925,6 +1220,7 @@ fn create_pipelines(
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut include_ctx = IncludeContext::new();
|
let mut include_ctx = IncludeContext::new();
|
||||||
|
include_ctx.include("constants.glsl", &constants);
|
||||||
include_ctx.include("globals.glsl", &globals);
|
include_ctx.include("globals.glsl", &globals);
|
||||||
include_ctx.include("sky.glsl", &sky);
|
include_ctx.include("sky.glsl", &sky);
|
||||||
include_ctx.include("light.glsl", &light);
|
include_ctx.include("light.glsl", &light);
|
||||||
@ -1074,6 +1370,35 @@ fn create_pipelines(
|
|||||||
gfx::state::CullFace::Back,
|
gfx::state::CullFace::Back,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
// Construct a pipeline for rendering shadow maps.
|
||||||
|
let shadow_pipeline = match create_shadow_pipeline(
|
||||||
|
factory,
|
||||||
|
shadow::pipe::new(),
|
||||||
|
&assets::load_watched::<String>(
|
||||||
|
"voxygen.shaders.light-shadows-vert",
|
||||||
|
shader_reload_indicator,
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
|
&assets::load_watched::<String>(
|
||||||
|
"voxygen.shaders.light-shadows-geom",
|
||||||
|
shader_reload_indicator,
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
|
&assets::load_watched::<String>(
|
||||||
|
"voxygen.shaders.light-shadows-frag",
|
||||||
|
shader_reload_indicator,
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
|
&include_ctx,
|
||||||
|
gfx::state::CullFace::Back,
|
||||||
|
) {
|
||||||
|
Ok(pipe) => Some(pipe),
|
||||||
|
Err(err) => {
|
||||||
|
log::warn!("Could not load shadow map pipeline: {:?}", err);
|
||||||
|
None
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
Ok((
|
Ok((
|
||||||
skybox_pipeline,
|
skybox_pipeline,
|
||||||
figure_pipeline,
|
figure_pipeline,
|
||||||
@ -1084,11 +1409,12 @@ fn create_pipelines(
|
|||||||
lod_terrain_pipeline,
|
lod_terrain_pipeline,
|
||||||
postprocess_pipeline,
|
postprocess_pipeline,
|
||||||
player_shadow_pipeline,
|
player_shadow_pipeline,
|
||||||
|
shadow_pipeline,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new pipeline from the provided vertex shader and fragment shader.
|
/// Create a new pipeline from the provided vertex shader and fragment shader.
|
||||||
fn create_pipeline<'a, P: gfx::pso::PipelineInit>(
|
fn create_pipeline<P: gfx::pso::PipelineInit>(
|
||||||
factory: &mut gfx_backend::Factory,
|
factory: &mut gfx_backend::Factory,
|
||||||
pipe: P,
|
pipe: P,
|
||||||
vs: &str,
|
vs: &str,
|
||||||
@ -1118,3 +1444,45 @@ fn create_pipeline<'a, P: gfx::pso::PipelineInit>(
|
|||||||
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a new shadow map pipeline.
|
||||||
|
fn create_shadow_pipeline<P: gfx::pso::PipelineInit>(
|
||||||
|
factory: &mut gfx_backend::Factory,
|
||||||
|
pipe: P,
|
||||||
|
vs: &str,
|
||||||
|
gs: &str,
|
||||||
|
fs: &str,
|
||||||
|
ctx: &IncludeContext,
|
||||||
|
cull_face: gfx::state::CullFace,
|
||||||
|
) -> Result<GfxPipeline<P>, RenderError> {
|
||||||
|
let vs = ctx.expand(vs)?;
|
||||||
|
let gs = ctx.expand(gs)?;
|
||||||
|
let fs = ctx.expand(fs)?;
|
||||||
|
|
||||||
|
let shader_set =
|
||||||
|
factory.create_shader_set_geometry(vs.as_bytes(), gs.as_bytes(), fs.as_bytes())?;
|
||||||
|
|
||||||
|
let result = Ok(GfxPipeline {
|
||||||
|
pso: factory.create_pipeline_state(
|
||||||
|
&shader_set,
|
||||||
|
gfx::Primitive::TriangleList,
|
||||||
|
gfx::state::Rasterizer {
|
||||||
|
front_face: gfx::state::FrontFace::CounterClockwise,
|
||||||
|
// Second-depth shadow mapping: should help reduce z-fighting provided all objects
|
||||||
|
// are "watertight" (every triangle edge is shared with at most one other
|
||||||
|
// triangle); this *should* be true for Veloren.
|
||||||
|
cull_face: /*cull_face*//*gfx::state::CullFace::Nothing*/match cull_face {
|
||||||
|
gfx::state::CullFace::Front => gfx::state::CullFace::Back,
|
||||||
|
gfx::state::CullFace::Back => gfx::state::CullFace::Front,
|
||||||
|
gfx::state::CullFace::Nothing => gfx::state::CullFace::Nothing,
|
||||||
|
},
|
||||||
|
method: gfx::state::RasterMethod::Fill,
|
||||||
|
offset: Some(gfx::state::Offset(4, /*10*/10)),
|
||||||
|
samples: None,//Some(gfx::state::MultiSample),
|
||||||
|
},
|
||||||
|
pipe,
|
||||||
|
)?,
|
||||||
|
});
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
@ -15,7 +15,7 @@ use crate::{
|
|||||||
audio::{music::MusicMgr, sfx::SfxMgr, AudioFrontend},
|
audio::{music::MusicMgr, sfx::SfxMgr, AudioFrontend},
|
||||||
render::{
|
render::{
|
||||||
create_pp_mesh, create_skybox_mesh, Consts, Globals, Light, Model, PostProcessLocals,
|
create_pp_mesh, create_skybox_mesh, Consts, Globals, Light, Model, PostProcessLocals,
|
||||||
PostProcessPipeline, Renderer, Shadow, SkyboxLocals, SkyboxPipeline,
|
PostProcessPipeline, Renderer, Shadow, ShadowLocals, SkyboxLocals, SkyboxPipeline,
|
||||||
},
|
},
|
||||||
settings::Settings,
|
settings::Settings,
|
||||||
window::{AnalogGameInput, Event},
|
window::{AnalogGameInput, Event},
|
||||||
@ -39,6 +39,12 @@ const LIGHT_DIST_RADIUS: f32 = 64.0; // The distance beyond which lights may not
|
|||||||
const SHADOW_DIST_RADIUS: f32 = 8.0;
|
const SHADOW_DIST_RADIUS: f32 = 8.0;
|
||||||
const SHADOW_MAX_DIST: f32 = 96.0; // The distance beyond which shadows may not be visible
|
const SHADOW_MAX_DIST: f32 = 96.0; // The distance beyond which shadows may not be visible
|
||||||
|
|
||||||
|
// const NEAR_PLANE: f32 = 0.5;
|
||||||
|
// const FAR_PLANE: f32 = 100000.0;
|
||||||
|
|
||||||
|
const SHADOW_NEAR: f32 = 0.5; //0.5;//1.0; // Near plane for shadow map rendering.
|
||||||
|
const SHADOW_FAR: f32 = 512.0; //100000.0;//25.0; // Far plane for shadow map rendering.
|
||||||
|
|
||||||
/// Above this speed is considered running
|
/// Above this speed is considered running
|
||||||
/// Used for first person camera effects
|
/// Used for first person camera effects
|
||||||
const RUNNING_THRESHOLD: f32 = 0.7;
|
const RUNNING_THRESHOLD: f32 = 0.7;
|
||||||
@ -56,6 +62,7 @@ struct PostProcess {
|
|||||||
pub struct Scene {
|
pub struct Scene {
|
||||||
globals: Consts<Globals>,
|
globals: Consts<Globals>,
|
||||||
lights: Consts<Light>,
|
lights: Consts<Light>,
|
||||||
|
shadow_mats: Consts<ShadowLocals>,
|
||||||
shadows: Consts<Shadow>,
|
shadows: Consts<Shadow>,
|
||||||
camera: Camera,
|
camera: Camera,
|
||||||
camera_input_state: Vec2<f32>,
|
camera_input_state: Vec2<f32>,
|
||||||
@ -102,6 +109,9 @@ impl Scene {
|
|||||||
shadows: renderer
|
shadows: renderer
|
||||||
.create_consts(&[Shadow::default(); MAX_SHADOW_COUNT])
|
.create_consts(&[Shadow::default(); MAX_SHADOW_COUNT])
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
|
shadow_mats: renderer
|
||||||
|
.create_consts(&[ShadowLocals::default(); MAX_LIGHT_COUNT * 6])
|
||||||
|
.unwrap(),
|
||||||
camera: Camera::new(resolution.x / resolution.y, CameraMode::ThirdPerson),
|
camera: Camera::new(resolution.x / resolution.y, CameraMode::ThirdPerson),
|
||||||
camera_input_state: Vec2::zero(),
|
camera_input_state: Vec2::zero(),
|
||||||
|
|
||||||
@ -344,6 +354,41 @@ impl Scene {
|
|||||||
.update_consts(&mut self.shadows, &shadows)
|
.update_consts(&mut self.shadows, &shadows)
|
||||||
.expect("Failed to update light constants");
|
.expect("Failed to update light constants");
|
||||||
|
|
||||||
|
// Update light projection matrices for the shadow map.
|
||||||
|
// NOTE: The aspect ratio is currently always 1 for our cube maps, since they
|
||||||
|
// are equal on all sides.
|
||||||
|
let shadow_aspect = 1.0;
|
||||||
|
// First, create a perspective projection matrix at 90 degrees (to cover a whole
|
||||||
|
// face of the cube map we're using).
|
||||||
|
let shadow_proj =
|
||||||
|
Mat4::perspective_rh_no(90.0f32.to_radians(), shadow_aspect, SHADOW_NEAR, SHADOW_FAR);
|
||||||
|
// Next, construct the 6 orientations we'll use for the six faces, in terms of
|
||||||
|
// their (forward, up) vectors.
|
||||||
|
let orientations = [
|
||||||
|
(Vec3::new(1.0, 0.0, 0.0), Vec3::new(0.0, -1.0, 0.0)),
|
||||||
|
(Vec3::new(-1.0, 0.0, 0.0), Vec3::new(0.0, -1.0, 0.0)),
|
||||||
|
(Vec3::new(0.0, 1.0, 0.0), Vec3::new(0.0, 0.0, 1.0)),
|
||||||
|
(Vec3::new(0.0, -1.0, 0.0), Vec3::new(0.0, 0.0, -1.0)),
|
||||||
|
(Vec3::new(0.0, 0.0, 1.0), Vec3::new(0.0, -1.0, 0.0)),
|
||||||
|
(Vec3::new(0.0, 0.0, -1.0), Vec3::new(0.0, -1.0, 0.0)),
|
||||||
|
];
|
||||||
|
// NOTE: We could create the shadow map collection at the same time as the
|
||||||
|
// lights, but then we'd have to sort them both, which wastes time.
|
||||||
|
let shadow_mats = lights
|
||||||
|
.iter()
|
||||||
|
.flat_map(|light| {
|
||||||
|
// Now, construct the full projection matrix by making the light look at each
|
||||||
|
// cube face.
|
||||||
|
let eye = Vec3::new(light.pos[0], light.pos[1], light.pos[2]);
|
||||||
|
orientations.iter().map(move |&(forward, up)| {
|
||||||
|
ShadowLocals::new(shadow_proj * Mat4::look_at_rh(eye, eye + forward, up))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
renderer
|
||||||
|
.update_consts(&mut self.shadow_mats, &shadow_mats)
|
||||||
|
.expect("Failed to update light constants");
|
||||||
|
|
||||||
// Update global constants.
|
// Update global constants.
|
||||||
renderer
|
renderer
|
||||||
.update_consts(&mut self.globals, &[Globals::new(
|
.update_consts(&mut self.globals, &[Globals::new(
|
||||||
@ -357,6 +402,7 @@ impl Scene {
|
|||||||
scene_data.state.get_time_of_day(),
|
scene_data.state.get_time_of_day(),
|
||||||
scene_data.state.get_time(),
|
scene_data.state.get_time(),
|
||||||
renderer.get_resolution(),
|
renderer.get_resolution(),
|
||||||
|
Vec2::new(SHADOW_NEAR, SHADOW_FAR),
|
||||||
lights.len(),
|
lights.len(),
|
||||||
shadows.len(),
|
shadows.len(),
|
||||||
scene_data
|
scene_data
|
||||||
@ -413,6 +459,7 @@ impl Scene {
|
|||||||
&self.globals,
|
&self.globals,
|
||||||
&self.lights,
|
&self.lights,
|
||||||
&self.shadows,
|
&self.shadows,
|
||||||
|
&self.shadow_mats,
|
||||||
self.lod.get_data(),
|
self.lod.get_data(),
|
||||||
self.camera.get_focus_pos(),
|
self.camera.get_focus_pos(),
|
||||||
);
|
);
|
||||||
@ -431,7 +478,14 @@ impl Scene {
|
|||||||
self.lod.render(renderer, &self.globals);
|
self.lod.render(renderer, &self.globals);
|
||||||
|
|
||||||
// Render the skybox.
|
// Render the skybox.
|
||||||
renderer.render_skybox(&self.skybox.model, &self.globals, &self.skybox.locals);
|
let lod = self.lod.get_data();
|
||||||
|
renderer.render_skybox(
|
||||||
|
&self.skybox.model,
|
||||||
|
&self.globals,
|
||||||
|
&self.skybox.locals,
|
||||||
|
&lod.map,
|
||||||
|
&lod.horizon,
|
||||||
|
);
|
||||||
|
|
||||||
self.figure_mgr.render_player(
|
self.figure_mgr.render_player(
|
||||||
renderer,
|
renderer,
|
||||||
@ -441,7 +495,7 @@ impl Scene {
|
|||||||
&self.globals,
|
&self.globals,
|
||||||
&self.lights,
|
&self.lights,
|
||||||
&self.shadows,
|
&self.shadows,
|
||||||
self.lod.get_data(),
|
lod,
|
||||||
&self.camera,
|
&self.camera,
|
||||||
scene_data.figure_lod_render_distance,
|
scene_data.figure_lod_render_distance,
|
||||||
);
|
);
|
||||||
@ -451,7 +505,7 @@ impl Scene {
|
|||||||
&self.globals,
|
&self.globals,
|
||||||
&self.lights,
|
&self.lights,
|
||||||
&self.shadows,
|
&self.shadows,
|
||||||
self.lod.get_data(),
|
lod,
|
||||||
self.camera.get_focus_pos(),
|
self.camera.get_focus_pos(),
|
||||||
scene_data.sprite_render_distance,
|
scene_data.sprite_render_distance,
|
||||||
);
|
);
|
||||||
|
@ -206,6 +206,8 @@ impl Scene {
|
|||||||
const VD: f32 = 115.0; // View Distance
|
const VD: f32 = 115.0; // View Distance
|
||||||
// const MAP_BOUNDS: Vec2<f32> = Vec2::new(140.0, 2048.0);
|
// const MAP_BOUNDS: Vec2<f32> = Vec2::new(140.0, 2048.0);
|
||||||
const TIME: f64 = 10.0 * 60.0 * 60.0; //43200.0; // 12 hours*3600 seconds
|
const TIME: f64 = 10.0 * 60.0 * 60.0; //43200.0; // 12 hours*3600 seconds
|
||||||
|
const SHADOW_NEAR: f32 = 1.0;
|
||||||
|
const SHADOW_FAR: f32 = 25.0;
|
||||||
|
|
||||||
if let Err(err) = renderer.update_consts(&mut self.globals, &[Globals::new(
|
if let Err(err) = renderer.update_consts(&mut self.globals, &[Globals::new(
|
||||||
view_mat,
|
view_mat,
|
||||||
@ -218,6 +220,7 @@ impl Scene {
|
|||||||
TIME,
|
TIME,
|
||||||
scene_data.time,
|
scene_data.time,
|
||||||
renderer.get_resolution(),
|
renderer.get_resolution(),
|
||||||
|
Vec2::new(SHADOW_NEAR, SHADOW_FAR),
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
BlockKind::Air,
|
BlockKind::Air,
|
||||||
@ -265,7 +268,13 @@ impl Scene {
|
|||||||
body: Option<humanoid::Body>,
|
body: Option<humanoid::Body>,
|
||||||
loadout: Option<&Loadout>,
|
loadout: Option<&Loadout>,
|
||||||
) {
|
) {
|
||||||
renderer.render_skybox(&self.skybox.model, &self.globals, &self.skybox.locals);
|
renderer.render_skybox(
|
||||||
|
&self.skybox.model,
|
||||||
|
&self.globals,
|
||||||
|
&self.skybox.locals,
|
||||||
|
&self.lod.map,
|
||||||
|
&self.lod.horizon,
|
||||||
|
);
|
||||||
|
|
||||||
if let Some(body) = body {
|
if let Some(body) = body {
|
||||||
let model = &self
|
let model = &self
|
||||||
|
@ -2,7 +2,7 @@ use crate::{
|
|||||||
mesh::Meshable,
|
mesh::Meshable,
|
||||||
render::{
|
render::{
|
||||||
Consts, FluidPipeline, Globals, Instances, Light, Mesh, Model, Renderer, Shadow,
|
Consts, FluidPipeline, Globals, Instances, Light, Mesh, Model, Renderer, Shadow,
|
||||||
SpriteInstance, SpritePipeline, TerrainLocals, TerrainPipeline, Texture,
|
ShadowLocals, SpriteInstance, SpritePipeline, TerrainLocals, TerrainPipeline, Texture,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2191,6 +2191,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
globals: &Consts<Globals>,
|
globals: &Consts<Globals>,
|
||||||
lights: &Consts<Light>,
|
lights: &Consts<Light>,
|
||||||
shadows: &Consts<Shadow>,
|
shadows: &Consts<Shadow>,
|
||||||
|
shadow_mats: &Consts<ShadowLocals>,
|
||||||
lod: &LodData,
|
lod: &LodData,
|
||||||
focus_pos: Vec3<f32>,
|
focus_pos: Vec3<f32>,
|
||||||
) {
|
) {
|
||||||
@ -2205,8 +2206,28 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
})
|
})
|
||||||
.take(self.chunks.len());
|
.take(self.chunks.len());
|
||||||
|
|
||||||
// Opaque
|
// Shadows
|
||||||
for (_, chunk) in chunk_iter.clone() {
|
for (_, chunk) in chunk_iter.clone() {
|
||||||
|
/* if chunk.visible */
|
||||||
|
{
|
||||||
|
renderer.render_shadow(
|
||||||
|
&chunk.opaque_model,
|
||||||
|
globals,
|
||||||
|
&chunk.locals,
|
||||||
|
shadow_mats,
|
||||||
|
lights,
|
||||||
|
shadows,
|
||||||
|
&lod.map,
|
||||||
|
&lod.horizon,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush shadows.
|
||||||
|
renderer.flush_shadows();
|
||||||
|
|
||||||
|
// Terrain
|
||||||
|
for (_, chunk) in chunk_iter {
|
||||||
if chunk.visible {
|
if chunk.visible {
|
||||||
renderer.render_terrain_chunk(
|
renderer.render_terrain_chunk(
|
||||||
&chunk.opaque_model,
|
&chunk.opaque_model,
|
||||||
|
@ -700,6 +700,16 @@ impl PlayState for SessionState {
|
|||||||
localized_strings.log_missing_entries();
|
localized_strings.log_missing_entries();
|
||||||
self.hud.update_language(localized_strings.clone());
|
self.hud.update_language(localized_strings.clone());
|
||||||
},
|
},
|
||||||
|
HudEvent::ChangeLightingMode(new_lighting_mode) => {
|
||||||
|
// Do this first so if it crashes the setting isn't saved :)
|
||||||
|
global_state
|
||||||
|
.window
|
||||||
|
.renderer_mut()
|
||||||
|
.set_lighting_mode(new_lighting_mode)
|
||||||
|
.unwrap();
|
||||||
|
global_state.settings.graphics.lighting_mode = new_lighting_mode;
|
||||||
|
global_state.settings.save_to_file_warn();
|
||||||
|
},
|
||||||
HudEvent::ToggleFullscreen => {
|
HudEvent::ToggleFullscreen => {
|
||||||
global_state
|
global_state
|
||||||
.window
|
.window
|
||||||
@ -751,6 +761,10 @@ impl PlayState for SessionState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let renderer = global_state.window.renderer_mut();
|
let renderer = global_state.window.renderer_mut();
|
||||||
|
|
||||||
|
// Flush renderer to synchronize commands sent on the main encoder with the
|
||||||
|
// start of the shadow encoder.
|
||||||
|
renderer.flush();
|
||||||
// Clear the screen
|
// Clear the screen
|
||||||
renderer.clear();
|
renderer.clear();
|
||||||
// Render the screen using the global renderer
|
// Render the screen using the global renderer
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
hud::{BarNumbers, CrosshairType, Intro, PressBehavior, ShortcutNumbers, XpBar},
|
hud::{BarNumbers, CrosshairType, Intro, PressBehavior, ShortcutNumbers, XpBar},
|
||||||
i18n,
|
i18n,
|
||||||
render::{AaMode, CloudMode, FluidMode},
|
render::{AaMode, CloudMode, FluidMode, LightingMode},
|
||||||
ui::ScaleMode,
|
ui::ScaleMode,
|
||||||
window::{GameInput, KeyMouse},
|
window::{GameInput, KeyMouse},
|
||||||
};
|
};
|
||||||
@ -556,6 +556,7 @@ pub struct GraphicsSettings {
|
|||||||
pub aa_mode: AaMode,
|
pub aa_mode: AaMode,
|
||||||
pub cloud_mode: CloudMode,
|
pub cloud_mode: CloudMode,
|
||||||
pub fluid_mode: FluidMode,
|
pub fluid_mode: FluidMode,
|
||||||
|
pub lighting_mode: LightingMode,
|
||||||
pub window_size: [u16; 2],
|
pub window_size: [u16; 2],
|
||||||
pub fullscreen: bool,
|
pub fullscreen: bool,
|
||||||
pub lod_detail: u32,
|
pub lod_detail: u32,
|
||||||
@ -573,6 +574,7 @@ impl Default for GraphicsSettings {
|
|||||||
aa_mode: AaMode::Fxaa,
|
aa_mode: AaMode::Fxaa,
|
||||||
cloud_mode: CloudMode::Regular,
|
cloud_mode: CloudMode::Regular,
|
||||||
fluid_mode: FluidMode::Shiny,
|
fluid_mode: FluidMode::Shiny,
|
||||||
|
lighting_mode: LightingMode::Ashikmin,
|
||||||
window_size: [1920, 1080],
|
window_size: [1920, 1080],
|
||||||
fullscreen: false,
|
fullscreen: false,
|
||||||
lod_detail: 500,
|
lod_detail: 500,
|
||||||
|
@ -451,6 +451,7 @@ impl Window {
|
|||||||
settings.graphics.aa_mode,
|
settings.graphics.aa_mode,
|
||||||
settings.graphics.cloud_mode,
|
settings.graphics.cloud_mode,
|
||||||
settings.graphics.fluid_mode,
|
settings.graphics.fluid_mode,
|
||||||
|
settings.graphics.lighting_mode,
|
||||||
)?,
|
)?,
|
||||||
window,
|
window,
|
||||||
cursor_grabbed: false,
|
cursor_grabbed: false,
|
||||||
|
Loading…
Reference in New Issue
Block a user