mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Adding shadows, greedy meshing, and more.
This commit is contained in:
parent
eaea83fe6a
commit
618a18c998
41
Cargo.lock
generated
41
Cargo.lock
generated
@ -1274,25 +1274,13 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "euclid"
|
name = "euclid"
|
||||||
version = "0.19.9"
|
version = "0.20.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "596b99621b9477e7a5f94d2d8dd13a9c5c302ac358b822c67a42b6f1054450e1"
|
checksum = "555d51b9a929edb14183fad621e2d5736fc8760707a24246047288d4c142b6bd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"euclid_macros",
|
|
||||||
"num-traits 0.2.11",
|
"num-traits 0.2.11",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "euclid_macros"
|
|
||||||
version = "0.1.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "fdcb84c18ea5037a1c5a23039b4ff29403abce2e0d6b1daa11cf0bde2b30be15"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2 0.4.30",
|
|
||||||
"quote 0.6.13",
|
|
||||||
"syn 0.15.44",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "failure"
|
name = "failure"
|
||||||
version = "0.1.7"
|
version = "0.1.7"
|
||||||
@ -1952,8 +1940,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "guillotiere"
|
name = "guillotiere"
|
||||||
version = "0.4.2"
|
version = "0.5.2"
|
||||||
source = "git+https://github.com/Imberflur/guillotiere#42c298f5bcf0f95f1a004360d05e25ca3711e9ed"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "47065d052e2f000066c4ffbea7051e55bff5c1532c400fc1e269492b2474ccc1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"euclid",
|
"euclid",
|
||||||
"svg_fmt",
|
"svg_fmt",
|
||||||
@ -4417,9 +4406,9 @@ checksum = "da5b4a0c9f3c7c8e891e445a7c776627e208e8bba23ab680798066dd283e6a15"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "svg_fmt"
|
name = "svg_fmt"
|
||||||
version = "0.2.1"
|
version = "0.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "20e5f95e89d737f30cd1f98a9af9a85c2a1cc162cfedfba5a0c54cf92d7206fc"
|
checksum = "8fb1df15f412ee2e9dfc1c504260fa695c1c3f10fe9f4a6ee2d2184d7d6450e2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
@ -4945,9 +4934,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vek"
|
name = "vek"
|
||||||
version = "0.10.0"
|
version = "0.11.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4c98f7e1c1400d5b1704baee82cbc56a3fde406769555ead0f2306e43ebab967"
|
checksum = "2657d8704e5e0be82b60157c8dbc71a269273ad766984508fdc54030a0690c4d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"approx 0.3.2",
|
"approx 0.3.2",
|
||||||
"num-integer",
|
"num-integer",
|
||||||
@ -4981,7 +4970,7 @@ dependencies = [
|
|||||||
"rayon",
|
"rayon",
|
||||||
"specs",
|
"specs",
|
||||||
"uvth",
|
"uvth",
|
||||||
"vek 0.10.0",
|
"vek 0.11.2",
|
||||||
"veloren-common",
|
"veloren-common",
|
||||||
"veloren-world",
|
"veloren-world",
|
||||||
]
|
]
|
||||||
@ -5016,7 +5005,7 @@ dependencies = [
|
|||||||
"specs",
|
"specs",
|
||||||
"specs-idvs",
|
"specs-idvs",
|
||||||
"sum_type",
|
"sum_type",
|
||||||
"vek 0.10.0",
|
"vek 0.11.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -5045,7 +5034,7 @@ dependencies = [
|
|||||||
"specs",
|
"specs",
|
||||||
"specs-idvs",
|
"specs-idvs",
|
||||||
"uvth",
|
"uvth",
|
||||||
"vek 0.10.0",
|
"vek 0.11.2",
|
||||||
"veloren-common",
|
"veloren-common",
|
||||||
"veloren-world",
|
"veloren-world",
|
||||||
]
|
]
|
||||||
@ -5083,6 +5072,7 @@ dependencies = [
|
|||||||
"fern",
|
"fern",
|
||||||
"gfx",
|
"gfx",
|
||||||
"gfx_device_gl",
|
"gfx_device_gl",
|
||||||
|
"gfx_gl",
|
||||||
"gfx_window_glutin",
|
"gfx_window_glutin",
|
||||||
"gilrs",
|
"gilrs",
|
||||||
"git2",
|
"git2",
|
||||||
@ -5103,7 +5093,7 @@ dependencies = [
|
|||||||
"specs-idvs",
|
"specs-idvs",
|
||||||
"treeculler",
|
"treeculler",
|
||||||
"uvth",
|
"uvth",
|
||||||
"vek 0.10.0",
|
"vek 0.11.2",
|
||||||
"veloren-client",
|
"veloren-client",
|
||||||
"veloren-common",
|
"veloren-common",
|
||||||
"veloren-server",
|
"veloren-server",
|
||||||
@ -5119,6 +5109,7 @@ dependencies = [
|
|||||||
"arr_macro",
|
"arr_macro",
|
||||||
"bincode",
|
"bincode",
|
||||||
"bitvec",
|
"bitvec",
|
||||||
|
"criterion",
|
||||||
"fxhash",
|
"fxhash",
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
"image",
|
"image",
|
||||||
@ -5138,7 +5129,7 @@ dependencies = [
|
|||||||
"roots",
|
"roots",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
"vek 0.10.0",
|
"vek 0.11.2",
|
||||||
"veloren-common",
|
"veloren-common",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -561,5 +561,33 @@
|
|||||||
"generic": "Reddragon"
|
"generic": "Reddragon"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"object": {
|
||||||
|
"body": {
|
||||||
|
"keyword": "object",
|
||||||
|
"names": []
|
||||||
|
},
|
||||||
|
"species": null
|
||||||
|
},
|
||||||
|
"fish_small": {
|
||||||
|
"body": {
|
||||||
|
"keyword": "fish_small",
|
||||||
|
"names": []
|
||||||
|
},
|
||||||
|
"species": null
|
||||||
|
},
|
||||||
|
"fish_medium": {
|
||||||
|
"body": {
|
||||||
|
"keyword": "fish_medium",
|
||||||
|
"names": []
|
||||||
|
},
|
||||||
|
"species": null
|
||||||
|
},
|
||||||
|
"bird_small": {
|
||||||
|
"body": {
|
||||||
|
"keyword": "bird_small",
|
||||||
|
"names": []
|
||||||
|
},
|
||||||
|
"species": null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,16 +17,40 @@
|
|||||||
#include <globals.glsl>
|
#include <globals.glsl>
|
||||||
|
|
||||||
in vec3 f_pos;
|
in vec3 f_pos;
|
||||||
in vec3 f_col;
|
// in float dummy;
|
||||||
in float f_ao;
|
// in vec3 f_col;
|
||||||
|
// in float f_ao;
|
||||||
|
// flat in uint f_pos_norm;
|
||||||
flat in vec3 f_norm;
|
flat in vec3 f_norm;
|
||||||
|
/*centroid */in vec2 f_uv_pos;
|
||||||
// in float f_alt;
|
// in float f_alt;
|
||||||
// in vec4 f_shadow;
|
// in vec4 f_shadow;
|
||||||
|
// in vec3 light_pos[2];
|
||||||
|
|
||||||
|
// #if (SHADOW_MODE == SHADOW_MODE_MAP)
|
||||||
|
// in vec4 sun_pos;
|
||||||
|
// #elif (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_NONE)
|
||||||
|
// const vec4 sun_pos = vec4(0.0);
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
uniform sampler2D t_col_light;
|
||||||
|
|
||||||
|
//struct ShadowLocals {
|
||||||
|
// mat4 shadowMatrices;
|
||||||
|
// mat4 texture_mat;
|
||||||
|
//};
|
||||||
|
//
|
||||||
|
//layout (std140)
|
||||||
|
//uniform u_light_shadows {
|
||||||
|
// ShadowLocals shadowMats[/*MAX_LAYER_FACES*/192];
|
||||||
|
//};
|
||||||
|
|
||||||
layout (std140)
|
layout (std140)
|
||||||
uniform u_locals {
|
uniform u_locals {
|
||||||
mat4 model_mat;
|
mat4 model_mat;
|
||||||
vec4 model_col;
|
vec4 model_col;
|
||||||
|
ivec4 atlas_offs;
|
||||||
|
vec3 model_pos;
|
||||||
// bit 0 - is player
|
// bit 0 - is player
|
||||||
// bit 1-31 - unused
|
// bit 1-31 - unused
|
||||||
int flags;
|
int flags;
|
||||||
@ -34,6 +58,7 @@ uniform u_locals {
|
|||||||
|
|
||||||
struct BoneData {
|
struct BoneData {
|
||||||
mat4 bone_mat;
|
mat4 bone_mat;
|
||||||
|
mat4 normals_mat;
|
||||||
};
|
};
|
||||||
|
|
||||||
layout (std140)
|
layout (std140)
|
||||||
@ -48,28 +73,81 @@ uniform u_bones {
|
|||||||
out vec4 tgt_color;
|
out vec4 tgt_color;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
// vec2 texSize = textureSize(t_col_light, 0);
|
||||||
|
// vec4 col_light = texture(t_col_light, (f_uv_pos + 0.5) / texSize);
|
||||||
|
// vec3 f_col = col_light.rgb;
|
||||||
|
// float f_ao = col_light.a;
|
||||||
|
|
||||||
|
// vec4 f_col_light = texture(t_col_light, (f_uv_pos + 0.5) / textureSize(t_col_light, 0));
|
||||||
|
// vec3 f_col = f_col_light.rgb;
|
||||||
|
// float f_ao = f_col_light.a;
|
||||||
|
|
||||||
|
// vec2 f_uv_pos = f_uv_pos + atlas_offs.xy;
|
||||||
|
vec4 f_col_light = texelFetch(t_col_light, ivec2(f_uv_pos)/* + uv_delta*//* - f_norm * 0.00001*/, 0);
|
||||||
|
// vec4 f_col_light = texelFetch(t_col_light, ivec2(int(f_uv_pos.x), int(f_uv_pos.y)/* + uv_delta*//* - f_norm * 0.00001*/), 0);
|
||||||
|
vec3 f_col = /*linear_to_srgb*//*srgb_to_linear*/(f_col_light.rgb);
|
||||||
|
// vec3 f_col = vec3(1.0);
|
||||||
|
// vec2 texSize = textureSize(t_col_light, 0);
|
||||||
|
float f_ao = texture(t_col_light, (f_uv_pos + 0.5) / textureSize(t_col_light, 0)).a;//1.0;//f_col_light.a * 4.0;// f_light = float(v_col_light & 0x3Fu) / 64.0;
|
||||||
|
// float /*f_light*/f_ao = textureProj(t_col_light, vec3(f_uv_pos, texSize)).a;//1.0;//f_col_light.a * 4.0;// f_light = float(v_col_light & 0x3Fu) / 64.0;
|
||||||
|
|
||||||
|
// vec3 my_chunk_pos = (vec3((uvec3(f_pos_norm) >> uvec3(0, 9, 18)) & uvec3(0x1FFu)) - 256.0) / 2.0;
|
||||||
|
// tgt_color = vec4(hash(floor(vec4(my_chunk_pos.x, 0, 0, 0))), hash(floor(vec4(0, my_chunk_pos.y, 0, 1))), hash(floor(vec4(0, 0, my_chunk_pos.z, 2))), 1.0);
|
||||||
|
// float f_ao = 0;
|
||||||
|
// tgt_color = vec4(vec3(f_ao), 1.0);
|
||||||
|
// tgt_color = vec4(f_col, 1.0);
|
||||||
|
// return;
|
||||||
|
|
||||||
|
// vec3 du = dFdx(f_pos);
|
||||||
|
// vec3 dv = dFdy(f_pos);
|
||||||
|
// vec3 f_norm = normalize(cross(du, dv));
|
||||||
|
|
||||||
|
// vec4 light_pos[2];
|
||||||
|
//#if (SHADOW_MODE == SHADOW_MODE_MAP)
|
||||||
|
// // for (uint i = 0u; i < light_shadow_count.z; ++i) {
|
||||||
|
// // light_pos[i] = /*vec3(*/shadowMats[i].texture_mat * vec4(f_pos, 1.0)/*)*/;
|
||||||
|
// // }
|
||||||
|
// vec4 sun_pos = /*vec3(*/shadowMats[0].texture_mat * vec4(f_pos, 1.0)/*)*/;
|
||||||
|
//#elif (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_NONE)
|
||||||
|
// vec4 sun_pos = vec4(0.0);
|
||||||
|
//#endif
|
||||||
|
|
||||||
vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz);
|
vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz);
|
||||||
// vec4 vert_pos4 = view_mat * vec4(f_pos, 1.0);
|
// vec4 vert_pos4 = view_mat * vec4(f_pos, 1.0);
|
||||||
// vec3 view_dir = normalize(-vec3(vert_pos4)/* / vert_pos4.w*/);
|
// vec3 view_dir = normalize(-vec3(vert_pos4)/* / vert_pos4.w*/);
|
||||||
vec3 view_dir = -cam_to_frag;
|
vec3 view_dir = -cam_to_frag;
|
||||||
|
|
||||||
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); */
|
||||||
// float sun_light = get_sun_brightness(sun_dir);
|
// float sun_light = get_sun_brightness(sun_dir);
|
||||||
// float moon_light = get_moon_brightness(moon_dir);
|
// float moon_light = get_moon_brightness(moon_dir);
|
||||||
/* float sun_shade_frac = horizon_at(f_pos, sun_dir);
|
/* float sun_shade_frac = horizon_at(f_pos, sun_dir);
|
||||||
float moon_shade_frac = horizon_at(f_pos, moon_dir); */
|
float moon_shade_frac = horizon_at(f_pos, moon_dir); */
|
||||||
|
#if (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_MAP || FLUID_MODE == FLUID_MODE_SHINY)
|
||||||
float f_alt = alt_at(f_pos.xy);
|
float f_alt = alt_at(f_pos.xy);
|
||||||
|
#elif (SHADOW_MODE == SHADOW_MODE_NONE || FLUID_MODE == FLUID_MODE_CHEAP)
|
||||||
|
float f_alt = f_pos.z;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_MAP)
|
||||||
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 sun_shade_frac = horizon_at2(f_shadow, f_alt, f_pos, sun_dir);
|
float sun_shade_frac = horizon_at2(f_shadow, f_alt, f_pos, sun_dir);
|
||||||
float moon_shade_frac = horizon_at2(f_shadow, f_alt, f_pos, moon_dir);
|
#elif (SHADOW_MODE == SHADOW_MODE_NONE)
|
||||||
|
float sun_shade_frac = 1.0;//horizon_at2(f_shadow, f_alt, f_pos, sun_dir);
|
||||||
|
#endif
|
||||||
|
float moon_shade_frac = 1.0;// horizon_at2(f_shadow, f_alt, f_pos, moon_dir);
|
||||||
// Globbal illumination "estimate" used to light the faces of voxels which are parallel to the sun or moon (which is a very common occurrence).
|
// Globbal illumination "estimate" used to light the faces of voxels which are parallel to the sun or moon (which is a very common occurrence).
|
||||||
// Will be attenuated by k_d, which is assumed to carry any additional ambient occlusion information (e.g. about shadowing).
|
// Will be attenuated by k_d, which is assumed to carry any additional ambient occlusion information (e.g. about shadowing).
|
||||||
// float ambient_sides = clamp(mix(0.5, 0.0, abs(dot(-f_norm, sun_dir)) * 10000.0), 0.0, 0.5);
|
// float ambient_sides = clamp(mix(0.5, 0.0, abs(dot(-f_norm, sun_dir)) * 10000.0), 0.0, 0.5);
|
||||||
// NOTE: current assumption is that moon and sun shouldn't be out at the sae time.
|
// NOTE: current assumption is that moon and sun shouldn't be out at the sae time.
|
||||||
// This assumption is (or can at least easily be) wrong, but if we pretend it's true we avoids having to explicitly pass in a separate shadow
|
// This assumption is (or can at least easily be) wrong, but if we pretend it's true we avoids having to explicitly pass in a separate shadow
|
||||||
// for the sun and moon (since they have different brightnesses / colors so the shadows shouldn't attenuate equally).
|
// for the sun and moon (since they have different brightnesses / colors so the shadows shouldn't attenuate equally).
|
||||||
float shade_frac = /*1.0;*/sun_shade_frac + moon_shade_frac;
|
// float shade_frac = /*1.0;*/sun_shade_frac + moon_shade_frac;
|
||||||
|
|
||||||
|
// DirectionalLight sun_info = get_sun_info(sun_dir, sun_shade_frac, light_pos);
|
||||||
|
float point_shadow = shadow_at(f_pos, f_norm);
|
||||||
|
DirectionalLight sun_info = get_sun_info(sun_dir, point_shadow * sun_shade_frac, /*sun_pos*/f_pos);
|
||||||
|
DirectionalLight moon_info = get_moon_info(moon_dir, point_shadow * moon_shade_frac/*, light_pos*/);
|
||||||
|
|
||||||
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;
|
||||||
@ -86,20 +164,22 @@ void main() {
|
|||||||
|
|
||||||
vec3 emitted_light, reflected_light;
|
vec3 emitted_light, reflected_light;
|
||||||
|
|
||||||
float point_shadow = shadow_at(f_pos, f_norm);
|
|
||||||
// vec3 light_frac = /*vec3(1.0);*//*vec3(max(dot(f_norm, -sun_dir) * 0.5 + 0.5, 0.0));*/light_reflection_factor(f_norm, view_dir, vec3(0, 0, -1.0), vec3(1.0), vec3(R_s), alpha);
|
// vec3 light_frac = /*vec3(1.0);*//*vec3(max(dot(f_norm, -sun_dir) * 0.5 + 0.5, 0.0));*/light_reflection_factor(f_norm, view_dir, vec3(0, 0, -1.0), vec3(1.0), vec3(R_s), alpha);
|
||||||
// vec3 point_light = light_at(f_pos, f_norm);
|
// vec3 point_light = light_at(f_pos, f_norm);
|
||||||
// vec3 light, diffuse_light, ambient_light;
|
// vec3 light, diffuse_light, ambient_light;
|
||||||
//get_sun_diffuse(f_norm, time_of_day.x, view_dir, k_a * point_shadow * (shade_frac * 0.5 + light_frac * 0.5), k_d * point_shadow * shade_frac, k_s * point_shadow * shade_frac, alpha, emitted_light, reflected_light);
|
//get_sun_diffuse(f_norm, time_of_day.x, view_dir, k_a * point_shadow * (shade_frac * 0.5 + light_frac * 0.5), k_d * point_shadow * shade_frac, k_s * point_shadow * shade_frac, alpha, emitted_light, reflected_light);
|
||||||
float max_light = 0.0;
|
float max_light = 0.0;
|
||||||
max_light += get_sun_diffuse2(f_norm, sun_dir, moon_dir, view_dir, k_a/* * (shade_frac * 0.5 + light_frac * 0.5)*/, k_d, k_s, alpha, emitted_light, reflected_light);
|
max_light += get_sun_diffuse2(sun_info, moon_info, f_norm, view_dir, k_a/* * (shade_frac * 0.5 + light_frac * 0.5)*/, k_d, k_s, alpha, emitted_light, reflected_light);
|
||||||
reflected_light *= point_shadow * shade_frac;
|
// reflected_light *= point_shadow * shade_frac;
|
||||||
emitted_light *= point_shadow * max(shade_frac, MIN_SHADOW);
|
// emitted_light *= point_shadow * max(shade_frac, MIN_SHADOW);
|
||||||
max_light *= point_shadow * shade_frac;
|
// max_light *= point_shadow * shade_frac;
|
||||||
|
// reflected_light *= point_shadow;
|
||||||
|
// emitted_light *= point_shadow;
|
||||||
|
// max_light *= point_shadow;
|
||||||
|
|
||||||
max_light += lights_at(f_pos, f_norm, view_dir, k_a, k_d, k_s, alpha, emitted_light, reflected_light);
|
max_light += lights_at(f_pos, f_norm, view_dir, k_a, k_d, k_s, alpha, emitted_light, reflected_light);
|
||||||
|
|
||||||
float ao = /*pow(f_ao, 0.5)*/f_ao * 0.85 + 0.15;
|
float ao = f_ao;//0.25 + f_ao * 0.75; ///*pow(f_ao, 0.5)*/f_ao * 0.85 + 0.15;
|
||||||
|
|
||||||
reflected_light *= ao;
|
reflected_light *= ao;
|
||||||
emitted_light *= ao;
|
emitted_light *= ao;
|
||||||
@ -118,21 +198,25 @@ void main() {
|
|||||||
// 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, view_dir, surf_color * emitted_light, surf_color * reflected_light);
|
surf_color = illuminate(max_light, view_dir, surf_color * emitted_light, surf_color * reflected_light);
|
||||||
|
|
||||||
|
#if (CLOUD_MODE == CLOUD_MODE_REGULAR)
|
||||||
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;
|
||||||
vec3 fog_color = get_sky_color(cam_to_frag/*view_dir*/, time_of_day.x, cam_pos.xyz, f_pos, 0.5, true, clouds);
|
vec3 fog_color = get_sky_color(cam_to_frag/*view_dir*/, time_of_day.x, cam_pos.xyz, f_pos, 0.5, false, clouds);
|
||||||
vec3 color = mix(mix(surf_color, fog_color, fog_level), clouds.rgb, clouds.a);
|
vec3 color = mix(mix(surf_color, fog_color, fog_level), clouds.rgb, clouds.a);
|
||||||
|
#elif (CLOUD_MODE == CLOUD_MODE_NONE)
|
||||||
|
vec3 color = surf_color;
|
||||||
|
#endif
|
||||||
|
|
||||||
if ((flags & 1) == 1 && int(cam_mode) == 1) {
|
// if ((flags & 1) == 1 && int(cam_mode) == 1) {
|
||||||
float distance = distance(vec3(cam_pos), focus_pos.xyz) - 2;
|
// float distance = distance(vec3(cam_pos), focus_pos.xyz) - 2;
|
||||||
|
|
||||||
float opacity = clamp(distance / distance_divider, 0, 1);
|
// float opacity = clamp(distance / distance_divider, 0, 1);
|
||||||
|
|
||||||
if(threshold_matrix[int(gl_FragCoord.x) % 4][int(gl_FragCoord.y) % 4] > opacity) {
|
// // if(threshold_matrix[int(gl_FragCoord.x) % 4][int(gl_FragCoord.y) % 4] > opacity) {
|
||||||
discard;
|
// // discard;
|
||||||
return;
|
// // return;
|
||||||
}
|
// // }
|
||||||
}
|
// }
|
||||||
|
|
||||||
tgt_color = vec4(color, 1.0);
|
tgt_color = vec4(color, 1.0);
|
||||||
}
|
}
|
||||||
|
@ -16,14 +16,19 @@
|
|||||||
#include <lod.glsl>
|
#include <lod.glsl>
|
||||||
|
|
||||||
in uint v_pos_norm;
|
in uint v_pos_norm;
|
||||||
in vec3 v_norm;
|
in uint v_atlas_pos;
|
||||||
in uint v_col;
|
|
||||||
in uint v_ao_bone;
|
// in vec3 v_norm;
|
||||||
|
/* in uint v_col;
|
||||||
|
// out vec3 light_pos[2];
|
||||||
|
in uint v_ao_bone; */
|
||||||
|
|
||||||
layout (std140)
|
layout (std140)
|
||||||
uniform u_locals {
|
uniform u_locals {
|
||||||
mat4 model_mat;
|
mat4 model_mat;
|
||||||
vec4 model_col;
|
vec4 model_col;
|
||||||
|
ivec4 atlas_offs;
|
||||||
|
vec3 model_pos;
|
||||||
// bit 0 - is player
|
// bit 0 - is player
|
||||||
// bit 1-31 - unused
|
// bit 1-31 - unused
|
||||||
int flags;
|
int flags;
|
||||||
@ -31,6 +36,7 @@ uniform u_locals {
|
|||||||
|
|
||||||
struct BoneData {
|
struct BoneData {
|
||||||
mat4 bone_mat;
|
mat4 bone_mat;
|
||||||
|
mat4 normals_mat;
|
||||||
};
|
};
|
||||||
|
|
||||||
layout (std140)
|
layout (std140)
|
||||||
@ -39,46 +45,96 @@ uniform u_bones {
|
|||||||
BoneData bones[16];
|
BoneData bones[16];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//struct ShadowLocals {
|
||||||
|
// mat4 shadowMatrices;
|
||||||
|
// mat4 texture_mat;
|
||||||
|
//};
|
||||||
|
//
|
||||||
|
//layout (std140)
|
||||||
|
//uniform u_light_shadows {
|
||||||
|
// ShadowLocals shadowMats[/*MAX_LAYER_FACES*/192];
|
||||||
|
//};
|
||||||
|
|
||||||
out vec3 f_pos;
|
out vec3 f_pos;
|
||||||
out vec3 f_col;
|
// flat out uint f_pos_norm;
|
||||||
out float f_ao;
|
|
||||||
flat out vec3 f_norm;
|
flat out vec3 f_norm;
|
||||||
|
// float dummy;
|
||||||
|
/*centroid */out vec2 f_uv_pos;
|
||||||
|
// out vec3 f_col;
|
||||||
|
// out float f_ao;
|
||||||
// out float f_alt;
|
// out float f_alt;
|
||||||
// out vec4 f_shadow;
|
// out vec4 f_shadow;
|
||||||
|
|
||||||
|
// #if (SHADOW_MODE == SHADOW_MODE_MAP)
|
||||||
|
// out vec4 sun_pos;
|
||||||
|
// #endif
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
// Pre-calculate bone matrix
|
// Pre-calculate bone matrix
|
||||||
uint bone_idx = (v_ao_bone >> 2) & 0x3Fu;
|
/* uint bone_idx = (v_ao_bone >> 2) & 0x3Fu; */
|
||||||
mat4 combined_mat = model_mat * bones[bone_idx].bone_mat;
|
uint bone_idx = (v_pos_norm >> 27) & 0xFu;
|
||||||
|
BoneData bone_data = bones[bone_idx];
|
||||||
|
mat4 bone_mat = bone_data.bone_mat;
|
||||||
|
mat4 combined_mat = /*model_mat * */bone_mat;
|
||||||
|
|
||||||
vec3 pos = (vec3((uvec3(v_pos_norm) >> uvec3(0, 9, 18)) & uvec3(0x1FFu)) - 256.0) / 2.0;
|
vec3 pos = (vec3((uvec3(v_pos_norm) >> uvec3(0, 9, 18)) & uvec3(0x1FFu)) - 256.0) / 2.0;
|
||||||
|
|
||||||
|
// vec4 bone_pos = bones[bone_idx].bone_mat * vec4(pos, 1);
|
||||||
|
|
||||||
f_pos = (
|
f_pos = (
|
||||||
combined_mat *
|
combined_mat *
|
||||||
vec4(pos, 1)).xyz;
|
vec4(pos, 1.0)
|
||||||
|
).xyz + (model_pos - focus_off.xyz);
|
||||||
|
|
||||||
f_pos.z -= 25.0 * pow(distance(focus_pos.xy, f_pos.xy) / view_distance.x, 20.0);
|
/* f_pos.z -= 25.0 * pow(distance(focus_pos.xy, f_pos.xy) / view_distance.x, 20.0); */
|
||||||
|
|
||||||
f_col = srgb_to_linear(vec3((uvec3(v_col) >> uvec3(0, 8, 16)) & uvec3(0xFFu)) / 255.0);
|
f_uv_pos = vec2((uvec2(v_atlas_pos) >> uvec2(2, 17)) & uvec2(0x7FFFu, 0x7FFFu));
|
||||||
|
|
||||||
f_ao = float(v_ao_bone & 0x3u) / 4.0;
|
// f_col = srgb_to_linear(vec3((uvec3(v_col) >> uvec3(0, 8, 16)) & uvec3(0xFFu)) / 255.0);
|
||||||
|
// f_col = vec3(1.0);
|
||||||
|
|
||||||
|
// f_ao = float(v_ao_bone & 0x3u) / 4.0;
|
||||||
|
// f_ao = 1.0;
|
||||||
|
/* for (uint i = 0u; i < light_shadow_count.z; ++i) {
|
||||||
|
light_pos[i] = vec3(shadowMats[i].texture_mat * vec4(f_pos, 1.0));
|
||||||
|
} */
|
||||||
|
|
||||||
// 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));
|
// uint normal_idx = ((v_atlas_pos & 3u) << 1u) | (v_pos_norm >> 31u);
|
||||||
vec3 norm = normals[(v_pos_norm >> 29) & 0x7u];
|
// const 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 norm = normals[normal_idx];
|
||||||
|
uint axis_idx = v_atlas_pos & 3u;
|
||||||
|
|
||||||
// Calculate normal here rather than for each pixel in the fragment shader
|
vec3 norm = bone_data.normals_mat[axis_idx].xyz;
|
||||||
f_norm = normalize((
|
// norm = normalize(norm);
|
||||||
combined_mat *
|
// vec3 norm = norm_mat * vec4(uvec3(1 << axis_idx) & uvec3(0x1u, 0x3u, 0x7u), 1);
|
||||||
vec4(norm, 0.0)
|
|
||||||
).xyz);
|
// // Calculate normal here rather than for each pixel in the fragment shader
|
||||||
|
// f_norm = normalize((
|
||||||
|
// combined_mat *
|
||||||
|
// vec4(norm, 0)
|
||||||
|
// ).xyz);
|
||||||
|
f_norm = mix(-norm, norm, v_pos_norm >> 31u);
|
||||||
|
|
||||||
|
// #if (SHADOW_MODE == SHADOW_MODE_MAP)
|
||||||
|
// // for (uint i = 0u; i < light_shadow_count.z; ++i) {
|
||||||
|
// // light_pos[i] = /*vec3(*/shadowMats[i].texture_mat * vec4(f_pos, 1.0)/*)*/;
|
||||||
|
// // }
|
||||||
|
// sun_pos = /*vec3(*/shadowMats[0].texture_mat * vec4(f_pos, 1.0)/*)*/;
|
||||||
|
// // #elif (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_NONE)
|
||||||
|
// // vec4 sun_pos = vec4(0.0);
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// f_pos_norm = v_pos_norm;
|
||||||
|
|
||||||
// Also precalculate shadow texture and estimated terrain altitude.
|
// Also precalculate shadow texture and estimated terrain altitude.
|
||||||
// f_alt = alt_at(f_pos.xy);
|
// f_alt = alt_at(f_pos.xy);
|
||||||
// f_shadow = textureBicubic(t_horizon, pos_to_tex(f_pos.xy));
|
// f_shadow = textureBicubic(t_horizon, pos_to_tex(f_pos.xy));
|
||||||
|
|
||||||
gl_Position = all_mat * vec4(f_pos, 1);
|
gl_Position = all_mat/*shadowMats[0].shadowMatrices*/ * vec4(f_pos, 1);
|
||||||
// gl_Position.z = -gl_Position.z / gl_Position.w;
|
// gl_Position.z = -gl_Position.z / 100.0 / gl_Position.w;
|
||||||
// gl_Position.z = -gl_Position.z / 100.0;
|
// gl_Position.z = -gl_Position.z / 100.0;
|
||||||
gl_Position.z = -1000.0 / (gl_Position.z + 10000.0);
|
// gl_Position.z = gl_Position.z / 100.0;
|
||||||
|
// gl_Position.z = -gl_Position.z;
|
||||||
|
// gl_Position.z = -1000.0 / (gl_Position.z + 10000.0);
|
||||||
}
|
}
|
||||||
|
@ -23,14 +23,25 @@
|
|||||||
|
|
||||||
in vec3 f_pos;
|
in vec3 f_pos;
|
||||||
flat in uint f_pos_norm;
|
flat in uint f_pos_norm;
|
||||||
in vec3 f_col;
|
// in vec3 f_col;
|
||||||
in float f_light;
|
// in float f_light;
|
||||||
|
// in vec3 light_pos[2];
|
||||||
|
|
||||||
|
// struct ShadowLocals {
|
||||||
|
// mat4 shadowMatrices;
|
||||||
|
// mat4 texture_mat;
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// layout (std140)
|
||||||
|
// uniform u_light_shadows {
|
||||||
|
// ShadowLocals shadowMats[/*MAX_LAYER_FACES*/192];
|
||||||
|
// };
|
||||||
|
|
||||||
layout (std140)
|
layout (std140)
|
||||||
uniform u_locals {
|
uniform u_locals {
|
||||||
vec3 model_offs;
|
vec3 model_offs;
|
||||||
float load_time;
|
float load_time;
|
||||||
|
ivec4 atlas_offs;
|
||||||
};
|
};
|
||||||
|
|
||||||
uniform sampler2D t_waves;
|
uniform sampler2D t_waves;
|
||||||
@ -42,33 +53,59 @@ out vec4 tgt_color;
|
|||||||
#include <lod.glsl>
|
#include <lod.glsl>
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
// First 3 normals are negative, next 3 are positive
|
// tgt_color = vec4(1.0 - MU_WATER, 1.0);
|
||||||
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));
|
// return;
|
||||||
|
// 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));
|
||||||
|
|
||||||
// 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[norm_axis + norm_dir];
|
vec3 f_norm = normals[norm_axis + norm_dir];
|
||||||
|
|
||||||
|
// vec4 light_pos[2];
|
||||||
|
// #if (SHADOW_MODE == SHADOW_MODE_MAP)
|
||||||
|
// // for (uint i = 0u; i < light_shadow_count.z; ++i) {
|
||||||
|
// // light_pos[i] = /*vec3(*/shadowMats[i].texture_mat * vec4(f_pos, 1.0)/*)*/;
|
||||||
|
// // }
|
||||||
|
// vec4 sun_pos = /*vec3(*/shadowMats[0].texture_mat * vec4(f_pos, 1.0)/*)*/;
|
||||||
|
// #elif (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_NONE)
|
||||||
|
// vec4 sun_pos = vec4(0.0);
|
||||||
|
// #endif
|
||||||
|
|
||||||
vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz);
|
vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz);
|
||||||
// vec4 vert_pos4 = view_mat * vec4(f_pos, 1.0);
|
// vec4 vert_pos4 = view_mat * vec4(f_pos, 1.0);
|
||||||
// vec3 view_dir = normalize(-vec3(vert_pos4)/* / vert_pos4.w*/);
|
// vec3 view_dir = normalize(-vec3(vert_pos4)/* / vert_pos4.w*/);
|
||||||
vec3 view_dir = -cam_to_frag;
|
vec3 view_dir = -cam_to_frag;
|
||||||
// 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));
|
||||||
/*const */vec3 water_color = 1.0 - MU_WATER;//srgb_to_linear(vec3(0.2, 0.5, 1.0));
|
/*const */vec3 water_color = (1.0 - MU_WATER) * MU_SCATTER;//srgb_to_linear(vec3(0.2, 0.5, 1.0));
|
||||||
// /*const */vec3 water_color = srgb_to_linear(vec3(0.0, 0.25, 0.5));
|
// /*const */vec3 water_color = srgb_to_linear(vec3(0.0, 0.25, 0.5));
|
||||||
|
|
||||||
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); */
|
||||||
|
#if (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_MAP || FLUID_MODE == FLUID_MODE_SHINY)
|
||||||
float f_alt = alt_at(f_pos.xy);
|
float f_alt = alt_at(f_pos.xy);
|
||||||
|
#elif (SHADOW_MODE == SHADOW_MODE_NONE || FLUID_MODE == FLUID_MODE_CHEAP)
|
||||||
|
float f_alt = f_pos.z;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_MAP)
|
||||||
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 sun_shade_frac = horizon_at2(f_shadow, f_alt, f_pos, sun_dir);
|
float sun_shade_frac = horizon_at2(f_shadow, f_alt, f_pos, sun_dir);
|
||||||
float moon_shade_frac = horizon_at2(f_shadow, f_alt, f_pos, moon_dir);
|
#elif (SHADOW_MODE == SHADOW_MODE_NONE)
|
||||||
|
float sun_shade_frac = 1.0;//horizon_at2(f_shadow, f_alt, f_pos, sun_dir);
|
||||||
|
#endif
|
||||||
|
float moon_shade_frac = 1.0;//horizon_at2(f_shadow, f_alt, f_pos, moon_dir);
|
||||||
// float sun_shade_frac = horizon_at(/*f_shadow, f_pos.z, */f_pos, sun_dir);
|
// float sun_shade_frac = horizon_at(/*f_shadow, f_pos.z, */f_pos, sun_dir);
|
||||||
// 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;
|
||||||
|
|
||||||
|
// DirectionalLight sun_info = get_sun_info(sun_dir, sun_shade_frac, light_pos);
|
||||||
|
float point_shadow = shadow_at(f_pos, f_norm);
|
||||||
|
DirectionalLight sun_info = get_sun_info(sun_dir, point_shadow * sun_shade_frac, /*sun_pos*/f_pos);
|
||||||
|
DirectionalLight moon_info = get_moon_info(moon_dir, point_shadow * moon_shade_frac/*, light_pos*/);
|
||||||
|
|
||||||
float fluid_alt = f_pos.z;//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);
|
||||||
|
|
||||||
@ -96,41 +133,44 @@ void main() {
|
|||||||
|
|
||||||
vec3 emitted_light, reflected_light;
|
vec3 emitted_light, reflected_light;
|
||||||
|
|
||||||
// float point_shadow = shadow_at(f_pos, f_norm);
|
// float point_shadow = shadow_at(f_pos, f_norm);
|
||||||
// vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz);
|
// vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz);
|
||||||
// vec3 emitted_light, reflected_light;
|
// vec3 emitted_light, reflected_light;
|
||||||
// vec3 light, diffuse_light, ambient_light;
|
// vec3 light, diffuse_light, ambient_light;
|
||||||
float point_shadow = shadow_at(f_pos,f_norm);
|
|
||||||
// Squared to account for prior saturation.
|
// Squared to account for prior saturation.
|
||||||
float f_light = pow(f_light, 1.5);
|
// float f_light = 1.0;// pow(f_light, 1.5);
|
||||||
// float vert_light = f_light;
|
// float vert_light = f_light;
|
||||||
// vec3 light_frac = /*vec3(1.0);*/light_reflection_factor(f_norm/*vec3(0, 0, 1.0)*/, view_dir, vec3(0, 0, -1.0), vec3(1.0), vec3(R_s), alpha);
|
// 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 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/*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);
|
max_light += get_sun_diffuse2(sun_info, moon_info, f_norm, /*time_of_day.x*//*-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, f_norm, 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;
|
||||||
// get_sun_diffuse(f_norm, time_of_day.x, light, diffuse_light, ambient_light, 0.0);
|
// reflected_light *= f_light * point_shadow;
|
||||||
// diffuse_light *= f_light * point_shadow;
|
// emitted_light *= f_light * point_shadow;
|
||||||
// ambient_light *= f_light, point_shadow;
|
// max_light *= f_light * point_shadow;
|
||||||
// vec3 point_light = light_at(f_pos, f_norm);
|
// get_sun_diffuse(f_norm, time_of_day.x, light, diffuse_light, ambient_light, 0.0);
|
||||||
// light += point_light;
|
// diffuse_light *= f_light * point_shadow;
|
||||||
// diffuse_light += point_light;
|
// ambient_light *= f_light, point_shadow;
|
||||||
|
// vec3 point_light = light_at(f_pos, f_norm);
|
||||||
|
// light += point_light;
|
||||||
|
// diffuse_light += point_light;
|
||||||
// reflected_light += point_light;
|
// reflected_light += point_light;
|
||||||
// vec3 surf_color = srgb_to_linear(vec3(0.4, 0.7, 2.0)) * light * diffuse_light * ambient_light;
|
// vec3 surf_color = srgb_to_linear(vec3(0.4, 0.7, 2.0)) * light * diffuse_light * ambient_light;
|
||||||
|
|
||||||
// lights_at(f_pos, f_norm, cam_to_frag, k_a * f_light * point_shadow, k_d * f_light * point_shadow, k_s * f_light * point_shadow, alpha, emitted_light, reflected_light);
|
// lights_at(f_pos, f_norm, cam_to_frag, k_a * f_light * point_shadow, k_d * f_light * point_shadow, k_s * f_light * point_shadow, alpha, emitted_light, reflected_light);
|
||||||
/*vec3 point_light = light_at(f_pos, f_norm);
|
/*vec3 point_light = light_at(f_pos, f_norm);
|
||||||
emitted_light += point_light;
|
emitted_light += point_light;
|
||||||
reflected_light += point_light; */
|
reflected_light += point_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);
|
max_light += lights_at(f_pos, /*f_norm*/cam_norm, view_dir, mu, cam_attenuation, fluid_alt, k_a, k_d, k_s, alpha, f_norm, 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);
|
||||||
|
|
||||||
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;
|
||||||
|
// float reflected_light_point = dot(reflected_light, reflected_light) * 0.5;///*length*/(diffuse_light_point.r) + f_light * point_shadow;
|
||||||
// vec3 dump_light = vec3(0.0);
|
// vec3 dump_light = vec3(0.0);
|
||||||
// vec3 specular_light_point = vec3(0.0);
|
// vec3 specular_light_point = vec3(0.0);
|
||||||
// lights_at(f_pos, f_norm, view_dir, vec3(0.0), vec3(0.0), /*vec3(1.0)*/k_s, alpha, dump_light, specular_light_point);
|
// lights_at(f_pos, f_norm, view_dir, vec3(0.0), vec3(0.0), /*vec3(1.0)*/k_s, alpha, dump_light, specular_light_point);
|
||||||
@ -139,14 +179,20 @@ void main() {
|
|||||||
// float reflected_light_point = /*length*/(diffuse_light_point.r) + f_light * point_shadow;
|
// float reflected_light_point = /*length*/(diffuse_light_point.r) + f_light * point_shadow;
|
||||||
// reflected_light += k_d * (diffuse_light_point + f_light * point_shadow * shade_frac) + specular_light_point;
|
// reflected_light += k_d * (diffuse_light_point + f_light * point_shadow * shade_frac) + specular_light_point;
|
||||||
|
|
||||||
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
|
float passthrough = /*pow(*/dot(cam_norm, -cam_to_frag/*view_dir*/)/*, 0.5)*/;
|
||||||
vec4 clouds;
|
float min_refl = min(emitted_light.r, min(emitted_light.g, emitted_light.b));
|
||||||
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(cam_norm, -cam_to_frag/*view_dir*/)/*, 0.5)*/;
|
vec3 surf_color = illuminate(max_light, view_dir, water_color * /* fog_color * */emitted_light, /*surf_color * */water_color * reflected_light);
|
||||||
|
// vec4 color = vec4(surf_color, passthrough * 1.0 / (1.0 + min_refl));// * (1.0 - /*log(1.0 + cam_attenuation)*//*cam_attenuation*/1.0 / (2.0 - log_cam)));
|
||||||
|
vec4 color = 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*/min_refl/* * 0.25*/)), passthrough);
|
||||||
|
|
||||||
vec3 surf_color = illuminate(max_light, view_dir, water_color * fog_color * emitted_light, /*surf_color * */water_color * reflected_light);
|
#if (CLOUD_MODE == CLOUD_MODE_REGULAR)
|
||||||
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);
|
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
|
||||||
|
vec4 clouds;
|
||||||
tgt_color = mix(mix(color, vec4(fog_color, 0.0), fog_level), vec4(clouds.rgb, 0.0), clouds.a);
|
vec3 fog_color = get_sky_color(cam_to_frag, time_of_day.x, cam_pos.xyz, f_pos, 0.25, false, clouds);
|
||||||
|
vec4 final_color = mix(mix(color, vec4(fog_color, 0.0), fog_level), vec4(clouds.rgb, 0.0), clouds.a);
|
||||||
|
#elif (CLOUD_MODE == CLOUD_MODE_NONE)
|
||||||
|
vec4 final_color = color;
|
||||||
|
#endif
|
||||||
|
tgt_color = final_color;
|
||||||
}
|
}
|
||||||
|
@ -25,13 +25,25 @@
|
|||||||
|
|
||||||
in vec3 f_pos;
|
in vec3 f_pos;
|
||||||
flat in uint f_pos_norm;
|
flat in uint f_pos_norm;
|
||||||
in vec3 f_col;
|
// in vec3 f_col;
|
||||||
in float f_light;
|
// in float f_light;
|
||||||
|
// in vec3 light_pos[2];
|
||||||
|
|
||||||
|
//struct ShadowLocals {
|
||||||
|
// mat4 shadowMatrices;
|
||||||
|
// mat4 texture_mat;
|
||||||
|
//};
|
||||||
|
//
|
||||||
|
//layout (std140)
|
||||||
|
//uniform u_light_shadows {
|
||||||
|
// ShadowLocals shadowMats[/*MAX_LAYER_FACES*/192];
|
||||||
|
//};
|
||||||
|
|
||||||
layout (std140)
|
layout (std140)
|
||||||
uniform u_locals {
|
uniform u_locals {
|
||||||
vec3 model_offs;
|
vec3 model_offs;
|
||||||
float load_time;
|
float load_time;
|
||||||
|
ivec4 atlas_offs;
|
||||||
};
|
};
|
||||||
|
|
||||||
uniform sampler2D t_waves;
|
uniform sampler2D t_waves;
|
||||||
@ -89,6 +101,16 @@ void main() {
|
|||||||
// Use an array to avoid conditional branching
|
// Use an array to avoid conditional branching
|
||||||
vec3 f_norm = normals[norm_axis + norm_dir];
|
vec3 f_norm = normals[norm_axis + norm_dir];
|
||||||
|
|
||||||
|
// vec4 light_pos[2];
|
||||||
|
//#if (SHADOW_MODE == SHADOW_MODE_MAP)
|
||||||
|
// // for (uint i = 0u; i < light_shadow_count.z; ++i) {
|
||||||
|
// // light_pos[i] = /*vec3(*/shadowMats[i].texture_mat * vec4(f_pos, 1.0)/*)*/;
|
||||||
|
// // }
|
||||||
|
// vec4 sun_pos = /*vec3(*/shadowMats[0].texture_mat * vec4(f_pos, 1.0)/*)*/;
|
||||||
|
//#elif (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_NONE)
|
||||||
|
// vec4 sun_pos = vec4(0.0);
|
||||||
|
//#endif
|
||||||
|
|
||||||
vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz);
|
vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz);
|
||||||
// vec4 vert_pos4 = view_mat * vec4(f_pos, 1.0);
|
// vec4 vert_pos4 = view_mat * vec4(f_pos, 1.0);
|
||||||
// vec3 view_dir = normalize(-vec3(vert_pos4)/* / vert_pos4.w*/);
|
// vec3 view_dir = normalize(-vec3(vert_pos4)/* / vert_pos4.w*/);
|
||||||
@ -121,7 +143,11 @@ void main() {
|
|||||||
vec3 norm = vec3(0, 0, 1) * nmap.z + b_norm * nmap.x + c_norm * nmap.y;
|
vec3 norm = vec3(0, 0, 1) * nmap.z + b_norm * nmap.x + c_norm * nmap.y;
|
||||||
// vec3 norm = f_norm;
|
// vec3 norm = f_norm;
|
||||||
|
|
||||||
|
#if (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_MAP || FLUID_MODE == FLUID_MODE_SHINY)
|
||||||
float f_alt = alt_at(f_pos.xy);
|
float f_alt = alt_at(f_pos.xy);
|
||||||
|
#elif (SHADOW_MODE == SHADOW_MODE_NONE || FLUID_MODE == FLUID_MODE_CHEAP)
|
||||||
|
float f_alt = f_pos.z;
|
||||||
|
#endif
|
||||||
|
|
||||||
float fluid_alt = max(ceil(f_pos.z), floor(f_alt));// f_alt;//max(f_alt - f_pos.z, 0.0);
|
float fluid_alt = max(ceil(f_pos.z), floor(f_alt));// f_alt;//max(f_alt - f_pos.z, 0.0);
|
||||||
const float alpha = 0.255/*/ / 4.0*//* / 4.0 / sqrt(2.0)*/;
|
const float alpha = 0.255/*/ / 4.0*//* / 4.0 / sqrt(2.0)*/;
|
||||||
@ -144,7 +170,7 @@ void main() {
|
|||||||
reflect_ray_dir = normalize(vec3(reflect_ray_dir4) / reflect_ray_dir4.w); */
|
reflect_ray_dir = normalize(vec3(reflect_ray_dir4) / reflect_ray_dir4.w); */
|
||||||
// vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz);
|
// vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz);
|
||||||
// Squared to account for prior saturation.
|
// Squared to account for prior saturation.
|
||||||
float f_light = pow(f_light, 1.5);
|
float f_light = 1.0;// pow(f_light, 1.5);
|
||||||
vec3 reflect_color = get_sky_color(/*reflect_ray_dir*/beam_view_dir, time_of_day.x, f_pos, vec3(-100000), 0.25, false, _clouds) * f_light;
|
vec3 reflect_color = get_sky_color(/*reflect_ray_dir*/beam_view_dir, time_of_day.x, f_pos, vec3(-100000), 0.25, false, _clouds) * f_light;
|
||||||
// /*const */vec3 water_color = srgb_to_linear(vec3(0.2, 0.5, 1.0));
|
// /*const */vec3 water_color = srgb_to_linear(vec3(0.2, 0.5, 1.0));
|
||||||
// /*const */vec3 water_color = srgb_to_linear(vec3(0.8, 0.9, 1.0));
|
// /*const */vec3 water_color = srgb_to_linear(vec3(0.8, 0.9, 1.0));
|
||||||
@ -153,14 +179,23 @@ void main() {
|
|||||||
// /*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);
|
||||||
vec3 moon_dir = get_moon_dir(time_of_day.x);
|
vec3 moon_dir = get_moon_dir(time_of_day.x); */
|
||||||
|
#if (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_MAP)
|
||||||
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 sun_shade_frac = horizon_at2(f_shadow, f_alt, f_pos, sun_dir);
|
float sun_shade_frac = horizon_at2(f_shadow, f_alt, f_pos, sun_dir);
|
||||||
float moon_shade_frac = horizon_at2(f_shadow, f_alt, f_pos, moon_dir);
|
#elif (SHADOW_MODE == SHADOW_MODE_NONE)
|
||||||
|
float sun_shade_frac = 1.0;//horizon_at2(f_shadow, f_alt, f_pos, sun_dir);
|
||||||
|
#endif
|
||||||
|
float moon_shade_frac = 1.0;// horizon_at2(f_shadow, f_alt, f_pos, moon_dir);
|
||||||
// float sun_shade_frac = horizon_at(/*f_shadow, f_pos.z, */f_pos, sun_dir);
|
// float sun_shade_frac = horizon_at(/*f_shadow, f_pos.z, */f_pos, sun_dir);
|
||||||
// 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;
|
||||||
|
|
||||||
|
// DirectionalLight sun_info = get_sun_info(sun_dir, sun_shade_frac, light_pos);
|
||||||
|
float point_shadow = shadow_at(f_pos, f_norm);
|
||||||
|
DirectionalLight sun_info = get_sun_info(sun_dir, point_shadow * sun_shade_frac, /*sun_pos*/f_pos);
|
||||||
|
DirectionalLight moon_info = get_moon_info(moon_dir, point_shadow * moon_shade_frac/*, light_pos*/);
|
||||||
|
|
||||||
// Hack to determine water depth: color goes down with distance through water, so
|
// Hack to determine water depth: color goes down with distance through water, so
|
||||||
// we assume water color absorption from this point a to some other point b is the distance
|
// we assume water color absorption from this point a to some other point b is the distance
|
||||||
@ -206,16 +241,18 @@ void main() {
|
|||||||
|
|
||||||
vec3 emitted_light, reflected_light;
|
vec3 emitted_light, reflected_light;
|
||||||
// vec3 light, diffuse_light, ambient_light;
|
// vec3 light, diffuse_light, ambient_light;
|
||||||
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(norm, 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(sun_info, moon_info, norm, /*time_of_day.x*/sun_view_dir, f_pos, mu, cam_attenuation, fluid_alt, k_a/* * (shade_frac * 0.5 + light_frac * 0.5)*/, vec3(k_d), /*vec3(f_light * point_shadow)*//*reflect_color*/k_s, alpha, f_norm, 1.0, emitted_light, reflected_light);
|
||||||
reflected_light *= /*water_color_direct * */reflect_color * f_light * point_shadow * shade_frac;
|
// reflected_light *= /*water_color_direct * */reflect_color * f_light * point_shadow * shade_frac;
|
||||||
emitted_light *= /*water_color_direct*//*ambient_attenuation * */f_light * point_shadow * max(shade_frac, MIN_SHADOW);
|
// emitted_light *= /*water_color_direct*//*ambient_attenuation * */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;
|
||||||
|
// reflected_light *= /*water_color_direct * */reflect_color * f_light * point_shadow;
|
||||||
|
// emitted_light *= /*water_color_direct*//*ambient_attenuation * */f_light * point_shadow;
|
||||||
|
// max_light *= f_light * point_shadow;
|
||||||
|
|
||||||
// vec3 diffuse_light_point = vec3(0.0);
|
// vec3 diffuse_light_point = vec3(0.0);
|
||||||
// max_light += lights_at(f_pos, cam_norm, view_dir, mu, cam_attenuation, fluid_alt, k_a, vec3(1.0), /*vec3(0.0)*/k_s, alpha, emitted_light, diffuse_light_point);
|
// max_light += lights_at(f_pos, cam_norm, view_dir, mu, cam_attenuation, fluid_alt, k_a, vec3(1.0), /*vec3(0.0)*/k_s, alpha, emitted_light, diffuse_light_point);
|
||||||
@ -226,7 +263,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, 1.0, 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, f_norm, 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.
|
||||||
@ -246,10 +283,6 @@ void main() {
|
|||||||
// 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, view_dir, emitted_light/* * log(1.0 - MU_WATER)*/, /*cam_attenuation * *//*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);
|
|
||||||
vec4 clouds;
|
|
||||||
vec3 fog_color = get_sky_color(cam_to_frag/*-view_dir*/, time_of_day.x, cam_pos.xyz, f_pos, 0.25, true, clouds);
|
|
||||||
|
|
||||||
// passthrough = pow(passthrough, 1.0 / (1.0 + water_depth_to_camera));
|
// passthrough = pow(passthrough, 1.0 / (1.0 + water_depth_to_camera));
|
||||||
/* surf_color = cam_attenuation.g < 0.5 ?
|
/* surf_color = cam_attenuation.g < 0.5 ?
|
||||||
vec3(1.0, 0.0, 0.0) :
|
vec3(1.0, 0.0, 0.0) :
|
||||||
@ -284,5 +317,13 @@ void main() {
|
|||||||
|
|
||||||
vec4 color = mix(vec4(reflect_color, 1.0), vec4(vec3(0), 1.0 / (1.0 + diffuse_light * 0.25)), passthrough); */
|
vec4 color = mix(vec4(reflect_color, 1.0), vec4(vec3(0), 1.0 / (1.0 + diffuse_light * 0.25)), passthrough); */
|
||||||
|
|
||||||
tgt_color = mix(mix(color, vec4(fog_color, 0.0), fog_level), vec4(clouds.rgb, 0.0), clouds.a);
|
#if (CLOUD_MODE == CLOUD_MODE_REGULAR)
|
||||||
|
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
|
||||||
|
vec4 clouds;
|
||||||
|
vec3 fog_color = get_sky_color(cam_to_frag/*-view_dir*/, time_of_day.x, cam_pos.xyz, f_pos, 0.25, false, clouds);
|
||||||
|
vec4 final_color = mix(mix(color, vec4(fog_color, 0.0), fog_level), vec4(clouds.rgb, 0.0), clouds.a);
|
||||||
|
#elif (CLOUD_MODE == CLOUD_MODE_NONE)
|
||||||
|
vec4 final_color = color;
|
||||||
|
#endif
|
||||||
|
tgt_color = final_color;
|
||||||
}
|
}
|
||||||
|
@ -21,48 +21,63 @@
|
|||||||
#include <random.glsl>
|
#include <random.glsl>
|
||||||
|
|
||||||
in uint v_pos_norm;
|
in uint v_pos_norm;
|
||||||
in uint v_col_light;
|
// in uint v_col_light;
|
||||||
|
|
||||||
layout (std140)
|
layout (std140)
|
||||||
uniform u_locals {
|
uniform u_locals {
|
||||||
vec3 model_offs;
|
vec3 model_offs;
|
||||||
float load_time;
|
float load_time;
|
||||||
|
ivec4 atlas_offs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// struct ShadowLocals {
|
||||||
|
// mat4 shadowMatrices;
|
||||||
|
// mat4 texture_mat;
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// layout (std140)
|
||||||
|
// uniform u_light_shadows {
|
||||||
|
// ShadowLocals shadowMats[/*MAX_LAYER_FACES*/192];
|
||||||
|
// };
|
||||||
|
|
||||||
out vec3 f_pos;
|
out vec3 f_pos;
|
||||||
flat out uint f_pos_norm;
|
flat out uint f_pos_norm;
|
||||||
out vec3 f_col;
|
// out vec3 f_col;
|
||||||
out float f_light;
|
// out float f_light;
|
||||||
|
// out vec3 light_pos[2];
|
||||||
|
|
||||||
const float EXTRA_NEG_Z = 65536.0;
|
const float EXTRA_NEG_Z = /*65536.0*/65536.1;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
f_pos = vec3((uvec3(v_pos_norm) >> uvec3(0, 6, 12)) & uvec3(0x3Fu, 0x3Fu, 0x1FFFFu)) - vec3(0, 0, EXTRA_NEG_Z) + model_offs;
|
f_pos = vec3((uvec3(v_pos_norm) >> uvec3(0, 6, 12)) & uvec3(0x3Fu, 0x3Fu, 0x1FFFFu)) - vec3(0, 0, EXTRA_NEG_Z) + model_offs - focus_off.xyz;
|
||||||
// f_pos.z -= 250.0 * (1.0 - min(1.0001 - 0.02 / pow(tick.x - load_time, 10.0), 1.0));
|
// f_pos.z -= 250.0 * (1.0 - min(1.0001 - 0.02 / pow(tick.x - load_time, 10.0), 1.0));
|
||||||
// f_pos.z -= min(32.0, 25.0 * pow(distance(focus_pos.xy, f_pos.xy) / view_distance.x, 20.0));
|
// f_pos.z -= min(32.0, 25.0 * pow(distance(focus_pos.xy, f_pos.xy) / view_distance.x, 20.0));
|
||||||
|
|
||||||
// Small waves
|
// Small waves
|
||||||
f_pos.xy += 0.01; // Avoid z-fighting
|
// f_pos.xy += 0.01; // Avoid z-fighting
|
||||||
// f_pos.x += 0.1 * sin(tick.x / 60 * hash(vec4(f_pos.xyz, 1.0)));
|
// f_pos.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)));
|
// f_pos.y += 0.1 * sin(tick.x / 60 * hash(vec4(f_pos.xyz, 2.0)));
|
||||||
#if (FLUID_MODE == FLUID_MODE_SHINY)
|
#if (FLUID_MODE == FLUID_MODE_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;
|
// 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
|
#endif
|
||||||
|
|
||||||
f_col = vec3(
|
/* f_col = vec3(
|
||||||
float((v_col_light >> 8) & 0xFFu),
|
float((v_col_light >> 8) & 0xFFu),
|
||||||
float((v_col_light >> 16) & 0xFFu),
|
float((v_col_light >> 16) & 0xFFu),
|
||||||
float((v_col_light >> 24) & 0xFFu)
|
float((v_col_light >> 24) & 0xFFu)
|
||||||
) / 255.0;
|
) / 255.0;
|
||||||
|
|
||||||
f_light = float(v_col_light & 0xFFu) / 255.0;
|
f_light = float(v_col_light & 0xFFu) / 255.0; */
|
||||||
|
/* for (uint i = 0u; i < light_shadow_count.z; ++i) {
|
||||||
|
light_pos[i] = vec3(shadowMats[i].texture_mat * vec4(f_pos, 1.0));
|
||||||
|
} */
|
||||||
|
|
||||||
f_pos_norm = v_pos_norm;
|
f_pos_norm = v_pos_norm;
|
||||||
|
|
||||||
gl_Position =
|
gl_Position =
|
||||||
all_mat *
|
all_mat *
|
||||||
vec4(f_pos, 1);
|
vec4(f_pos, 1);
|
||||||
// gl_Position.z = -gl_Position.z / gl_Position.w;
|
// gl_Position.z = -gl_Position.z / gl_Position.w;
|
||||||
// gl_Position.z = -gl_Position.z / 100.0;
|
// gl_Position.z = -gl_Position.z / 100.0;
|
||||||
gl_Position.z = -1000.0 / (gl_Position.z + 10000.0);
|
// gl_Position.z = -1000.0 / (gl_Position.z + 10000.0);
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,10 @@
|
|||||||
#define LIGHTING_ALGORITHM_BLINN_PHONG 1u
|
#define LIGHTING_ALGORITHM_BLINN_PHONG 1u
|
||||||
#define LIGHTING_ALGORITHM_ASHIKHMIN 2u
|
#define LIGHTING_ALGORITHM_ASHIKHMIN 2u
|
||||||
|
|
||||||
|
#define SHADOW_MODE_NONE 0u
|
||||||
|
#define SHADOW_MODE_CHEAP 1u
|
||||||
|
#define SHADOW_MODE_MAP 2u
|
||||||
|
|
||||||
/* Unlike the other flags (for now anyway), these are bitmask values */
|
/* Unlike the other flags (for now anyway), these are bitmask values */
|
||||||
#define LIGHTING_TYPE_REFLECTION 0x01u
|
#define LIGHTING_TYPE_REFLECTION 0x01u
|
||||||
#define LIGHTING_TYPE_TRANSMISSION 0x02u
|
#define LIGHTING_TYPE_TRANSMISSION 0x02u
|
||||||
@ -43,6 +47,7 @@
|
|||||||
#define FLUID_MODE <mode>
|
#define FLUID_MODE <mode>
|
||||||
#define CLOUD_MODE <mode>
|
#define CLOUD_MODE <mode>
|
||||||
#define LIGHTING_ALGORITHM <algorithm>
|
#define LIGHTING_ALGORITHM <algorithm>
|
||||||
|
#define SHADOW_MODE <mode>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Constants expected to be defined by any shader that needs to perform lighting calculations
|
/* Constants expected to be defined by any shader that needs to perform lighting calculations
|
||||||
@ -56,3 +61,11 @@
|
|||||||
#define LIGHTING_DISTRIBUTION_SCHEME <scheme>
|
#define LIGHTING_DISTRIBUTION_SCHEME <scheme>
|
||||||
#define LIGHTING_DISTRIBUTION <distribution>
|
#define LIGHTING_DISTRIBUTION <distribution>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Constants that *may* be defined by any shader.
|
||||||
|
* (and whose values may take automatically defined constants into account): */
|
||||||
|
|
||||||
|
/*
|
||||||
|
// When sets, shadow maps are used to cast shadows.
|
||||||
|
#define HAS_SHADOW_MAPS
|
||||||
|
*/
|
||||||
|
@ -4,9 +4,12 @@ uniform u_globals {
|
|||||||
mat4 proj_mat;
|
mat4 proj_mat;
|
||||||
mat4 all_mat;
|
mat4 all_mat;
|
||||||
vec4 cam_pos;
|
vec4 cam_pos;
|
||||||
|
vec4 focus_off;
|
||||||
vec4 focus_pos;
|
vec4 focus_pos;
|
||||||
vec4 view_distance;
|
vec4 view_distance;
|
||||||
vec4 time_of_day;
|
vec4 time_of_day;
|
||||||
|
vec4 sun_dir;
|
||||||
|
vec4 moon_dir;
|
||||||
vec4 tick;
|
vec4 tick;
|
||||||
vec4 screen_res;
|
vec4 screen_res;
|
||||||
uvec4 light_shadow_count;
|
uvec4 light_shadow_count;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <srgb.glsl>
|
#include <srgb.glsl>
|
||||||
|
#include <shadows.glsl>
|
||||||
|
|
||||||
struct Light {
|
struct Light {
|
||||||
vec4 light_pos;
|
vec4 light_pos;
|
||||||
@ -8,7 +9,7 @@ struct Light {
|
|||||||
|
|
||||||
layout (std140)
|
layout (std140)
|
||||||
uniform u_lights {
|
uniform u_lights {
|
||||||
Light lights[32];
|
Light lights[31];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Shadow {
|
struct Shadow {
|
||||||
@ -26,116 +27,6 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAS_SHADOW_MAPS
|
|
||||||
// uniform samplerCubeArrayShadow t_shadow_maps;
|
|
||||||
// uniform samplerCubeArray t_shadow_maps;
|
|
||||||
uniform samplerCubeShadow t_shadow_maps;
|
|
||||||
// uniform samplerCube t_shadow_maps;
|
|
||||||
|
|
||||||
// uniform sampler2DArray t_directed_shadow_maps;
|
|
||||||
|
|
||||||
float VectorToDepth (vec3 Vec)
|
|
||||||
{
|
|
||||||
vec3 AbsVec = abs(Vec);
|
|
||||||
float LocalZcomp = max(AbsVec.x, max(AbsVec.y, AbsVec.z));
|
|
||||||
// float LocalZcomp = length(Vec);
|
|
||||||
|
|
||||||
// Replace f and n with the far and near plane values you used when
|
|
||||||
// you drew your cube map.
|
|
||||||
// const float f = 2048.0;
|
|
||||||
// const float n = 1.0;
|
|
||||||
|
|
||||||
// float NormZComp = (screen_res.w+screen_res.z) / (screen_res.w-screen_res.z) - (2*screen_res.w*screen_res.z)/(screen_res.w-screen_res.z)/LocalZcomp;
|
|
||||||
// float NormZComp = 1.0 - shadow_proj_factors.y / shadow_proj_factors.x / LocalZcomp;
|
|
||||||
float NormZComp = shadow_proj_factors.x - shadow_proj_factors.y / LocalZcomp;
|
|
||||||
// NormZComp = -1000.0 / (NormZComp + 10000.0);
|
|
||||||
return (NormZComp + 1.0) * 0.5;
|
|
||||||
|
|
||||||
// float NormZComp = length(LocalZcomp);
|
|
||||||
// NormZComp = -NormZComp / screen_res.w;
|
|
||||||
// // return (NormZComp + 1.0) * 0.5;
|
|
||||||
// return NormZComp;
|
|
||||||
}
|
|
||||||
|
|
||||||
const vec3 sampleOffsetDirections[20] = vec3[]
|
|
||||||
(
|
|
||||||
vec3( 1, 1, 1), vec3( 1, -1, 1), vec3(-1, -1, 1), vec3(-1, 1, 1),
|
|
||||||
vec3( 1, 1, -1), vec3( 1, -1, -1), vec3(-1, -1, -1), vec3(-1, 1, -1),
|
|
||||||
vec3( 1, 1, 0), vec3( 1, -1, 0), vec3(-1, -1, 0), vec3(-1, 1, 0),
|
|
||||||
vec3( 1, 0, 1), vec3(-1, 0, 1), vec3( 1, 0, -1), vec3(-1, 0, -1),
|
|
||||||
vec3( 0, 1, 1), vec3( 0, -1, 1), vec3( 0, -1, -1), vec3( 0, 1, -1)
|
|
||||||
// vec3(0, 0, 0)
|
|
||||||
);
|
|
||||||
|
|
||||||
float ShadowCalculation(uint lightIndex, vec3 fragToLight, /*float currentDepth*/vec3 fragPos)
|
|
||||||
{
|
|
||||||
if (lightIndex != 0u) {
|
|
||||||
return 1.0;
|
|
||||||
};
|
|
||||||
|
|
||||||
float shadow = 0.0;
|
|
||||||
float bias = 0.0;//-0.003;//-0.003;//-0.005;//0.001;//-1.0;//-0.001;//0.001;//0.003;//-0.05;//-0.1;//0.0;//0.1
|
|
||||||
|
|
||||||
{
|
|
||||||
float currentDepth = VectorToDepth(fragToLight);// + bias;
|
|
||||||
|
|
||||||
float visibility = texture(t_shadow_maps, vec4(fragToLight, currentDepth));// / (screen_res.w/* - screen_res.z*/)/*1.0 -bias*//*-(currentDepth - bias) / screen_res.w*//*-screen_res.w*/);
|
|
||||||
if (visibility == 1.0 || visibility == 0.0) {
|
|
||||||
return visibility;
|
|
||||||
}
|
|
||||||
// return visibility == 1.0 ? 1.0 : 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int samples = 20;
|
|
||||||
float lightDistance = length(fragToLight);
|
|
||||||
float viewDistance = length(cam_pos.xyz - fragPos);
|
|
||||||
// float diskRadius = 0.00001;
|
|
||||||
// float diskRadius = 1.0;
|
|
||||||
// float diskRadius = 0.05;
|
|
||||||
float diskRadius = (1.0 + (/*viewDistance*/viewDistance / screen_res.w)) / 25.0;
|
|
||||||
// float diskRadius = lightDistance;
|
|
||||||
for(int i = 0; i < samples; ++i)
|
|
||||||
{
|
|
||||||
float currentDepth = VectorToDepth(fragToLight + sampleOffsetDirections[i] * diskRadius) + bias;
|
|
||||||
// float closestDepth = texture(depthMap, fragToLight).r;
|
|
||||||
// closestDepth *= far_plane; // Undo mapping [0;1]
|
|
||||||
/* if(currentDepth - bias > closestDepth)
|
|
||||||
shadow += 1.0;*/
|
|
||||||
float visibility = texture(t_shadow_maps, vec4(fragToLight, currentDepth)/*, -2.5*/);
|
|
||||||
shadow += visibility;
|
|
||||||
// float closestDepth = texture(t_shadow_maps, vec3(fragToLight)/*, -2.5*/).r;
|
|
||||||
// shadow += closestDepth > currentDepth ? 1.0 : 0.0;
|
|
||||||
}
|
|
||||||
shadow /= float(samples);
|
|
||||||
// shadow = shadow * shadow * (3.0 - 2.0 * shadow);
|
|
||||||
|
|
||||||
// use the light to fragment vector to sample from the depth map
|
|
||||||
// float bias = 0.0;///*0.05*/0.01;//0.05;// 0.05;
|
|
||||||
// float closestDepth = texture(t_shadow_maps, /*vec4*/vec3(fragToLight/*, (lightIndex + 1)*//* * 6*/)/*, 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 = (closestDepth + 0.0) * 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 + 1), -(currentDepth/* + screen_res.z*/) / screen_res.w);// / (screen_res.w/* - screen_res.z*/)/*1.0 -bias*//*-(currentDepth - bias) / screen_res.w*//*-screen_res.w*/);
|
|
||||||
// currentDepth += bias;
|
|
||||||
// currentDepth = -1000.0 / (currentDepth + 10000.0);
|
|
||||||
// currentDepth /= screen_res.w;
|
|
||||||
// float currentDepth = VectorToDepth(fragToLight) + bias;
|
|
||||||
|
|
||||||
// float visibility = texture(t_shadow_maps, vec4(fragToLight, currentDepth));// / (screen_res.w/* - screen_res.z*/)/*1.0 -bias*//*-(currentDepth - bias) / screen_res.w*//*-screen_res.w*/);
|
|
||||||
// return visibility == 1.0 ? 1.0 : 0.0;
|
|
||||||
return shadow;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
float ShadowCalculation(uint lightIndex, vec3 fragToLight, /*float currentDepth*/vec3 fragPos)
|
|
||||||
{
|
|
||||||
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).
|
||||||
// //
|
// //
|
||||||
@ -177,7 +68,7 @@ vec3 light_at(vec3 wpos, vec3 wnorm) {
|
|||||||
// Only access the array once
|
// Only access the array once
|
||||||
Light L = lights[i];
|
Light L = lights[i];
|
||||||
|
|
||||||
vec3 light_pos = L.light_pos.xyz;
|
vec3 light_pos = L.light_pos.xyz - focus_off.xyz;
|
||||||
|
|
||||||
// Pre-calculate difference between light and fragment
|
// Pre-calculate difference between light and fragment
|
||||||
vec3 difference = light_pos - wpos;
|
vec3 difference = light_pos - wpos;
|
||||||
@ -195,12 +86,15 @@ vec3 light_at(vec3 wpos, vec3 wnorm) {
|
|||||||
float shadow_at(vec3 wpos, vec3 wnorm) {
|
float shadow_at(vec3 wpos, vec3 wnorm) {
|
||||||
float shadow = 1.0;
|
float shadow = 1.0;
|
||||||
|
|
||||||
|
#if (SHADOW_MODE == SHADOW_MODE_NONE || SHADOW_MODE == SHADOW_MODE_MAP)
|
||||||
|
return shadow;
|
||||||
|
#elif (SHADOW_MODE == SHADOW_MODE_CHEAP)
|
||||||
for (uint i = 0u; i < light_shadow_count.y; i ++) {
|
for (uint i = 0u; i < light_shadow_count.y; i ++) {
|
||||||
|
|
||||||
// Only access the array once
|
// Only access the array once
|
||||||
Shadow S = shadows[i];
|
Shadow S = shadows[i];
|
||||||
|
|
||||||
vec3 shadow_pos = S.shadow_pos_radius.xyz;
|
vec3 shadow_pos = S.shadow_pos_radius.xyz - focus_off.xyz;
|
||||||
float radius = S.shadow_pos_radius.w;
|
float radius = S.shadow_pos_radius.w;
|
||||||
|
|
||||||
vec3 diff = shadow_pos - wpos;
|
vec3 diff = shadow_pos - wpos;
|
||||||
@ -209,11 +103,15 @@ float shadow_at(vec3 wpos, vec3 wnorm) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
float shade = max(pow(diff.x * diff.x + diff.y * diff.y + diff.z * diff.z, 0.25) / pow(radius * radius * 0.5, 0.25), 0.5);
|
float shade = max(pow(diff.x * diff.x + diff.y * diff.y + diff.z * diff.z, 0.25) / pow(radius * radius * 0.5, 0.25), 0.5);
|
||||||
|
// float shade = max(pow(dot(diff, diff) / (radius * radius * 0.5), 0.25), 0.5);
|
||||||
|
// float shade = dot(diff, diff) / (radius * radius * 0.5);
|
||||||
|
|
||||||
shadow = min(shadow, shade);
|
shadow = min(shadow, shade);
|
||||||
}
|
}
|
||||||
// NOTE: Squared to compenate for prior saturation.
|
// NOTE: Squared to compenate for prior saturation.
|
||||||
return min(shadow * shadow, 1.0);
|
return min(shadow, 1.0);
|
||||||
|
// return min(shadow * shadow, 1.0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns computed maximum intensity.
|
// Returns computed maximum intensity.
|
||||||
@ -221,20 +119,21 @@ 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*/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*/) {
|
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, vec3 voxel_norm, float voxel_lighting, inout vec3 emitted_light, inout vec3 reflected_light/*, out float shadow*/) {
|
||||||
|
// return 0.0;
|
||||||
// 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.015625;
|
const float LIGHT_AMBIENCE = 0.0;//0.015625;
|
||||||
|
|
||||||
for (uint i = 0u; i < light_shadow_count.x/*32u*/; i ++) {
|
for (uint i = 0u; i < /*light_shadow_count.x*//*0u*/light_shadow_count.x/*32u*/; i ++) {
|
||||||
|
|
||||||
// Only access the array once
|
// Only access the array once
|
||||||
Light L = lights[i];
|
Light L = lights[i];
|
||||||
|
|
||||||
vec3 light_pos = L.light_pos.xyz;
|
vec3 light_pos = L.light_pos.xyz - focus_off.xyz;
|
||||||
|
|
||||||
// Pre-calculate difference between light and fragment
|
// Pre-calculate difference between light and fragment
|
||||||
vec3 difference = light_pos - wpos;
|
vec3 difference = light_pos - wpos;
|
||||||
@ -282,10 +181,10 @@ float lights_at(vec3 wpos, vec3 wnorm, vec3 /*cam_to_frag*/view_dir, vec3 mu, ve
|
|||||||
#if (LIGHTING_TYPE & LIGHTING_TYPE_TRANSMISSION) != 0
|
#if (LIGHTING_TYPE & LIGHTING_TYPE_TRANSMISSION) != 0
|
||||||
is_direct = true;
|
is_direct = true;
|
||||||
#endif
|
#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);
|
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_norm, voxel_lighting);
|
||||||
float computed_shadow = ShadowCalculation(i, -difference, wpos/*, light_distance*/);
|
float computed_shadow = ShadowCalculationPoint(i, -difference, wnorm, wpos/*, light_distance*/);
|
||||||
directed_light += is_direct ? max(computed_shadow, /*LIGHT_AMBIENCE*/0.0) * direct_light * square_factor : vec3(0.0);
|
// directed_light += is_direct ? max(computed_shadow, /*LIGHT_AMBIENCE*/0.0) * direct_light * square_factor : vec3(0.0);
|
||||||
// directed_light += is_direct ? mix(LIGHT_AMBIENCE, 1.0, computed_shadow) * direct_light * square_factor : vec3(0.0);
|
directed_light += is_direct ? mix(LIGHT_AMBIENCE, 1.0, computed_shadow) * direct_light * square_factor : vec3(0.0);
|
||||||
// ambient_light += is_direct ? vec3(0.0) : vec3(0.0); // direct_light * square_factor * LIGHT_AMBIENCE;
|
// ambient_light += is_direct ? vec3(0.0) : vec3(0.0); // direct_light * square_factor * LIGHT_AMBIENCE;
|
||||||
// ambient_light += is_direct ? direct_light * (1.0 - square_factor * LIGHT_AMBIENCE) : vec3(0.0);
|
// ambient_light += is_direct ? direct_light * (1.0 - square_factor * LIGHT_AMBIENCE) : vec3(0.0);
|
||||||
|
|
||||||
@ -308,7 +207,7 @@ float lights_at(vec3 wpos, vec3 wnorm, vec3 /*cam_to_frag*/view_dir, vec3 mu, ve
|
|||||||
// 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*//*computed_shadow * */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.
|
||||||
@ -321,11 +220,11 @@ float lights_at(vec3 wpos, vec3 wnorm, vec3 /*cam_to_frag*/view_dir, vec3 mu, ve
|
|||||||
// shadow = shadow_at(wpos, wnorm);
|
// shadow = shadow_at(wpos, wnorm);
|
||||||
// float shadow = shadow_at(wpos, wnorm);
|
// float shadow = shadow_at(wpos, wnorm);
|
||||||
reflected_light += directed_light;
|
reflected_light += directed_light;
|
||||||
emitted_light += k_a * ambient_light/* * shadow*/;// min(shadow, 1.0);
|
// emitted_light += k_a * ambient_light/* * shadow*/;// min(shadow, 1.0);
|
||||||
return /*rel_luminance(ambient_light + directed_light)*/rel_luminance(max_light);//ambient_light;
|
return /*rel_luminance(ambient_light + directed_light)*/rel_luminance(max_light);//ambient_light;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 view_dir, 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, view_dir, vec3(0.0), vec3(1.0), 0.0, k_a, k_d, k_s, alpha, 1.0, 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, wnorm, 1.0, emitted_light, reflected_light);
|
||||||
}
|
}
|
||||||
|
@ -10,13 +10,13 @@ const float MIN_SHADOW = 0.33;
|
|||||||
vec2 pos_to_uv(sampler2D sampler, vec2 pos) {
|
vec2 pos_to_uv(sampler2D sampler, vec2 pos) {
|
||||||
// Want: (pixel + 0.5) / W
|
// Want: (pixel + 0.5) / W
|
||||||
vec2 texSize = textureSize(sampler, 0);
|
vec2 texSize = textureSize(sampler, 0);
|
||||||
vec2 uv_pos = (pos + 16) / (32.0 * texSize);
|
vec2 uv_pos = (focus_off.xy + pos + 16) / (32.0 * texSize);
|
||||||
return vec2(uv_pos.x, 1.0 - uv_pos.y);
|
return vec2(uv_pos.x, 1.0 - uv_pos.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec2 pos_to_tex(vec2 pos) {
|
vec2 pos_to_tex(vec2 pos) {
|
||||||
// Want: (pixel + 0.5)
|
// Want: (pixel + 0.5)
|
||||||
vec2 uv_pos = (pos + 16) / 32.0;
|
vec2 uv_pos = (focus_off.xy + pos + 16) / 32.0;
|
||||||
return vec2(uv_pos.x, uv_pos.y);
|
return vec2(uv_pos.x, uv_pos.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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 - focus_off.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
|
||||||
@ -87,7 +87,7 @@ float alt_at_real(vec2 pos) {
|
|||||||
// #if (FLUID_MODE == FLUID_MODE_CHEAP)
|
// #if (FLUID_MODE == FLUID_MODE_CHEAP)
|
||||||
// return alt_at(pos);
|
// return alt_at(pos);
|
||||||
// #elif (FLUID_MODE == FLUID_MODE_SHINY)
|
// #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);
|
return (textureBicubic(t_map, pos_to_tex(pos)).a * (/*1300.0*//*1278.7266845703125*/view_distance.w) + /*140.0*/view_distance.z - focus_off.z);
|
||||||
// #endif
|
// #endif
|
||||||
//+ (texture(t_noise, pos * 0.002).x - 0.5) * 64.0;
|
//+ (texture(t_noise, pos * 0.002).x - 0.5) * 64.0;
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ float alt_at_real(vec2 pos) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
float horizon_at2(vec4 f_horizons, float alt, vec3 pos, /*float time_of_day*/vec3 light_dir) {
|
float horizon_at2(vec4 f_horizons, float alt, vec3 pos, /*float time_of_day*/vec4 light_dir) {
|
||||||
// vec3 sun_dir = get_sun_dir(time_of_day);
|
// vec3 sun_dir = get_sun_dir(time_of_day);
|
||||||
const float PI_2 = 3.1415926535897932384626433832795 / 2.0;
|
const float PI_2 = 3.1415926535897932384626433832795 / 2.0;
|
||||||
const float MIN_LIGHT = 0.0;//0.115/*0.0*/;
|
const float MIN_LIGHT = 0.0;//0.115/*0.0*/;
|
||||||
@ -133,9 +133,9 @@ float horizon_at2(vec4 f_horizons, float alt, vec3 pos, /*float time_of_day*/vec
|
|||||||
.unwrap_or(1.0);
|
.unwrap_or(1.0);
|
||||||
*/
|
*/
|
||||||
// vec2 f_horizon;
|
// vec2 f_horizon;
|
||||||
if (light_dir.z >= 0) {
|
/* if (light_dir.z >= 0) {
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
} */
|
||||||
/* if (light_dir.x >= 0) {
|
/* if (light_dir.x >= 0) {
|
||||||
f_horizon = f_horizons.rg;
|
f_horizon = f_horizons.rg;
|
||||||
// f_horizon = f_horizons.ba;
|
// f_horizon = f_horizons.ba;
|
||||||
@ -159,7 +159,7 @@ float horizon_at2(vec4 f_horizons, float alt, vec3 pos, /*float time_of_day*/vec
|
|||||||
} */
|
} */
|
||||||
float height = f_horizon.y * /*1300.0*//*1278.7266845703125*/view_distance.w + view_distance.z;
|
float height = f_horizon.y * /*1300.0*//*1278.7266845703125*/view_distance.w + view_distance.z;
|
||||||
const float w = 0.1;
|
const float w = 0.1;
|
||||||
float deltah = height - alt;
|
float deltah = height - alt - focus_off.z;
|
||||||
//if (deltah < 0.0001/* || angle < 0.0001 || abs(light_dir.x) < 0.0001*/) {
|
//if (deltah < 0.0001/* || angle < 0.0001 || abs(light_dir.x) < 0.0001*/) {
|
||||||
// return 1.0;
|
// return 1.0;
|
||||||
/*} else */{
|
/*} else */{
|
||||||
@ -187,12 +187,12 @@ float horizon_at2(vec4 f_horizons, float alt, vec3 pos, /*float time_of_day*/vec
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float horizon_at(vec3 pos, /*float time_of_day*/vec3 light_dir) {
|
// float horizon_at(vec3 pos, /*float time_of_day*/vec3 light_dir) {
|
||||||
vec4 f_horizons = textureBicubic(t_horizon, pos_to_tex(pos.xy));
|
// vec4 f_horizons = textureBicubic(t_horizon, pos_to_tex(pos.xy));
|
||||||
f_horizons.xyz = /*linear_to_srgb*/(f_horizons.xyz);
|
// // f_horizons.xyz = /*linear_to_srgb*/(f_horizons.xyz);
|
||||||
float alt = alt_at_real(pos.xy);
|
// float alt = alt_at_real(pos.xy);
|
||||||
return horizon_at2(f_horizons, alt, pos, light_dir);
|
// return horizon_at2(f_horizons, alt, pos, light_dir);
|
||||||
}
|
// }
|
||||||
|
|
||||||
vec2 splay(vec2 pos) {
|
vec2 splay(vec2 pos) {
|
||||||
// const float SPLAY_MULT = 1048576.0;
|
// const float SPLAY_MULT = 1048576.0;
|
||||||
|
@ -2,6 +2,15 @@
|
|||||||
#include <srgb.glsl>
|
#include <srgb.glsl>
|
||||||
#include <cloud.glsl>
|
#include <cloud.glsl>
|
||||||
#include <srgb.glsl>
|
#include <srgb.glsl>
|
||||||
|
#include <shadows.glsl>
|
||||||
|
|
||||||
|
// Information about an approximately directional light, like the sun or moon.
|
||||||
|
struct DirectionalLight {
|
||||||
|
// vec3 dir;
|
||||||
|
float shadow;
|
||||||
|
// vec3 color;
|
||||||
|
// float brightness;
|
||||||
|
};
|
||||||
|
|
||||||
const float PI = 3.141592;
|
const float PI = 3.141592;
|
||||||
|
|
||||||
@ -32,52 +41,81 @@ 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;
|
||||||
|
|
||||||
vec3 get_sun_dir(float time_of_day) {
|
|
||||||
const float TIME_FACTOR = (PI * 2.0) / (3600.0 * 24.0);
|
|
||||||
|
|
||||||
float sun_angle_rad = time_of_day * TIME_FACTOR;
|
|
||||||
// return vec3(sin(sun_angle_rad), 0.0, cos(sun_angle_rad));
|
|
||||||
return vec3(sin(sun_angle_rad), 0.0, cos(sun_angle_rad));
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3 get_moon_dir(float time_of_day) {
|
|
||||||
const float TIME_FACTOR = (PI * 2.0) / (3600.0 * 24.0);
|
|
||||||
|
|
||||||
float moon_angle_rad = time_of_day * TIME_FACTOR;
|
|
||||||
// -cos((60+60*4)/360*2*pi)-0.5 = 0
|
|
||||||
// -cos((60+60*5)/360*2*pi)-0.5 = -0.5
|
|
||||||
// -cos((60+60*6)/360*2*pi)-0.5 = 0
|
|
||||||
//
|
|
||||||
// i.e. moon out from (60*5)/360*24 = 20:00 to (60*7/360*24) = 28:00 = 04:00.
|
|
||||||
//
|
|
||||||
// Then sun out from 04:00 to 20:00.
|
|
||||||
return normalize(-vec3(sin(moon_angle_rad), 0.0, cos(moon_angle_rad) - 0.5));
|
|
||||||
}
|
|
||||||
|
|
||||||
const float PERSISTENT_AMBIANCE = 1.0 / 512;// 1.0 / 512; // 0.00125 // 0.1;// 0.025; // 0.1;
|
const float PERSISTENT_AMBIANCE = 1.0 / 512;// 1.0 / 512; // 0.00125 // 0.1;// 0.025; // 0.1;
|
||||||
|
|
||||||
float get_sun_brightness(vec3 sun_dir) {
|
//vec3 get_sun_dir(float time_of_day) {
|
||||||
return max(-sun_dir.z + 0.6, 0.0) * 0.9;
|
// const float TIME_FACTOR = (PI * 2.0) / (3600.0 * 24.0);
|
||||||
|
//
|
||||||
|
// float sun_angle_rad = time_of_day * TIME_FACTOR;
|
||||||
|
// // return vec3(sin(sun_angle_rad), 0.0, cos(sun_angle_rad));
|
||||||
|
// return vec3(sin(sun_angle_rad), 0.0, cos(sun_angle_rad));
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//vec3 get_moon_dir(float time_of_day) {
|
||||||
|
// const float TIME_FACTOR = (PI * 2.0) / (3600.0 * 24.0);
|
||||||
|
//
|
||||||
|
// float moon_angle_rad = time_of_day * TIME_FACTOR;
|
||||||
|
// // -cos((60+60*4)/360*2*pi)-0.5 = 0
|
||||||
|
// // -cos((60+60*5)/360*2*pi)-0.5 = -0.5
|
||||||
|
// // -cos((60+60*6)/360*2*pi)-0.5 = 0
|
||||||
|
// //
|
||||||
|
// // i.e. moon out from (60*5)/360*24 = 20:00 to (60*7/360*24) = 28:00 = 04:00.
|
||||||
|
// //
|
||||||
|
// // Then sun out from 04:00 to 20:00.
|
||||||
|
// return normalize(-vec3(sin(moon_angle_rad), 0.0, cos(moon_angle_rad) - 0.5));
|
||||||
|
//}
|
||||||
|
|
||||||
|
float get_sun_brightness(/*vec3 sun_dir*/) {
|
||||||
|
return max(-sun_dir.z + 0.6, 0.0) * 0.9;
|
||||||
}
|
}
|
||||||
|
|
||||||
float get_moon_brightness(vec3 moon_dir) {
|
float get_moon_brightness(/*vec3 moon_dir*/) {
|
||||||
return max(-moon_dir.z + 0.6, 0.0) * 0.007;
|
return max(-moon_dir.z + 0.6, 0.0) * 0.007;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 get_sun_color(vec3 sun_dir) {
|
vec3 get_sun_color(/*vec3 sun_dir*/) {
|
||||||
return mix(
|
return mix(
|
||||||
mix(
|
mix(
|
||||||
DUSK_LIGHT,
|
DUSK_LIGHT,
|
||||||
NIGHT_LIGHT,
|
NIGHT_LIGHT,
|
||||||
max(sun_dir.z, 0)
|
max(sun_dir.z, 0)
|
||||||
),
|
),
|
||||||
DAY_LIGHT,
|
DAY_LIGHT,
|
||||||
max(-sun_dir.z, 0)
|
max(-sun_dir.z, 0)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 get_moon_color(vec3 moon_dir) {
|
vec3 get_moon_color(/*vec3 moon_dir*/) {
|
||||||
return vec3(0.05, 0.05, 0.6);
|
return vec3(0.05, 0.05, 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
DirectionalLight get_sun_info(vec4 _dir, float shade_frac/*, vec4 light_pos[2]*/, /*vec4 sun_pos*/vec3 f_pos) {
|
||||||
|
float shadow = shade_frac;
|
||||||
|
#ifdef HAS_SHADOW_MAPS
|
||||||
|
#if (SHADOW_MODE == SHADOW_MODE_MAP)
|
||||||
|
if (sun_dir.z < /*0.6*/0.0) {
|
||||||
|
/* ShadowLocals sun_shadow = shadowMats[0];
|
||||||
|
vec4 sun_pos = sun_shadow.texture_mat * vec4(f_pos, 1.0); */
|
||||||
|
// #if (SHADOW_MODE == SHADOW_MODE_MAP)
|
||||||
|
// // for (uint i = 0u; i < light_shadow_count.z; ++i) {
|
||||||
|
// // light_pos[i] = /*vec3(*/shadowMats[i].texture_mat * vec4(f_pos, 1.0)/*)*/;
|
||||||
|
// // }
|
||||||
|
// #elif (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_NONE)
|
||||||
|
// vec4 sun_pos = vec4(0.0);
|
||||||
|
// #endif
|
||||||
|
shadow = min(shadow, ShadowCalculationDirected(/*sun_pos, *//*0u*/f_pos));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
return DirectionalLight(/*dir, */shade_frac * shadow/*, get_sun_color(dir), get_sun_brightness(dir)*/);
|
||||||
|
}
|
||||||
|
|
||||||
|
DirectionalLight get_moon_info(vec4 _dir, float shade_frac/*, vec4 light_pos[2]*/) {
|
||||||
|
float shadow = shade_frac;
|
||||||
|
// #ifdef HAS_SHADOW_MAPS
|
||||||
|
// shadow = min(shade_frac, ShadowCalculationDirected(light_pos, 1u));
|
||||||
|
// #endif
|
||||||
|
return DirectionalLight(/*dir, */shadow/*, get_moon_color(dir), get_moon_brightness(dir)*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
// // Calculates extra emission and reflectance (due to sunlight / moonlight).
|
// // Calculates extra emission and reflectance (due to sunlight / moonlight).
|
||||||
@ -92,19 +130,19 @@ vec3 get_moon_color(vec3 moon_dir) {
|
|||||||
// // anything interesting here.
|
// // anything interesting here.
|
||||||
// // void get_sun_diffuse(vec3 norm, float time_of_day, out vec3 light, out vec3 diffuse_light, out vec3 ambient_light, float diffusion
|
// // void get_sun_diffuse(vec3 norm, float time_of_day, out vec3 light, out vec3 diffuse_light, out vec3 ambient_light, float diffusion
|
||||||
// void get_sun_diffuse(vec3 norm, float time_of_day, vec3 dir, vec3 k_a, vec3 k_d, vec3 k_s, float alpha, out vec3 emitted_light, out vec3 reflected_light) {
|
// void get_sun_diffuse(vec3 norm, float time_of_day, vec3 dir, vec3 k_a, vec3 k_d, vec3 k_s, float alpha, out vec3 emitted_light, out vec3 reflected_light) {
|
||||||
// const float SUN_AMBIANCE = 0.1 / 2.0;// 0.1 / 3.0;
|
// const float SUN_AMBIANCE = 0.1 / 2.0;// 0.1 / 3.0;
|
||||||
//
|
//
|
||||||
// vec3 sun_dir = get_sun_dir(time_of_day);
|
// vec3 sun_dir = get_sun_dir(time_of_day);
|
||||||
// vec3 moon_dir = get_moon_dir(time_of_day);
|
// vec3 moon_dir = get_moon_dir(time_of_day);
|
||||||
//
|
//
|
||||||
// float sun_light = get_sun_brightness(sun_dir);
|
// float sun_light = get_sun_brightness(sun_dir);
|
||||||
// float moon_light = get_moon_brightness(moon_dir);
|
// float moon_light = get_moon_brightness(moon_dir);
|
||||||
//
|
//
|
||||||
// vec3 sun_color = get_sun_color(sun_dir);
|
// vec3 sun_color = get_sun_color(sun_dir);
|
||||||
// vec3 moon_color = get_moon_color(moon_dir);
|
// vec3 moon_color = get_moon_color(moon_dir);
|
||||||
//
|
//
|
||||||
// vec3 sun_chroma = sun_color * sun_light;
|
// vec3 sun_chroma = sun_color * sun_light;
|
||||||
// vec3 moon_chroma = moon_color * moon_light;
|
// vec3 moon_chroma = moon_color * moon_light;
|
||||||
//
|
//
|
||||||
// /* float NLsun = max(dot(-norm, sun_dir), 0);
|
// /* float NLsun = max(dot(-norm, sun_dir), 0);
|
||||||
// float NLmoon = max(dot(-norm, moon_dir), 0);
|
// float NLmoon = max(dot(-norm, moon_dir), 0);
|
||||||
@ -121,12 +159,12 @@ vec3 get_moon_color(vec3 moon_dir) {
|
|||||||
// sun_chroma * light_reflection_factor(norm, dir, sun_dir, k_d, k_s, alpha) +
|
// sun_chroma * light_reflection_factor(norm, dir, sun_dir, k_d, k_s, alpha) +
|
||||||
// moon_chroma * 1.0 * /*4.0 * */light_reflection_factor(norm, dir, moon_dir, k_d, k_s, alpha);
|
// moon_chroma * 1.0 * /*4.0 * */light_reflection_factor(norm, dir, moon_dir, k_d, k_s, alpha);
|
||||||
//
|
//
|
||||||
// /* light = sun_chroma + moon_chroma + PERSISTENT_AMBIANCE;
|
// /* light = sun_chroma + moon_chroma + PERSISTENT_AMBIANCE;
|
||||||
// diffuse_light =
|
// diffuse_light =
|
||||||
// sun_chroma * mix(1.0, max(dot(-norm, sun_dir) * 0.5 + 0.5, 0.0), diffusion) +
|
// sun_chroma * mix(1.0, max(dot(-norm, sun_dir) * 0.5 + 0.5, 0.0), diffusion) +
|
||||||
// moon_chroma * mix(1.0, pow(dot(-norm, moon_dir) * 2.0, 2.0), diffusion) +
|
// moon_chroma * mix(1.0, pow(dot(-norm, moon_dir) * 2.0, 2.0), diffusion) +
|
||||||
// PERSISTENT_AMBIANCE;
|
// PERSISTENT_AMBIANCE;
|
||||||
// ambient_light = vec3(SUN_AMBIANCE * sun_light + moon_light); */
|
// ambient_light = vec3(SUN_AMBIANCE * sun_light + moon_light); */
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// Returns computed maximum intensity.
|
// Returns computed maximum intensity.
|
||||||
@ -135,22 +173,38 @@ vec3 get_moon_color(vec3 moon_dir) {
|
|||||||
// 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 get_sun_diffuse2(vec3 norm, vec3 sun_dir, vec3 moon_dir, vec3 dir, vec3 wpos, vec3 mu, vec3 cam_attenuation, float surface_alt, vec3 k_a, vec3 k_d, vec3 k_s, float alpha, float voxel_lighting, out vec3 emitted_light, out vec3 reflected_light) {
|
float get_sun_diffuse2(DirectionalLight sun_info, DirectionalLight moon_info, vec3 norm, vec3 dir, vec3 wpos, vec3 mu, vec3 cam_attenuation, float surface_alt, vec3 k_a, vec3 k_d, vec3 k_s, float alpha, vec3 voxel_norm, float voxel_lighting, out vec3 emitted_light, out vec3 reflected_light) {
|
||||||
const vec3 SUN_AMBIANCE = MU_SCATTER;//0.23;/* / 1.8*/;// 0.1 / 3.0;
|
const float MIN_SHADOW = 0.15;
|
||||||
const vec3 MOON_AMBIANCE = MU_SCATTER;//0.23;//0.1;
|
const vec3 SUN_AMBIANCE = MU_SCATTER;//0.23;/* / 1.8*/;// 0.1 / 3.0;
|
||||||
|
const vec3 MOON_AMBIANCE = MU_SCATTER;//0.23;//0.1;
|
||||||
|
|
||||||
float sun_light = get_sun_brightness(sun_dir);
|
/* vec3 sun_dir = sun_info.dir;
|
||||||
float moon_light = get_moon_brightness(moon_dir);
|
vec3 moon_dir = moon_info.dir; */
|
||||||
|
vec3 sun_dir = sun_dir.xyz;
|
||||||
|
vec3 moon_dir = moon_dir.xyz;
|
||||||
|
|
||||||
vec3 sun_color = get_sun_color(sun_dir) * SUN_COLOR_FACTOR;
|
float sun_light = get_sun_brightness(/*sun_dir*/);//sun_info.brightness;;
|
||||||
vec3 moon_color = get_moon_color(moon_dir);
|
float moon_light = get_moon_brightness(/*moon_dir*/);//moon_info.brightness;
|
||||||
|
|
||||||
|
vec3 sun_color = get_sun_color(/*sun_dir*/) * SUN_COLOR_FACTOR;//sun_info.color * SUN_COLOR_FACTOR;
|
||||||
|
vec3 moon_color = get_moon_color(/*moon_dir*/);//moon_info.color;
|
||||||
|
|
||||||
// If the sun is facing the wrong way, we currently just want zero light, hence default point is wpos.
|
// If the sun is facing the wrong way, we currently just want zero light, hence default point is wpos.
|
||||||
vec3 sun_attenuation = compute_attenuation(wpos, -sun_dir, mu, surface_alt, wpos);
|
vec3 sun_attenuation = compute_attenuation(wpos, -sun_dir, mu, surface_alt, wpos);
|
||||||
vec3 moon_attenuation = compute_attenuation(wpos, -moon_dir, mu, surface_alt, wpos);
|
vec3 moon_attenuation = compute_attenuation(wpos, -moon_dir, mu, surface_alt, wpos);
|
||||||
|
|
||||||
vec3 sun_chroma = sun_color * sun_light * cam_attenuation * sun_attenuation;
|
vec3 sun_chroma = sun_color * sun_light * cam_attenuation * sun_attenuation;
|
||||||
vec3 moon_chroma = moon_color * moon_light * cam_attenuation * moon_attenuation;
|
vec3 moon_chroma = moon_color * moon_light * cam_attenuation * moon_attenuation;
|
||||||
|
|
||||||
|
// #ifdef HAS_SHADOW_MAPS
|
||||||
|
// float sun_shadow = ShadowCalculationDirected(light_pos, 0u);
|
||||||
|
// float moon_shadow = ShadowCalculationDirected(light_pos, 1u);
|
||||||
|
// #else
|
||||||
|
// float sun_shadow = 1.0;
|
||||||
|
// float moon_shadow = 1.0;
|
||||||
|
// #endif
|
||||||
|
float sun_shadow = sun_info.shadow;
|
||||||
|
float moon_shadow = moon_info.shadow;
|
||||||
|
|
||||||
// https://en.m.wikipedia.org/wiki/Diffuse_sky_radiation
|
// https://en.m.wikipedia.org/wiki/Diffuse_sky_radiation
|
||||||
//
|
//
|
||||||
@ -239,7 +293,7 @@ float get_sun_diffuse2(vec3 norm, vec3 sun_dir, vec3 moon_dir, vec3 dir, vec3 wp
|
|||||||
vec3 R_t_r = R_d + R_r;
|
vec3 R_t_r = R_d + R_r;
|
||||||
|
|
||||||
// vec3 half_vec = normalize(-norm + dir);
|
// vec3 half_vec = normalize(-norm + dir);
|
||||||
vec3 light_frac = R_t_b * (sun_chroma * SUN_AMBIANCE + moon_chroma * MOON_AMBIANCE) * light_reflection_factor(norm, /*norm*//*dir*/dir, /*-norm*/-dir, /*k_d*/k_d/* * (1.0 - k_s)*/, /*k_s*/vec3(0.0), alpha, voxel_lighting);
|
vec3 light_frac = R_t_b * (sun_chroma * SUN_AMBIANCE + moon_chroma * MOON_AMBIANCE) * light_reflection_factor(norm, /*norm*//*dir*/dir, /*-norm*/-/*dir*/norm, /*k_d*/k_d/* * (1.0 - k_s)*/, /*k_s*/vec3(0.0), alpha, voxel_norm, voxel_lighting);
|
||||||
// vec3 light_frac = /*vec3(1.0)*//*H_d * */
|
// vec3 light_frac = /*vec3(1.0)*//*H_d * */
|
||||||
// SUN_AMBIANCE * /*sun_light*/sun_chroma * light_reflection_factor(norm, dir, /*vec3(0, 0, -1.0)*/-norm, vec3((1.0 + cos_sun) * 0.5), vec3(k_s * (1.0 - cos_sun) * 0.5), alpha) +
|
// SUN_AMBIANCE * /*sun_light*/sun_chroma * light_reflection_factor(norm, dir, /*vec3(0, 0, -1.0)*/-norm, vec3((1.0 + cos_sun) * 0.5), vec3(k_s * (1.0 - cos_sun) * 0.5), alpha) +
|
||||||
// MOON_AMBIANCE * /*sun_light*/moon_chroma * light_reflection_factor(norm, dir, /*vec3(0, 0, -1.0)*/-norm, vec3((1.0 + cos_moon) * 0.5), vec3(k_s * (1.0 - cos_moon) * 0.5), alpha);
|
// MOON_AMBIANCE * /*sun_light*/moon_chroma * light_reflection_factor(norm, dir, /*vec3(0, 0, -1.0)*/-norm, vec3((1.0 + cos_moon) * 0.5), vec3(k_s * (1.0 - cos_moon) * 0.5), alpha);
|
||||||
@ -254,145 +308,160 @@ float get_sun_diffuse2(vec3 norm, vec3 sun_dir, vec3 moon_dir, vec3 dir, vec3 wp
|
|||||||
// float ambient_sides = clamp(mix(0.5, 0.0, abs(dot(-norm, sun_dir)) * mix(0.0, 1.0, abs(sun_dir.z) * 10000.0) * 10000.0), 0.0, 0.5);
|
// float ambient_sides = clamp(mix(0.5, 0.0, abs(dot(-norm, sun_dir)) * mix(0.0, 1.0, abs(sun_dir.z) * 10000.0) * 10000.0), 0.0, 0.5);
|
||||||
// float ambient_sides = clamp(mix(0.5, 0.0, abs(dot(-norm, sun_dir)) * mix(0.0, 1.0, abs(sun_dir.z) * 10000.0) * 10000.0), 0.0, 0.5);
|
// float ambient_sides = clamp(mix(0.5, 0.0, abs(dot(-norm, sun_dir)) * mix(0.0, 1.0, abs(sun_dir.z) * 10000.0) * 10000.0), 0.0, 0.5);
|
||||||
|
|
||||||
emitted_light = k_a * light_frac + PERSISTENT_AMBIANCE;
|
emitted_light = light_frac + k_a * PERSISTENT_AMBIANCE;
|
||||||
// emitted_light = k_a * light_frac * (/*ambient_sides + */SUN_AMBIANCE * /*sun_light*/sun_chroma + /*vec3(moon_light)*/MOON_AMBIANCE * moon_chroma) + PERSISTENT_AMBIANCE;
|
// emitted_light = k_a * light_frac * (/*ambient_sides + */SUN_AMBIANCE * /*sun_light*/sun_chroma + /*vec3(moon_light)*/MOON_AMBIANCE * moon_chroma) + PERSISTENT_AMBIANCE;
|
||||||
|
|
||||||
// TODO: Add shadows.
|
|
||||||
reflected_light = R_t_r * (
|
reflected_light = R_t_r * (
|
||||||
(1.0 - SUN_AMBIANCE) * sun_chroma * (light_reflection_factor(norm, dir, sun_dir, k_d, k_s, alpha, voxel_lighting) /*+
|
(1.0 - SUN_AMBIANCE) * sun_chroma * sun_shadow * (light_reflection_factor(norm, dir, sun_dir, k_d, k_s, alpha, voxel_norm, voxel_lighting) /*+
|
||||||
light_reflection_factor(norm, dir, normalize(sun_dir + vec3(0.0, 0.1, 0.0)), k_d, k_s, alpha) +
|
light_reflection_factor(norm, dir, normalize(sun_dir + vec3(0.0, 0.1, 0.0)), k_d, k_s, alpha) +
|
||||||
light_reflection_factor(norm, dir, normalize(sun_dir - vec3(0.0, 0.1, 0.0)), k_d, k_s, alpha)*/) +
|
light_reflection_factor(norm, dir, normalize(sun_dir - vec3(0.0, 0.1, 0.0)), k_d, k_s, alpha)*/) +
|
||||||
(1.0 - MOON_AMBIANCE) * moon_chroma * 1.0 * /*4.0 * */light_reflection_factor(norm, dir, moon_dir, k_d, k_s, alpha, voxel_lighting)
|
(1.0 - MOON_AMBIANCE) * moon_chroma * moon_shadow * 1.0 * /*4.0 * */light_reflection_factor(norm, dir, moon_dir, k_d, k_s, alpha, voxel_norm, voxel_lighting)
|
||||||
);
|
);
|
||||||
|
|
||||||
/* light = sun_chroma + moon_chroma + PERSISTENT_AMBIANCE;
|
/* light = sun_chroma + moon_chroma + PERSISTENT_AMBIANCE;
|
||||||
diffuse_light =
|
diffuse_light =
|
||||||
sun_chroma * mix(1.0, max(dot(-norm, sun_dir) * 0.5 + 0.5, 0.0), diffusion) +
|
sun_chroma * mix(1.0, max(dot(-norm, sun_dir) * 0.5 + 0.5, 0.0), diffusion) +
|
||||||
moon_chroma * mix(1.0, pow(dot(-norm, moon_dir) * 2.0, 2.0), diffusion) +
|
moon_chroma * mix(1.0, pow(dot(-norm, moon_dir) * 2.0, 2.0), diffusion) +
|
||||||
PERSISTENT_AMBIANCE;
|
PERSISTENT_AMBIANCE;
|
||||||
ambient_light = vec3(SUN_AMBIANCE * sun_light + moon_light); */
|
ambient_light = vec3(SUN_AMBIANCE * sun_light + moon_light); */
|
||||||
return rel_luminance(emitted_light + reflected_light);//rel_luminance(emitted_light + reflected_light);//sun_chroma + moon_chroma + PERSISTENT_AMBIANCE;
|
return rel_luminance(emitted_light + reflected_light);//rel_luminance(emitted_light + reflected_light);//sun_chroma + moon_chroma + PERSISTENT_AMBIANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
float get_sun_diffuse2(vec3 norm, vec3 sun_dir, vec3 moon_dir, vec3 dir, vec3 k_a, vec3 k_d, vec3 k_s, float alpha, float voxel_lighting, out vec3 emitted_light, out vec3 reflected_light) {
|
float get_sun_diffuse2(DirectionalLight sun_info, DirectionalLight moon_info, vec3 norm, vec3 dir, vec3 k_a, vec3 k_d, vec3 k_s, float alpha, vec3 voxel_norm, float voxel_lighting, out vec3 emitted_light, out vec3 reflected_light) {
|
||||||
return get_sun_diffuse2(norm, sun_dir, moon_dir, dir, vec3(0.0), vec3(0.0), vec3(1.0), 0.0, k_a, k_d, k_s, alpha, voxel_lighting, emitted_light, reflected_light);
|
return get_sun_diffuse2(sun_info, moon_info, norm, dir, vec3(0.0), vec3(0.0), vec3(1.0), 0.0, k_a, k_d, k_s, alpha, voxel_norm, voxel_lighting, emitted_light, reflected_light);
|
||||||
}
|
}
|
||||||
|
|
||||||
float get_sun_diffuse2(vec3 norm, vec3 sun_dir, vec3 moon_dir, vec3 dir, vec3 k_a, vec3 k_d, vec3 k_s, float alpha, out vec3 emitted_light, out vec3 reflected_light) {
|
float get_sun_diffuse2(DirectionalLight sun_info, DirectionalLight moon_info, vec3 norm, vec3 dir, vec3 k_a, vec3 k_d, vec3 k_s, float alpha, out vec3 emitted_light, out vec3 reflected_light) {
|
||||||
return get_sun_diffuse2(norm, sun_dir, moon_dir, dir, vec3(0.0), vec3(0.0), vec3(1.0), 0.0, k_a, k_d, k_s, alpha, 1.0, emitted_light, reflected_light);
|
return get_sun_diffuse2(sun_info, moon_info, norm, dir, vec3(0.0), vec3(0.0), vec3(1.0), 0.0, k_a, k_d, k_s, alpha, norm, 1.0, emitted_light, reflected_light);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This has been extracted into a function to allow quick exit when detecting a star.
|
// This has been extracted into a function to allow quick exit when detecting a star.
|
||||||
float is_star_at(vec3 dir) {
|
float is_star_at(vec3 dir) {
|
||||||
float star_scale = 80.0;
|
float star_scale = 80.0;
|
||||||
|
|
||||||
// Star positions
|
// Star positions
|
||||||
vec3 pos = (floor(dir * star_scale) - 0.5) / star_scale;
|
vec3 pos = (floor(dir * star_scale) - 0.5) / star_scale;
|
||||||
|
|
||||||
// Noisy offsets
|
// Noisy offsets
|
||||||
pos += (3.0 / star_scale) * /*rand_perm_3*/hash(vec4(pos, 1.0));
|
pos += (3.0 / star_scale) * /*rand_perm_3*/hash(vec4(pos, 1.0));
|
||||||
|
|
||||||
// Find distance to fragment
|
// Find distance to fragment
|
||||||
float dist = length(normalize(pos) - dir);
|
float dist = length(normalize(pos) - dir);
|
||||||
|
|
||||||
// Star threshold
|
// Star threshold
|
||||||
if (dist < 0.0015) {
|
if (dist < 0.0015) {
|
||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 get_sky_color(vec3 dir, float time_of_day, vec3 origin, vec3 f_pos, float quality, bool with_stars, float refractionIndex, out vec4 clouds) {
|
vec3 get_sky_color(vec3 dir, float time_of_day, vec3 origin, vec3 f_pos, float quality, bool with_stars, float refractionIndex, out vec4 clouds) {
|
||||||
// Sky color
|
#if (CLOUD_MODE == CLOUD_MODE_NONE)
|
||||||
vec3 sun_dir = get_sun_dir(time_of_day);
|
const bool has_clouds = false;
|
||||||
vec3 moon_dir = get_moon_dir(time_of_day);
|
#elif (CLOUD_MODE == CLOUD_MODE_REGULAR)
|
||||||
|
const bool has_clouds = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
// sun_dir = sun_dir.z <= 0 ? refract(sun_dir/*-view_dir*/, vec3(0.0, 0.0, 1.0), refractionIndex) : sun_dir;
|
if (with_stars || has_clouds) {
|
||||||
// moon_dir = moon_dir.z <= 0 ? refract(moon_dir/*-view_dir*/, vec3(0.0, 0.0, 1.0), refractionIndex) : moon_dir;
|
// Sky color
|
||||||
|
/* vec3 sun_dir = get_sun_dir(time_of_day);
|
||||||
|
vec3 moon_dir = get_moon_dir(time_of_day); */
|
||||||
|
vec3 sun_dir = sun_dir.xyz;
|
||||||
|
vec3 moon_dir = moon_dir.xyz;
|
||||||
|
|
||||||
// Add white dots for stars. Note these flicker and jump due to FXAA
|
// sun_dir = sun_dir.z <= 0 ? refract(sun_dir/*-view_dir*/, vec3(0.0, 0.0, 1.0), refractionIndex) : sun_dir;
|
||||||
float star = 0.0;
|
// moon_dir = moon_dir.z <= 0 ? refract(moon_dir/*-view_dir*/, vec3(0.0, 0.0, 1.0), refractionIndex) : moon_dir;
|
||||||
if (with_stars) {
|
|
||||||
vec3 star_dir = normalize(sun_dir * dir.z + cross(sun_dir, vec3(0, 1, 0)) * dir.x + vec3(0, 1, 0) * dir.y);
|
|
||||||
star = is_star_at(star_dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sun
|
// Add white dots for stars. Note these flicker and jump due to FXAA
|
||||||
const vec3 SUN_SURF_COLOR = vec3(1.5, 0.9, 0.35) * 200.0;
|
float star = 0.0;
|
||||||
|
if (with_stars || has_clouds) {
|
||||||
|
vec3 star_dir = normalize(sun_dir * dir.z + cross(sun_dir, vec3(0, 1, 0)) * dir.x + vec3(0, 1, 0) * dir.y);
|
||||||
|
star = is_star_at(star_dir);
|
||||||
|
}
|
||||||
|
|
||||||
vec3 sun_halo_color = mix(
|
// Sun
|
||||||
SUN_HALO_DUSK,
|
const vec3 SUN_SURF_COLOR = vec3(1.5, 0.9, 0.35) * 200.0;
|
||||||
SUN_HALO_DAY,
|
|
||||||
max(-sun_dir.z, 0)
|
|
||||||
);
|
|
||||||
|
|
||||||
vec3 sun_halo = pow(max(dot(dir, -sun_dir) + 0.1, 0.0), 8.0) * sun_halo_color;
|
vec3 sun_halo_color = mix(
|
||||||
vec3 sun_surf = pow(max(dot(dir, -sun_dir) - 0.001, 0.0), 3000.0) * SUN_SURF_COLOR * SUN_COLOR_FACTOR;
|
SUN_HALO_DUSK,
|
||||||
vec3 sun_light = (sun_halo + sun_surf) * clamp(dir.z * 10.0, 0, 1);
|
SUN_HALO_DAY,
|
||||||
|
max(-sun_dir.z, 0)
|
||||||
|
);
|
||||||
|
|
||||||
// Moon
|
vec3 sun_halo = pow(max(dot(dir, -sun_dir) + 0.1, 0.0), 8.0) * sun_halo_color;
|
||||||
const vec3 MOON_SURF_COLOR = vec3(0.7, 1.0, 1.5) * 500.0;
|
vec3 sun_surf = pow(max(dot(dir, -sun_dir) - 0.001, 0.0), 3000.0) * SUN_SURF_COLOR * SUN_COLOR_FACTOR;
|
||||||
const vec3 MOON_HALO_COLOR = vec3(0.015, 0.015, 0.05);
|
vec3 sun_light = (sun_halo + sun_surf) * clamp(dir.z * 10.0, 0, 1);
|
||||||
|
|
||||||
vec3 moon_halo = pow(max(dot(dir, -moon_dir) + 0.1, 0.0), 8.0) * MOON_HALO_COLOR;
|
// Moon
|
||||||
vec3 moon_surf = pow(max(dot(dir, -moon_dir) - 0.001, 0.0), 3000.0) * MOON_SURF_COLOR;
|
const vec3 MOON_SURF_COLOR = vec3(0.7, 1.0, 1.5) * 500.0;
|
||||||
vec3 moon_light = clamp(moon_halo + moon_surf, vec3(0), vec3(max(dir.z * 3.0, 0)));
|
const vec3 MOON_HALO_COLOR = vec3(0.015, 0.015, 0.05);
|
||||||
|
|
||||||
// Replaced all clamp(sun_dir, 0, 1) with max(sun_dir, 0) because sun_dir is calculated from sin and cos, which are never > 1
|
vec3 moon_halo = pow(max(dot(dir, -moon_dir) + 0.1, 0.0), 8.0) * MOON_HALO_COLOR;
|
||||||
|
vec3 moon_surf = pow(max(dot(dir, -moon_dir) - 0.001, 0.0), 3000.0) * MOON_SURF_COLOR;
|
||||||
|
vec3 moon_light = clamp(moon_halo + moon_surf, vec3(0), vec3(max(dir.z * 3.0, 0)));
|
||||||
|
|
||||||
vec3 sky_top = mix(
|
// Replaced all clamp(sun_dir, 0, 1) with max(sun_dir, 0) because sun_dir is calculated from sin and cos, which are never > 1
|
||||||
mix(
|
|
||||||
SKY_DUSK_TOP + star / (1.0 + moon_surf * 100.0),
|
|
||||||
SKY_NIGHT_TOP + star / (1.0 + moon_surf * 100.0),
|
|
||||||
max(pow(sun_dir.z, 0.2), 0)
|
|
||||||
),
|
|
||||||
SKY_DAY_TOP,
|
|
||||||
max(-sun_dir.z, 0)
|
|
||||||
);
|
|
||||||
|
|
||||||
vec3 sky_mid = mix(
|
vec3 sky_top = mix(
|
||||||
mix(
|
mix(
|
||||||
SKY_DUSK_MID,
|
SKY_DUSK_TOP + star / (1.0 + moon_surf * 100.0),
|
||||||
SKY_NIGHT_MID,
|
SKY_NIGHT_TOP + star / (1.0 + moon_surf * 100.0),
|
||||||
max(pow(sun_dir.z, 0.2), 0)
|
max(pow(sun_dir.z, 0.2), 0)
|
||||||
),
|
),
|
||||||
SKY_DAY_MID,
|
SKY_DAY_TOP,
|
||||||
max(-sun_dir.z, 0)
|
max(-sun_dir.z, 0)
|
||||||
);
|
);
|
||||||
|
|
||||||
vec3 sky_bot = mix(
|
vec3 sky_mid = mix(
|
||||||
mix(
|
mix(
|
||||||
SKY_DUSK_BOT,
|
SKY_DUSK_MID,
|
||||||
SKY_NIGHT_BOT,
|
SKY_NIGHT_MID,
|
||||||
max(pow(sun_dir.z, 0.2), 0)
|
max(pow(sun_dir.z, 0.2), 0)
|
||||||
),
|
),
|
||||||
SKY_DAY_BOT,
|
SKY_DAY_MID,
|
||||||
max(-sun_dir.z, 0)
|
max(-sun_dir.z, 0)
|
||||||
);
|
);
|
||||||
|
|
||||||
vec3 sky_color = mix(
|
vec3 sky_bot = mix(
|
||||||
mix(
|
mix(
|
||||||
sky_mid,
|
SKY_DUSK_BOT,
|
||||||
sky_bot,
|
SKY_NIGHT_BOT,
|
||||||
pow(max(-dir.z, 0), 0.4)
|
max(pow(sun_dir.z, 0.2), 0)
|
||||||
),
|
),
|
||||||
sky_top,
|
SKY_DAY_BOT,
|
||||||
max(dir.z, 0)
|
max(-sun_dir.z, 0)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Approximate distance to fragment
|
vec3 sky_color = mix(
|
||||||
float f_dist = distance(origin, f_pos);
|
mix(
|
||||||
|
sky_mid,
|
||||||
|
sky_bot,
|
||||||
|
pow(max(-dir.z, 0), 0.4)
|
||||||
|
),
|
||||||
|
sky_top,
|
||||||
|
max(dir.z, 0)
|
||||||
|
);
|
||||||
|
|
||||||
// Clouds
|
// Approximate distance to fragment
|
||||||
clouds = get_cloud_color(dir, origin, time_of_day, f_dist, quality);
|
float f_dist = distance(origin, f_pos);
|
||||||
clouds.rgb *= get_sun_brightness(sun_dir) * (sun_halo * 1.5 + get_sun_color(sun_dir)) + get_moon_brightness(moon_dir) * (moon_halo * 80.0 + get_moon_color(moon_dir) + 0.25);
|
|
||||||
|
|
||||||
if (f_dist > 5000.0) {
|
// Clouds
|
||||||
sky_color += sun_light + moon_light;
|
#if (CLOUD_MODE == CLOUD_MODE_NONE)
|
||||||
}
|
clouds = vec4(0.0);
|
||||||
|
#elif (CLOUD_MODE == CLOUD_MODE_REGULAR)
|
||||||
|
clouds = get_cloud_color(dir, origin, time_of_day, f_dist, quality);
|
||||||
|
clouds.rgb *= get_sun_brightness(/*sun_dir*/) * (sun_halo * 1.5 + get_sun_color(/*sun_dir*/)) + get_moon_brightness(/*moon_dir*/) * (moon_halo * 80.0 + get_moon_color(/*moon_dir*/) + 0.25);
|
||||||
|
#endif
|
||||||
|
|
||||||
return mix(sky_color, clouds.rgb, clouds.a);
|
if (f_dist > 5000.0) {
|
||||||
|
sky_color += sun_light + moon_light;
|
||||||
|
}
|
||||||
|
return mix(sky_color, clouds.rgb, clouds.a);
|
||||||
|
} else {
|
||||||
|
clouds = vec4(0.0);
|
||||||
|
return vec3(0.0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 get_sky_color(vec3 dir, float time_of_day, vec3 origin, vec3 f_pos, float quality, bool with_stars, out vec4 clouds) {
|
vec3 get_sky_color(vec3 dir, float time_of_day, vec3 origin, vec3 f_pos, float quality, bool with_stars, out vec4 clouds) {
|
||||||
@ -400,30 +469,31 @@ vec3 get_sky_color(vec3 dir, float time_of_day, vec3 origin, vec3 f_pos, float q
|
|||||||
}
|
}
|
||||||
|
|
||||||
float fog(vec3 f_pos, vec3 focus_pos, uint medium) {
|
float fog(vec3 f_pos, vec3 focus_pos, uint medium) {
|
||||||
return max(1.0 - 5000.0 / (1.0 + distance(f_pos.xy, focus_pos.xy)), 0.0);
|
return max(1.0 - 5000.0 / (1.0 + distance(f_pos.xy, focus_pos.xy)), 0.0);
|
||||||
|
|
||||||
float fog_radius = view_distance.x;
|
float fog_radius = view_distance.x;
|
||||||
float mist_radius = 10000000.0;
|
float mist_radius = 10000000.0;
|
||||||
|
|
||||||
float min_fog = 0.5;
|
float min_fog = 0.5;
|
||||||
float max_fog = 1.0;
|
float max_fog = 1.0;
|
||||||
|
|
||||||
if (medium == 1u) {
|
if (medium == 1u) {
|
||||||
mist_radius = UNDERWATER_MIST_DIST;
|
mist_radius = UNDERWATER_MIST_DIST;
|
||||||
min_fog = 0.0;
|
min_fog = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
float fog = distance(f_pos.xy, focus_pos.xy) / fog_radius;
|
float fog = distance(f_pos.xy, focus_pos.xy) / fog_radius;
|
||||||
float mist = distance(f_pos, focus_pos) / mist_radius;
|
float mist = distance(f_pos, focus_pos) / mist_radius;
|
||||||
|
|
||||||
return pow(clamp((max(fog, mist) - min_fog) / (max_fog - min_fog), 0.0, 1.0), 1.7);
|
return pow(clamp((max(fog, mist) - min_fog) / (max_fog - min_fog), 0.0, 1.0), 1.7);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* vec3 illuminate(vec3 color, vec3 light, vec3 diffuse, vec3 ambience) {
|
/* vec3 illuminate(vec3 color, vec3 light, vec3 diffuse, vec3 ambience) {
|
||||||
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 view_dir, /*vec3 max_light, */vec3 emitted, vec3 reflected) {
|
vec3 illuminate(float max_light, vec3 view_dir, /*vec3 max_light, */vec3 emitted, vec3 reflected) {
|
||||||
|
return emitted + 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;
|
||||||
@ -446,25 +516,25 @@ vec3 illuminate(float max_light, vec3 view_dir, /*vec3 max_light, */vec3 emitted
|
|||||||
float lum = rel_luminance(color);
|
float lum = rel_luminance(color);
|
||||||
// float lum_sky = lum - max_light;
|
// float lum_sky = lum - max_light;
|
||||||
|
|
||||||
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); */
|
||||||
float sky_light = rel_luminance(
|
float sky_light = rel_luminance(
|
||||||
get_sun_color(sun_dir) * get_sun_brightness(sun_dir) * SUN_COLOR_FACTOR +
|
get_sun_color(/*sun_dir*/) * get_sun_brightness(/*sun_dir*/) * SUN_COLOR_FACTOR +
|
||||||
get_moon_color(moon_dir) * get_moon_brightness(moon_dir));
|
get_moon_color(/*moon_dir*/) * get_moon_brightness(/*moon_dir*/));
|
||||||
|
|
||||||
// Tone mapped value.
|
// Tone mapped value.
|
||||||
// vec3 T = /*color*//*lum*/color;//normalize(color) * lum / (1.0 + lum);
|
// vec3 T = /*color*//*lum*/color;//normalize(color) * lum / (1.0 + lum);
|
||||||
// float alpha = 0.5;//2.0;
|
// float alpha = 0.5;//2.0;
|
||||||
float alpha = mix(
|
float alpha = mix(
|
||||||
mix(
|
mix(
|
||||||
DUSK_EXPOSURE,
|
DUSK_EXPOSURE,
|
||||||
NIGHT_EXPOSURE,
|
NIGHT_EXPOSURE,
|
||||||
max(sun_dir.z, 0)
|
max(sun_dir.z, 0)
|
||||||
),
|
),
|
||||||
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;
|
vec3 now_light = moon_dir.z < 0 ? moon_dir.xyz : sun_dir.xyz;
|
||||||
float cos_view_light = dot(-now_light, view_dir);
|
float cos_view_light = dot(-now_light, view_dir);
|
||||||
// alpha *= exp(1.0 - cos_view_light);
|
// alpha *= exp(1.0 - cos_view_light);
|
||||||
// sky_light *= 1.0 - log(1.0 + view_dir.z);
|
// sky_light *= 1.0 - log(1.0 + view_dir.z);
|
||||||
@ -497,14 +567,14 @@ vec3 illuminate(float max_light, vec3 view_dir, /*vec3 max_light, */vec3 emitted
|
|||||||
// Heuristic desaturation
|
// Heuristic desaturation
|
||||||
// const float s = 0.8;
|
// const float s = 0.8;
|
||||||
float s = mix(
|
float s = mix(
|
||||||
mix(
|
mix(
|
||||||
DUSK_SATURATION,
|
DUSK_SATURATION,
|
||||||
NIGHT_SATURATION,
|
NIGHT_SATURATION,
|
||||||
max(sun_dir.z, 0)
|
max(sun_dir.z, 0)
|
||||||
),
|
),
|
||||||
DAY_SATURATION,
|
DAY_SATURATION,
|
||||||
max(-sun_dir.z, 0)
|
max(-sun_dir.z, 0)
|
||||||
);
|
);
|
||||||
// s = max(s, (max_light) / (1.0 + s));
|
// s = max(s, (max_light) / (1.0 + s));
|
||||||
s = max(s, max_light / (1.0 + max_light));
|
s = max(s, max_light / (1.0 + max_light));
|
||||||
|
|
||||||
|
@ -2,6 +2,23 @@
|
|||||||
// See https://en.wikipedia.org/wiki/Electromagnetic_absorption_by_water
|
// See https://en.wikipedia.org/wiki/Electromagnetic_absorption_by_water
|
||||||
const vec3 MU_WATER = vec3(0.6, 0.04, 0.01);
|
const vec3 MU_WATER = vec3(0.6, 0.04, 0.01);
|
||||||
|
|
||||||
|
// // NOTE: Automatic in v4.0
|
||||||
|
// float
|
||||||
|
// mip_map_level(in vec2 texture_coordinate)
|
||||||
|
// {
|
||||||
|
// // The OpenGL Graphics System: A Specification 4.2
|
||||||
|
// // - chapter 3.9.11, equation 3.21
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// vec2 dx_vtc = dFdx(texture_coordinate);
|
||||||
|
// vec2 dy_vtc = dFdy(texture_coordinate);
|
||||||
|
// float delta_max_sqr = max(dot(dx_vtc, dx_vtc), dot(dy_vtc, dy_vtc));
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// //return max(0.0, 0.5 * log2(delta_max_sqr) - 1.0); // == log2(sqrt(delta_max_sqr));
|
||||||
|
// return 0.5 * log2(delta_max_sqr); // == log2(sqrt(delta_max_sqr));
|
||||||
|
// }
|
||||||
|
|
||||||
//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));
|
||||||
@ -53,8 +70,8 @@ float BeckmannDistribution_D(float NdotH, float alpha) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Voxel Distribution
|
// Voxel Distribution
|
||||||
float BeckmannDistribution_D_Voxel(vec3 wh, vec3 norm, float alpha) {
|
float BeckmannDistribution_D_Voxel(vec3 wh, vec3 voxel_norm, float alpha) {
|
||||||
vec3 sides = sign(norm);
|
vec3 sides = sign(voxel_norm);
|
||||||
// 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);
|
||||||
|
|
||||||
@ -64,7 +81,7 @@ float BeckmannDistribution_D_Voxel(vec3 wh, vec3 norm, float alpha) {
|
|||||||
vec3 NdotH2 = NdotH * NdotH;
|
vec3 NdotH2 = NdotH * NdotH;
|
||||||
vec3 NdotH2m2 = NdotH2 * alpha * alpha;
|
vec3 NdotH2m2 = NdotH2 * alpha * alpha;
|
||||||
vec3 k_spec = exp((NdotH2 - 1) / NdotH2m2) / (PI * NdotH2m2 * NdotH2);
|
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));
|
return dot(mix(k_spec, /*cos_sides_o*/vec3(0.0), equal(NdotH, vec3(0.0))), /*cos_sides_i*/abs(voxel_norm));
|
||||||
// // const float PI = 3.1415926535897932384626433832795;
|
// // const float PI = 3.1415926535897932384626433832795;
|
||||||
// const vec3 normals[6] = vec3[](vec3(1,0,0), vec3(0,1,0), vec3(0,0,1), vec3(-1,0,0), vec3(0,-1,0), vec3(0,0,-1));
|
// const vec3 normals[6] = vec3[](vec3(1,0,0), vec3(0,1,0), vec3(0,0,1), vec3(-1,0,0), vec3(0,-1,0), vec3(0,0,-1));
|
||||||
|
|
||||||
@ -100,8 +117,8 @@ 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) {
|
float TrowbridgeReitzDistribution_D_Voxel(vec3 wh, vec3 voxel_norm, float alpha) {
|
||||||
vec3 sides = sign(norm);
|
vec3 sides = sign(voxel_norm);
|
||||||
// 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);
|
||||||
|
|
||||||
@ -118,7 +135,7 @@ float TrowbridgeReitzDistribution_D_Voxel(vec3 wh, vec3 norm, float alpha) {
|
|||||||
vec3 e = (1 - NdotH2) / NdotH2m2;
|
vec3 e = (1 - NdotH2) / NdotH2m2;
|
||||||
vec3 k_spec = 1.0 / (PI * NdotH2m2 * NdotH2 * (1 + e) * (1 + e));
|
vec3 k_spec = 1.0 / (PI * NdotH2m2 * NdotH2 * (1 + e) * (1 + e));
|
||||||
// vec3 k_spec = exp((NdotH2 - 1) / NdotH2m2) / (PI * NdotH2m2 * NdotH2);
|
// 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));
|
return dot(mix(k_spec, /*cos_sides_o*/vec3(0.0), equal(NdotH, vec3(0.0))), /*cos_sides_i*/abs(voxel_norm));
|
||||||
}
|
}
|
||||||
|
|
||||||
float BeckmannDistribution_Lambda(vec3 norm, vec3 dir, float alpha) {
|
float BeckmannDistribution_Lambda(vec3 norm, vec3 dir, float alpha) {
|
||||||
@ -223,7 +240,7 @@ vec3 FresnelBlend_f(vec3 norm, vec3 dir, vec3 light_dir, vec3 R_d, vec3 R_s, flo
|
|||||||
// http://www.pbr-book.org/3ed-2018/Reflection_Models/Microfacet_Models.html#fragment-MicrofacetDistributionPublicMethods-2
|
// http://www.pbr-book.org/3ed-2018/Reflection_Models/Microfacet_Models.html#fragment-MicrofacetDistributionPublicMethods-2
|
||||||
// and
|
// and
|
||||||
// http://www.pbr-book.org/3ed-2018/Reflection_Models/Fresnel_Incidence_Effects.html
|
// http://www.pbr-book.org/3ed-2018/Reflection_Models/Fresnel_Incidence_Effects.html
|
||||||
vec3 FresnelBlend_Voxel_f(vec3 norm, vec3 dir, vec3 light_dir, vec3 R_d, vec3 R_s, float alpha, float dist) {
|
vec3 FresnelBlend_Voxel_f(vec3 norm, vec3 dir, vec3 light_dir, vec3 R_d, vec3 R_s, float alpha, vec3 voxel_norm, float dist) {
|
||||||
const float PI = 3.1415926535897932384626433832795;
|
const float PI = 3.1415926535897932384626433832795;
|
||||||
alpha = alpha * sqrt(2.0);
|
alpha = alpha * sqrt(2.0);
|
||||||
float cos_wi = /*max(*/dot(-light_dir, norm)/*, 0.0)*/;
|
float cos_wi = /*max(*/dot(-light_dir, norm)/*, 0.0)*/;
|
||||||
@ -233,7 +250,7 @@ vec3 FresnelBlend_Voxel_f(vec3 norm, vec3 dir, vec3 light_dir, vec3 R_d, vec3 R_
|
|||||||
vec4 AbsNdotL = abs(vec4(light_dir, cos_wi));
|
vec4 AbsNdotL = abs(vec4(light_dir, cos_wi));
|
||||||
vec4 AbsNdotV = abs(vec4(dir, cos_wo));
|
vec4 AbsNdotV = abs(vec4(dir, cos_wo));
|
||||||
#else
|
#else
|
||||||
vec3 sides = sign(norm);
|
vec3 sides = sign(voxel_norm);
|
||||||
vec4 AbsNdotL = vec4(max(-light_dir * sides, 0.0), abs(cos_wi));
|
vec4 AbsNdotL = vec4(max(-light_dir * sides, 0.0), abs(cos_wi));
|
||||||
vec4 AbsNdotV = vec4(max(dir * sides, 0.0), abs(cos_wo));
|
vec4 AbsNdotV = vec4(max(dir * sides, 0.0), abs(cos_wo));
|
||||||
#endif
|
#endif
|
||||||
@ -288,8 +305,8 @@ vec3 FresnelBlend_Voxel_f(vec3 norm, vec3 dir, vec3 light_dir, vec3 R_d, vec3 R_
|
|||||||
}
|
}
|
||||||
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 = TrowbridgeReitzDistribution_D_Voxel(wh, voxel_norm, alpha);
|
||||||
float distr = BeckmannDistribution_D_Voxel(wh, norm, alpha);
|
float distr = BeckmannDistribution_D_Voxel(wh, voxel_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) *
|
||||||
@ -365,67 +382,67 @@ vec3 light_reflection_factor2(vec3 norm, vec3 dir, vec3 light_dir, vec3 k_d, vec
|
|||||||
// // return vec3(0.0);
|
// // return vec3(0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 light_reflection_factor(vec3 norm, vec3 dir, vec3 light_dir, vec3 k_d, vec3 k_s, float alpha, float voxel_lighting) {
|
vec3 light_reflection_factor(vec3 norm, vec3 dir, vec3 light_dir, vec3 k_d, vec3 k_s, float alpha, vec3 voxel_norm, float voxel_lighting) {
|
||||||
#if (LIGHTING_ALGORITHM == LIGHTING_ALGORITHM_LAMBERTIAN)
|
#if (LIGHTING_ALGORITHM == LIGHTING_ALGORITHM_LAMBERTIAN)
|
||||||
const float PI = 3.141592;
|
const float PI = 3.141592;
|
||||||
#if (LIGHTING_DISTRIBUTION_SCHEME == LIGHTING_DISTRIBUTION_SCHEME_VOXEL)
|
#if (LIGHTING_DISTRIBUTION_SCHEME == LIGHTING_DISTRIBUTION_SCHEME_VOXEL)
|
||||||
#if (LIGHTING_TYPE & LIGHTING_TYPE_TRANSMISSION) != 0
|
#if (LIGHTING_TYPE & LIGHTING_TYPE_TRANSMISSION) != 0
|
||||||
vec4 AbsNdotL = abs(vec4(light_dir, dot(norm, light_dir)));
|
vec4 AbsNdotL = abs(vec4(light_dir, dot(norm, light_dir)));
|
||||||
#else
|
#else
|
||||||
vec3 sides = sign(norm);
|
vec3 sides = sign(voxel_norm);
|
||||||
vec4 AbsNdotL = max(vec4(-light_dir * sides, dot(norm, -light_dir)), 0.0);
|
vec4 AbsNdotL = max(vec4(-light_dir * sides, dot(norm, -light_dir)), 0.0);
|
||||||
#endif
|
#endif
|
||||||
float diffuse = dot(AbsNdotL, vec4(abs(norm) * (1.0 - voxel_lighting), voxel_lighting));
|
float diffuse = dot(AbsNdotL, vec4(abs(voxel_norm) * (1.0 - voxel_lighting), voxel_lighting));
|
||||||
#elif (LIGHTING_DISTRIBUTION_SCHEME == LIGHTING_DISTRIBUTION_SCHEME_MICROFACET)
|
#elif (LIGHTING_DISTRIBUTION_SCHEME == LIGHTING_DISTRIBUTION_SCHEME_MICROFACET)
|
||||||
#if (LIGHTING_TYPE & LIGHTING_TYPE_TRANSMISSION) != 0
|
#if (LIGHTING_TYPE & LIGHTING_TYPE_TRANSMISSION) != 0
|
||||||
float diffuse = abs(dot(norm, light_dir));
|
float diffuse = abs(dot(norm, light_dir));
|
||||||
#else
|
#else
|
||||||
float diffuse = max(dot(norm, -light_dir), 0.0);
|
float diffuse = max(dot(norm, -light_dir), 0.0);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
return k_d / PI * diffuse;
|
return k_d / PI * diffuse;
|
||||||
#elif (LIGHTING_ALGORITHM == LIGHTING_ALGORITHM_BLINN_PHONG)
|
#elif (LIGHTING_ALGORITHM == LIGHTING_ALGORITHM_BLINN_PHONG)
|
||||||
const float PI = 3.141592;
|
const float PI = 3.141592;
|
||||||
alpha = alpha * sqrt(2.0);
|
alpha = alpha * sqrt(2.0);
|
||||||
#if (LIGHTING_TYPE & LIGHTING_TYPE_TRANSMISSION) != 0
|
#if (LIGHTING_TYPE & LIGHTING_TYPE_TRANSMISSION) != 0
|
||||||
float ndotL = abs(dot(norm, light_dir));
|
float ndotL = abs(dot(norm, light_dir));
|
||||||
#else
|
#else
|
||||||
float ndotL = max(dot(norm, -light_dir), 0.0);
|
float ndotL = max(dot(norm, -light_dir), 0.0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (ndotL > 0.0) {
|
if (ndotL > 0.0) {
|
||||||
#if (LIGHTING_DISTRIBUTION_SCHEME == LIGHTING_DISTRIBUTION_SCHEME_VOXEL)
|
#if (LIGHTING_DISTRIBUTION_SCHEME == LIGHTING_DISTRIBUTION_SCHEME_VOXEL)
|
||||||
#if (LIGHTING_TYPE & LIGHTING_TYPE_TRANSMISSION) != 0
|
#if (LIGHTING_TYPE & LIGHTING_TYPE_TRANSMISSION) != 0
|
||||||
vec4 AbsNdotL = abs(vec4(light_dir, ndotL));
|
vec4 AbsNdotL = abs(vec4(light_dir, ndotL));
|
||||||
#else
|
#else
|
||||||
vec3 sides = sign(norm);
|
vec3 sides = sign(voxel_norm);
|
||||||
vec4 AbsNdotL = max(vec4(-light_dir * sides, ndotL), 0.0);
|
vec4 AbsNdotL = max(vec4(-light_dir * sides, ndotL), 0.0);
|
||||||
#endif
|
#endif
|
||||||
float diffuse = dot(AbsNdotL, vec4(abs(norm) * (1.0 - voxel_lighting), voxel_lighting));
|
float diffuse = dot(AbsNdotL, vec4(abs(voxel_norm) * (1.0 - voxel_lighting), voxel_lighting));
|
||||||
#elif (LIGHTING_DISTRIBUTION_SCHEME == LIGHTING_DISTRIBUTION_SCHEME_MICROFACET)
|
#elif (LIGHTING_DISTRIBUTION_SCHEME == LIGHTING_DISTRIBUTION_SCHEME_MICROFACET)
|
||||||
float diffuse = ndotL;
|
float diffuse = ndotL;
|
||||||
#endif
|
#endif
|
||||||
vec3 H = normalize(-light_dir + dir);
|
vec3 H = normalize(-light_dir + dir);
|
||||||
|
|
||||||
#if (LIGHTING_TYPE & LIGHTING_TYPE_TRANSMISSION) != 0
|
#if (LIGHTING_TYPE & LIGHTING_TYPE_TRANSMISSION) != 0
|
||||||
float NdotH = abs(dot(norm, H));
|
float NdotH = abs(dot(norm, H));
|
||||||
#else
|
#else
|
||||||
float NdotH = max(dot(norm, H), 0.0);
|
float NdotH = max(dot(norm, H), 0.0);
|
||||||
#endif
|
#endif
|
||||||
return (1.0 - k_s) / PI * k_d * diffuse + k_s * pow(NdotH, alpha/* * 4.0*/);
|
return (1.0 - k_s) / PI * k_d * diffuse + k_s * pow(NdotH, alpha/* * 4.0*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
return vec3(0.0);
|
return vec3(0.0);
|
||||||
#elif (LIGHTING_ALGORITHM == LIGHTING_ALGORITHM_ASHIKHMIN)
|
#elif (LIGHTING_ALGORITHM == LIGHTING_ALGORITHM_ASHIKHMIN)
|
||||||
#if (LIGHTING_DISTRIBUTION_SCHEME == LIGHTING_DISTRIBUTION_SCHEME_VOXEL)
|
#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_norm, voxel_lighting);
|
||||||
#elif (LIGHTING_DISTRIBUTION_SCHEME == LIGHTING_DISTRIBUTION_SCHEME_MICROFACET)
|
#elif (LIGHTING_DISTRIBUTION_SCHEME == LIGHTING_DISTRIBUTION_SCHEME_MICROFACET)
|
||||||
//if (voxel_lighting < 1.0) {
|
//if (voxel_lighting < 1.0) {
|
||||||
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);
|
||||||
//} 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
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -530,3 +547,68 @@ vec3 compute_attenuation_point(vec3 wpos, vec3 ray_dir, vec3 mu, float surface_a
|
|||||||
return exp(-mu * sqrt(depth2));
|
return exp(-mu * sqrt(depth2));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//#ifdef HAS_SHADOW_MAPS
|
||||||
|
// #if (SHADOW_MODE == SHADOW_MODE_MAP)
|
||||||
|
//uniform sampler2DShadow t_directed_shadow_maps;
|
||||||
|
//// uniform sampler2DArrayShadow t_directed_shadow_maps;
|
||||||
|
//
|
||||||
|
//float ShadowCalculationDirected(in vec4 /*light_pos[2]*/sun_pos, uint lightIndex)
|
||||||
|
//{
|
||||||
|
// float bias = 0.0;//-0.0001;// 0.05 / (2.0 * view_distance.x);
|
||||||
|
// // const vec3 sampleOffsetDirections[20] = vec3[]
|
||||||
|
// // (
|
||||||
|
// // vec3( 1, 1, 1), vec3( 1, -1, 1), vec3(-1, -1, 1), vec3(-1, 1, 1),
|
||||||
|
// // vec3( 1, 1, -1), vec3( 1, -1, -1), vec3(-1, -1, -1), vec3(-1, 1, -1),
|
||||||
|
// // vec3( 1, 1, 0), vec3( 1, -1, 0), vec3(-1, -1, 0), vec3(-1, 1, 0),
|
||||||
|
// // vec3( 1, 0, 1), vec3(-1, 0, 1), vec3( 1, 0, -1), vec3(-1, 0, -1),
|
||||||
|
// // vec3( 0, 1, 1), vec3( 0, -1, 1), vec3( 0, -1, -1), vec3( 0, 1, -1)
|
||||||
|
// // // vec3(0, 0, 0)
|
||||||
|
// // );
|
||||||
|
// /* if (lightIndex >= light_shadow_count.z) {
|
||||||
|
// return 1.0;
|
||||||
|
// } */
|
||||||
|
// // vec3 fragPos = sun_pos.xyz;// / sun_pos.w;//light_pos[lightIndex].xyz;
|
||||||
|
// float visibility = textureProj(t_directed_shadow_maps, sun_pos);
|
||||||
|
// // float visibility = textureProj(t_directed_shadow_maps, vec4(fragPos.xy, /*lightIndex, */fragPos.z + bias, sun_pos.w));
|
||||||
|
// return visibility;
|
||||||
|
// // return mix(visibility, 0.0, sun_pos.z < -1.0);
|
||||||
|
// // return mix(mix(0.0, 1.0, visibility == 1.0), 1.0, sign(sun_pos.w) * sun_pos.z > /*1.0*/abs(sun_pos.w));
|
||||||
|
// // return visibility == 1.0 ? 1.0 : 0.0;
|
||||||
|
// /* if (visibility == 1.0) {
|
||||||
|
// return 1.0;
|
||||||
|
// } */
|
||||||
|
// // return visibility;
|
||||||
|
// /* if (fragPos.z > 1.0) {
|
||||||
|
// return 1.0;
|
||||||
|
// } */
|
||||||
|
// // if (visibility <= 0.75) {
|
||||||
|
// // return 0.0;
|
||||||
|
// // }
|
||||||
|
// // int samples = 20;
|
||||||
|
// // float shadow = 0.0;
|
||||||
|
// // // float bias = 0.0001;
|
||||||
|
// // float viewDistance = length(cam_pos.xyz - fragPos);
|
||||||
|
// // // float diskRadius = 0.2 * (1.0 + (viewDistance / screen_res.w)) / 25.0;
|
||||||
|
// // float diskRadius = 0.0008;//0.005;// / (2.0 * view_distance.x);//(1.0 + (viewDistance / screen_res.w)) / 25.0;
|
||||||
|
// // for(int i = 0; i < samples; ++i)
|
||||||
|
// // {
|
||||||
|
// // vec3 currentDepth = fragPos + vec3(sampleOffsetDirections[i].xyz) * diskRadius + bias;
|
||||||
|
// // visibility = texture(t_directed_shadow_maps, vec4(currentDepth.xy, lightIndex, currentDepth.z)/*, -2.5*/);
|
||||||
|
// // shadow += mix(visibility, 1.0, visibility >= 0.5);
|
||||||
|
// // }
|
||||||
|
// // shadow /= float(samples);
|
||||||
|
// // return shadow;
|
||||||
|
//}
|
||||||
|
// #elif (SHADOW_MODE == SHADOW_MODE_NONE || SHADOW_MODE == SHADOW_MODE_CHEAP)
|
||||||
|
//float ShadowCalculationDirected(in vec4 light_pos[2], uint lightIndex)
|
||||||
|
//{
|
||||||
|
// return 1.0;
|
||||||
|
//}
|
||||||
|
// #endif
|
||||||
|
//#else
|
||||||
|
//float ShadowCalculationDirected(in vec4 light_pos[2], uint lightIndex)
|
||||||
|
//{
|
||||||
|
// return 1.0;
|
||||||
|
//}
|
||||||
|
//#endif
|
||||||
|
48
assets/voxygen/shaders/light-shadows-directed-frag.glsl
Normal file
48
assets/voxygen/shaders/light-shadows-directed-frag.glsl
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// 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
|
||||||
|
// #extension ARB_texture_storage : enable
|
||||||
|
|
||||||
|
#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 vec3 FragPos; // FragPos from GS (output per emitvertex)
|
||||||
|
// flat in int FragLayer;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
// Only need to do anything with point lights, since sun and moon should already have nonlinear
|
||||||
|
// distance.
|
||||||
|
/*if (FragLayer > 0) */{
|
||||||
|
// get distance between fragment and light source
|
||||||
|
// float lightDistance = length(FragPos - lights[FragLayer & 31].light_pos.xyz);
|
||||||
|
|
||||||
|
// // // map to [0;1] range by dividing by far_plane
|
||||||
|
// lightDistance = lightDistance / screen_res.w;//FragPos.w;//screen_res.w;
|
||||||
|
|
||||||
|
// // // write this as modified depth
|
||||||
|
// // // lightDistance = -1000.0 / (lightDistance + 10000.0);
|
||||||
|
// // // lightDistance /= screen_res.w;
|
||||||
|
// gl_FragDepth = lightDistance;// / /*FragPos.w;*/screen_res.w;//-1000.0 / (lightDistance + 1000.0);//lightDistance
|
||||||
|
}
|
||||||
|
}
|
63
assets/voxygen/shaders/light-shadows-directed-vert.glsl
Normal file
63
assets/voxygen/shaders/light-shadows-directed-vert.glsl
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
#version 330 core
|
||||||
|
// #extension ARB_texture_storage : enable
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
|
// Currently, we only need globals for focus_off.
|
||||||
|
#include <globals.glsl>
|
||||||
|
// For shadow locals.
|
||||||
|
#include <shadows.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;
|
||||||
|
// in vec4 v_pos;
|
||||||
|
|
||||||
|
// Light projection matrices.
|
||||||
|
layout (std140)
|
||||||
|
uniform u_locals {
|
||||||
|
vec3 model_offs;
|
||||||
|
float load_time;
|
||||||
|
ivec4 atlas_offs;
|
||||||
|
};
|
||||||
|
|
||||||
|
// out vec4 shadowMapCoord;
|
||||||
|
|
||||||
|
const int EXTRA_NEG_Z = 32768;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
#if (SHADOW_MODE == SHADOW_MODE_MAP)
|
||||||
|
vec3 f_chunk_pos = vec3(ivec3((uvec3(v_pos_norm) >> uvec3(0, 6, 12)) & uvec3(0x3Fu, 0x3Fu, 0xFFFFu)) - ivec3(0, 0, EXTRA_NEG_Z));
|
||||||
|
vec3 f_pos = f_chunk_pos + model_offs - focus_off.xyz;
|
||||||
|
// f_pos = v_pos;
|
||||||
|
// vec3 f_pos = f_chunk_pos + model_offs;
|
||||||
|
|
||||||
|
// gl_Position = v_pos + vec4(model_offs, 0.0);
|
||||||
|
gl_Position = /*all_mat * */shadowMats[/*layer_face*/0].shadowMatrices * vec4(f_pos/*, 1.0*/, /*float(((f_pos_norm >> 29) & 0x7u) ^ 0x1)*//*uintBitsToFloat(v_pos_norm)*/1.0);
|
||||||
|
// gl_Position.z = -gl_Position.z;
|
||||||
|
// gl_Position.z = clamp(gl_Position.z, -abs(gl_Position.w), abs(gl_Position.w));
|
||||||
|
// shadowMapCoord = lights[gl_InstanceID].light_pos * gl_Vertex;
|
||||||
|
// vec4(v_pos, 0.0, 1.0);
|
||||||
|
#endif
|
||||||
|
}
|
74
assets/voxygen/shaders/light-shadows-figure-vert.glsl
Normal file
74
assets/voxygen/shaders/light-shadows-figure-vert.glsl
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
#version 330 core
|
||||||
|
// #extension ARB_texture_storage : enable
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
|
// Currently, we only need globals for focus_off.
|
||||||
|
#include <globals.glsl>
|
||||||
|
// For shadow locals.
|
||||||
|
#include <shadows.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_atlas_pos;
|
||||||
|
// in uint v_col_light;
|
||||||
|
// in vec4 v_pos;
|
||||||
|
|
||||||
|
layout (std140)
|
||||||
|
uniform u_locals {
|
||||||
|
mat4 model_mat;
|
||||||
|
vec4 model_col;
|
||||||
|
ivec4 atlas_offs;
|
||||||
|
vec3 model_pos;
|
||||||
|
// bit 0 - is player
|
||||||
|
// bit 1-31 - unused
|
||||||
|
int flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BoneData {
|
||||||
|
mat4 bone_mat;
|
||||||
|
mat4 normals_mat;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout (std140)
|
||||||
|
uniform u_bones {
|
||||||
|
// Warning: might not actually be 16 elements long. Don't index out of bounds!
|
||||||
|
BoneData bones[16];
|
||||||
|
};
|
||||||
|
|
||||||
|
// out vec4 shadowMapCoord;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
#if (SHADOW_MODE == SHADOW_MODE_MAP)
|
||||||
|
uint bone_idx = (v_pos_norm >> 27) & 0xFu;
|
||||||
|
vec3 pos = (vec3((uvec3(v_pos_norm) >> uvec3(0, 9, 18)) & uvec3(0x1FFu)) - 256.0) / 2.0;
|
||||||
|
|
||||||
|
vec3 f_pos = (
|
||||||
|
bones[bone_idx].bone_mat *
|
||||||
|
vec4(pos, 1.0)
|
||||||
|
).xyz + (model_pos - focus_off.xyz/* + vec3(0.0, 0.0, 0.0001)*/);
|
||||||
|
|
||||||
|
gl_Position = shadowMats[/*layer_face*/0].shadowMatrices * vec4(f_pos, 1.0);
|
||||||
|
#endif
|
||||||
|
}
|
@ -21,12 +21,12 @@
|
|||||||
|
|
||||||
#define LIGHTING_DISTRIBUTION LIGHTING_DISTRIBUTION_BECKMANN
|
#define LIGHTING_DISTRIBUTION LIGHTING_DISTRIBUTION_BECKMANN
|
||||||
|
|
||||||
// Currently, we only need globals for the far plane.
|
// // Currently, we only need globals for the far plane.
|
||||||
#include <globals.glsl>
|
// #include <globals.glsl>
|
||||||
// Currently, we only need lights for the light position
|
// // Currently, we only need lights for the light position
|
||||||
#include <light.glsl>
|
// #include <light.glsl>
|
||||||
|
|
||||||
in vec3 FragPos; // FragPos from GS (output per emitvertex)
|
// in vec3 FragPos; // FragPos from GS (output per emitvertex)
|
||||||
// flat in int FragLayer;
|
// flat in int FragLayer;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
|
@ -21,11 +21,14 @@
|
|||||||
|
|
||||||
#define LIGHTING_DISTRIBUTION LIGHTING_DISTRIBUTION_BECKMANN
|
#define LIGHTING_DISTRIBUTION LIGHTING_DISTRIBUTION_BECKMANN
|
||||||
|
|
||||||
|
#define HAS_SHADOW_MAPS
|
||||||
|
|
||||||
// Currently, we only need globals for the max light count (light_shadow_count.x)
|
// Currently, we only need globals for the max light count (light_shadow_count.x)
|
||||||
// and the far plane (scene_res.z).
|
// and the far plane (scene_res.z).
|
||||||
#include <globals.glsl>
|
#include <globals.glsl>
|
||||||
// Currently, we only need lights for the light position
|
#include <shadows.glsl>
|
||||||
#include <light.glsl>
|
// // Currently, we only need lights for the light position
|
||||||
|
// #include <light.glsl>
|
||||||
|
|
||||||
// Since our output primitive is a triangle strip, we have to render three vertices
|
// Since our output primitive is a triangle strip, we have to render three vertices
|
||||||
// each.
|
// each.
|
||||||
@ -171,14 +174,15 @@ layout (triangles/*, invocations = 6*/) in;
|
|||||||
|
|
||||||
layout (triangle_strip, max_vertices = /*MAX_LAYER_VERTICES_PER_FACE*//*96*/18) out;
|
layout (triangle_strip, max_vertices = /*MAX_LAYER_VERTICES_PER_FACE*//*96*/18) out;
|
||||||
|
|
||||||
struct ShadowLocals {
|
//struct ShadowLocals {
|
||||||
mat4 shadowMatrices;
|
// mat4 shadowMatrices;
|
||||||
};
|
// mat4 texture_mat;
|
||||||
|
//};
|
||||||
layout (std140)
|
//
|
||||||
uniform u_light_shadows {
|
//layout (std140)
|
||||||
ShadowLocals shadowMats[/*MAX_LAYER_FACES*/192];
|
//uniform u_light_shadows {
|
||||||
};
|
// ShadowLocals shadowMats[/*MAX_LAYER_FACES*/192];
|
||||||
|
//};
|
||||||
|
|
||||||
// NOTE: We choose not to output FragPos currently to save on space limitations
|
// NOTE: We choose not to output FragPos currently to save on space limitations
|
||||||
// (see extensive documentation above). However, as these limitations have been
|
// (see extensive documentation above). However, as these limitations have been
|
||||||
@ -218,15 +222,17 @@ void main() {
|
|||||||
/* if (light_shadow_count.x == 1) {
|
/* if (light_shadow_count.x == 1) {
|
||||||
return;
|
return;
|
||||||
} */
|
} */
|
||||||
for (int layer = 1; layer <= /*light_shadow_count.x*/1; ++layer)
|
#if (SHADOW_MODE == SHADOW_MODE_MAP)
|
||||||
|
for (uint layer = 1u; layer <= min(light_shadow_count.x, 1u); ++layer)
|
||||||
{
|
{
|
||||||
int layer_base = layer * FACES_PER_POINT_LIGHT;
|
int layer_base = int(layer) * FACES_PER_POINT_LIGHT;
|
||||||
// We use instancing here in order to increase the number of emitted vertices.
|
// We use instancing here in order to increase the number of emitted vertices.
|
||||||
// int face = gl_InvocationID;
|
// int face = gl_InvocationID;
|
||||||
for(int face = 0; face < FACES_PER_POINT_LIGHT; ++face)
|
for(int face = 0; face < FACES_PER_POINT_LIGHT; ++face)
|
||||||
{
|
{
|
||||||
// int layer_face = layer * FACES_PER_POINT_LIGHT + face;
|
// int layer_face = layer * FACES_PER_POINT_LIGHT + face;
|
||||||
// int layer_face = layer * FACES_PER_POINT_LIGHT + face;
|
// int layer_face = layer * FACES_PER_POINT_LIGHT + face;
|
||||||
|
// for(int i = VERTICES_PER_FACE - 1; i >= 0; --i) // for each triangle vertex
|
||||||
for(int i = 0; i < VERTICES_PER_FACE; ++i) // for each triangle vertex
|
for(int i = 0; i < VERTICES_PER_FACE; ++i) // for each triangle vertex
|
||||||
{
|
{
|
||||||
// NOTE: See above, we don't make FragPos a uniform.
|
// NOTE: See above, we don't make FragPos a uniform.
|
||||||
@ -256,4 +262,5 @@ void main() {
|
|||||||
EndPrimitive();
|
EndPrimitive();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
|
|
||||||
#define LIGHTING_DISTRIBUTION LIGHTING_DISTRIBUTION_BECKMANN
|
#define LIGHTING_DISTRIBUTION LIGHTING_DISTRIBUTION_BECKMANN
|
||||||
|
|
||||||
// Currently, we only need globals for the all_mat matrix.
|
// Currently, we only need globals for focus_off.
|
||||||
#include <globals.glsl>
|
#include <globals.glsl>
|
||||||
|
|
||||||
/* Accurate packed shadow maps for many lights at once!
|
/* Accurate packed shadow maps for many lights at once!
|
||||||
@ -35,6 +35,7 @@ layout (std140)
|
|||||||
uniform u_locals {
|
uniform u_locals {
|
||||||
vec3 model_offs;
|
vec3 model_offs;
|
||||||
float load_time;
|
float load_time;
|
||||||
|
ivec4 atlas_offs;
|
||||||
};
|
};
|
||||||
|
|
||||||
// out vec4 shadowMapCoord;
|
// out vec4 shadowMapCoord;
|
||||||
@ -43,7 +44,7 @@ const int EXTRA_NEG_Z = 32768;
|
|||||||
|
|
||||||
void main() {
|
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));
|
vec3 f_chunk_pos = vec3(ivec3((uvec3(v_pos_norm) >> uvec3(0, 6, 12)) & uvec3(0x3Fu, 0x3Fu, 0xFFFFu)) - ivec3(0, 0, EXTRA_NEG_Z));
|
||||||
vec3 f_pos = f_chunk_pos + model_offs;
|
vec3 f_pos = f_chunk_pos + model_offs - focus_off.xyz;
|
||||||
// f_pos = v_pos;
|
// f_pos = v_pos;
|
||||||
// vec3 f_pos = f_chunk_pos + model_offs;
|
// vec3 f_pos = f_chunk_pos + model_offs;
|
||||||
|
|
||||||
|
@ -12,7 +12,8 @@
|
|||||||
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
|
#define LIGHTING_TRANSPORT_MODE LIGHTING_TRANSPORT_MODE_RADIANCE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define LIGHTING_DISTRIBUTION_SCHEME LIGHTING_DISTRIBUTION_SCHEME_VOXEL
|
// #define LIGHTING_DISTRIBUTION_SCHEME LIGHTING_DISTRIBUTION_SCHEME_VOXEL
|
||||||
|
#define LIGHTING_DISTRIBUTION_SCHEME LIGHTING_DISTRIBUTION_SCHEME_MICROFACET
|
||||||
|
|
||||||
#define LIGHTING_DISTRIBUTION LIGHTING_DISTRIBUTION_BECKMANN
|
#define LIGHTING_DISTRIBUTION LIGHTING_DISTRIBUTION_BECKMANN
|
||||||
|
|
||||||
@ -22,36 +23,45 @@
|
|||||||
|
|
||||||
in vec3 f_pos;
|
in vec3 f_pos;
|
||||||
in vec3 f_norm;
|
in vec3 f_norm;
|
||||||
in vec2 v_pos_orig;
|
// in vec2 v_pos_orig;
|
||||||
// in vec4 f_shadow;
|
// in vec4 f_shadow;
|
||||||
// in vec4 f_square;
|
// in vec4 f_square;
|
||||||
|
|
||||||
out vec4 tgt_color;
|
out vec4 tgt_color;
|
||||||
|
|
||||||
|
/// const vec4 sun_pos = vec4(0);
|
||||||
|
// const vec4 light_pos[2] = vec4[](vec4(0), vec4(0)/*, vec3(00), vec3(0), vec3(0), vec3(0)*/);
|
||||||
|
|
||||||
#include <sky.glsl>
|
#include <sky.glsl>
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
// tgt_color = vec4(vec3(1.0), 1.0);
|
||||||
|
// return;
|
||||||
// vec3 f_pos = lod_pos(f_pos.xy);
|
// vec3 f_pos = lod_pos(f_pos.xy);
|
||||||
// vec3 f_col = lod_col(f_pos.xy);
|
// vec3 f_col = lod_col(f_pos.xy);
|
||||||
|
|
||||||
// vec4 vert_pos4 = view_mat * vec4(f_pos, 1.0);
|
// vec4 vert_pos4 = view_mat * vec4(f_pos, 1.0);
|
||||||
// vec3 view_dir = normalize(-vec3(vert_pos4)/* / vert_pos4.w*/);
|
// vec3 view_dir = normalize(-vec3(vert_pos4)/* / vert_pos4.w*/);
|
||||||
|
|
||||||
float my_alt = /*f_pos.z;*/alt_at_real(f_pos.xy);
|
float my_alt = /*f_pos.z;*/alt_at_real(f_pos.xy);
|
||||||
// vec3 f_pos = vec3(f_pos.xy, max(my_alt, f_pos.z));
|
// vec3 f_pos = vec3(f_pos.xy, max(my_alt, f_pos.z));
|
||||||
/* gl_Position =
|
/* gl_Position =
|
||||||
proj_mat *
|
proj_mat *
|
||||||
view_mat *
|
view_mat *
|
||||||
vec4(f_pos, 1);
|
vec4(f_pos, 1);
|
||||||
gl_Position.z = -1000.0 / (gl_Position.z + 10000.0); */
|
gl_Position.z = -1000.0 / (gl_Position.z + 10000.0); */
|
||||||
vec3 my_pos = vec3(f_pos.xy, my_alt);
|
vec3 my_pos = vec3(f_pos.xy, my_alt);
|
||||||
vec3 my_norm = lod_norm(f_pos.xy/*, f_square*/);
|
vec3 my_norm = lod_norm(f_pos.xy/*, f_square*/);
|
||||||
|
|
||||||
float which_norm = dot(my_norm, normalize(cam_pos.xyz - my_pos));
|
float which_norm = dot(my_norm, normalize(cam_pos.xyz - my_pos));
|
||||||
// which_norm = 0.5 + which_norm * 0.5;
|
// which_norm = 0.5 + which_norm * 0.5;
|
||||||
which_norm = pow(max(0.0, which_norm), /*0.03125*/1 / 8.0);// * 0.5;
|
|
||||||
|
// which_norm = pow(max(0.0, which_norm), /*0.03125*/1 / 8.0);// * 0.5;
|
||||||
|
// smoothstep
|
||||||
|
which_norm = which_norm * which_norm * (3 - 2 * abs(which_norm));
|
||||||
|
|
||||||
// which_norm = mix(0.0, 1.0, which_norm > 0.0);
|
// which_norm = mix(0.0, 1.0, which_norm > 0.0);
|
||||||
// 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));
|
||||||
vec3 f_norm = mix(faceforward(f_norm, cam_pos.xyz - f_pos, -f_norm), my_norm, which_norm);
|
vec3 f_norm = mix(faceforward(f_norm, cam_pos.xyz - f_pos, -f_norm), my_norm, which_norm);
|
||||||
vec3 f_pos = mix(f_pos, my_pos, which_norm);
|
vec3 f_pos = mix(f_pos, my_pos, which_norm);
|
||||||
// vec3 fract_pos = fract(f_pos);
|
// vec3 fract_pos = fract(f_pos);
|
||||||
@ -73,7 +83,7 @@ void main() {
|
|||||||
f_norm = my_f_norm;
|
f_norm = my_f_norm;
|
||||||
depth = my_f_proj.z;
|
depth = my_f_proj.z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// f_pos = new_f_pos.xyz;
|
// f_pos = new_f_pos.xyz;
|
||||||
} */
|
} */
|
||||||
|
|
||||||
@ -94,7 +104,10 @@ void main() {
|
|||||||
// mat4 invfoo = foo * inverse(foo * all_mat);
|
// mat4 invfoo = foo * inverse(foo * all_mat);
|
||||||
// vec3 old_coord = all_mat * vec4(f_pos.xyz, 1.0);
|
// vec3 old_coord = all_mat * vec4(f_pos.xyz, 1.0);
|
||||||
// vec4 new_f_pos = invfoo * (old_coord);//vec4(f_pos, 1.0);
|
// vec4 new_f_pos = invfoo * (old_coord);//vec4(f_pos, 1.0);
|
||||||
vec3 f_col = lod_col(f_pos.xy);
|
vec3 f_col = lod_col(f_pos.xy);
|
||||||
|
// tgt_color = vec4(f_col, 1.0);
|
||||||
|
// return;
|
||||||
|
// vec3 f_col = srgb_to_linear(vec3(1.0));
|
||||||
// vec3 f_norm = faceforward(f_norm, cam_pos.xyz - f_pos, -f_norm);
|
// vec3 f_norm = faceforward(f_norm, cam_pos.xyz - f_pos, -f_norm);
|
||||||
// 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);
|
||||||
@ -168,7 +181,7 @@ 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) / 4096.0, 2.0), 0, 1);
|
float dist_lerp = 0.0;//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));
|
||||||
|
|
||||||
@ -198,9 +211,23 @@ void main() {
|
|||||||
// we travel along x and y?
|
// we travel along x and y?
|
||||||
//
|
//
|
||||||
// TODO: Handle negative numbers.
|
// 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(-fract(f_pos), 1.0 - fract(f_pos), lessThan(sides, vec3(0.0)));
|
||||||
|
vec3 delta_sides = mix(fract(f_pos) - 1.0, fract(f_pos), lessThan(sides, vec3(0.0)));
|
||||||
|
/* vec3 delta_sides =
|
||||||
|
mix(
|
||||||
|
mix(-fract(f_pos), 1.0 - fract(f_pos), lessThan(sides, vec3(0.0))),
|
||||||
|
mix(-(f_pos - ceil(f_pos)), 1.0 - (f_pos - ceil(f_pos)), lessThan(sides, vec3(0.0))),
|
||||||
|
lessThan(f_pos, vec3(0.0))
|
||||||
|
); */
|
||||||
|
/* vec3 delta_sides =
|
||||||
|
mix(
|
||||||
|
mix(1.0 - fract(f_pos), -fract(f_pos), lessThan(sides, vec3(0.0))),
|
||||||
|
mix(1.0 - (f_pos - ceil(f_pos)), -(f_pos - ceil(f_pos)), lessThan(sides, vec3(0.0))),
|
||||||
|
lessThan(f_pos, vec3(0.0))
|
||||||
|
); */
|
||||||
// vec3 delta_sides = mix(1.0 - fract(f_pos), -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);
|
// vec3 delta_sides = 1.0 + sides * fract(-sides * f_pos);
|
||||||
|
// delta_sides = -sign(delta_sides) * (1.0 - abs(delta_sides));
|
||||||
// Three faces: xy, xz, and yz.
|
// Three faces: xy, xz, and yz.
|
||||||
// TODO: Handle zero slopes (for 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_xy = min(abs(f_norm.xy / f_norm.z * delta_sides.z), 1.0);
|
||||||
@ -209,22 +236,96 @@ void main() {
|
|||||||
// vec3 corner_delta = vec3(voxel_norm.xy / voxel_norm.z * delta_sides.z, delta_sides.z);
|
// 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.
|
// Now we just compute an (upper bounded) distance to the corner in each direction.
|
||||||
// vec3 corner_distance = min(abs(corner_delta), 1.0);
|
// vec3 corner_distance = min(abs(corner_delta), 1.0);
|
||||||
|
// Now, if both sides hit something, lerp to 0.25. If one side hits something, lerp to 0.75. And if no sides hit something,
|
||||||
|
// lerp to 1.0 (TODO: incorporate the corner properly).
|
||||||
|
// Bilinear interpolation on each plane:
|
||||||
|
float ao_xy = dot(vec2(corner_xy.x, 1.0 - corner_xy.x), mat2(vec2(corner_xy.x < 1.00 ? corner_xy.y < 1.00 ? 0.25 : 0.5 : corner_xy.y < 1.00 ? 0.5 : 0.75, corner_xy.x < 1.00 ? 0.75 : 1.00), vec2(corner_xy.y < 1.00 ? 0.75 : 1.0, 1.0)) * vec2(corner_xy.y, 1.0 - corner_xy.y));
|
||||||
|
float ao_yz = dot(vec2(corner_yz.x, 1.0 - corner_yz.x), mat2(vec2(corner_yz.x < 1.00 ? corner_yz.y < 1.00 ? 0.25 : 0.5 : corner_yz.y < 1.00 ? 0.5 : 0.75, corner_yz.x < 1.00 ? 0.75 : 1.00), vec2(corner_yz.y < 1.00 ? 0.75 : 1.0, 1.0)) * vec2(corner_yz.y, 1.0 - corner_yz.y));
|
||||||
|
float ao_xz = dot(vec2(corner_xz.x, 1.0 - corner_xz.x), mat2(vec2(corner_xz.x < 1.00 ? corner_xz.y < 1.00 ? 0.25 : 0.5 : corner_xz.y < 1.00 ? 0.5 : 0.75, corner_xz.x < 1.00 ? 0.75 : 1.00), vec2(corner_xz.y < 1.00 ? 0.75 : 1.0, 1.0)) * vec2(corner_xz.y, 1.0 - corner_xz.y));
|
||||||
|
/* 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.25 : 0.5 : corner_xy.y < 1.00 ? 0.5 : 0.75, corner_xy.x < 1.00 ? 0.75 : 1.00), vec2(corner_xy.y < 1.00 ? 0.75 : 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.25 : 0.5 : corner_yz.y < 1.00 ? 0.5 : 0.75, corner_yz.x < 1.00 ? 0.75 : 1.00), vec2(corner_yz.y < 1.00 ? 0.75 : 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.25 : 0.5 : corner_xz.y < 1.00 ? 0.5 : 0.75, corner_xz.x < 1.00 ? 0.75 : 1.00), vec2(corner_xz.y < 1.00 ? 0.75 : 1.0, 1.0)) * vec2(1.0 - corner_xz.y, corner_xz.y)); */
|
||||||
// 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,
|
// 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.
|
// lerp to 1.0.
|
||||||
// Bilinear interpolation on each plane:
|
// 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_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_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));
|
// 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...
|
// 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(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(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(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))*/);
|
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));
|
float f_orig_len = length(cam_pos.xyz - f_pos);
|
||||||
// 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);
|
vec3 f_orig_view_dir = normalize(cam_pos.xyz - f_pos);
|
||||||
|
// f_ao_vec *= sign(max(f_orig_view_dir * sides, 0.0));
|
||||||
|
// Projecting view onto face:
|
||||||
|
// bool IntersectRayPlane(vec3 rayOrigin, vec3 rayDirection, vec3 posOnPlane, vec3 planeNormal, inout vec3 intersectionPoint)
|
||||||
|
// {
|
||||||
|
// float rDotn = dot(rayDirection, planeNormal);
|
||||||
|
//
|
||||||
|
// //parallel to plane or pointing away from plane?
|
||||||
|
// if (rDotn < 0.0000001 )
|
||||||
|
// return false;
|
||||||
|
//
|
||||||
|
// float s = dot(planeNormal, (posOnPlane - rayOrigin)) / rDotn;
|
||||||
|
//
|
||||||
|
// intersectionPoint = rayOrigin + s * rayDirection;
|
||||||
|
//
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
|
||||||
|
bvec3 hit_yz_xz_xy;
|
||||||
|
vec3 dist_yz_xz_xy;
|
||||||
|
/* {
|
||||||
|
// vec3 rDotn = -f_orig_view_dir * -sides;
|
||||||
|
// vec3 rDotn = f_orig_view_dir * sides;
|
||||||
|
// hit_yz_xz_xy = greaterThanEqual(rDotn, vec3(0.000001));
|
||||||
|
// vec3 s = -sides * (f_pos + delta_sides - cam_pos.xyz) / rDotn;
|
||||||
|
// dist_yz_xz_xy = abs(s * -f_orig_view_dir);
|
||||||
|
// vec3 s = -sides * (f_pos + delta_sides - cam_pos.xyz) / (-f_orig_view_dir * -sides);
|
||||||
|
// vec3 s = (f_pos + delta_sides - cam_pos.xyz) / -f_orig_view_dir;
|
||||||
|
// dist_yz_xz_xy = abs(s);
|
||||||
|
hit_yz_xz_xy = greaterThanEqual(f_orig_view_dir * sides, vec3(0.000001));
|
||||||
|
dist_yz_xz_xy = abs((f_pos + delta_sides - cam_pos.xyz) / -f_orig_view_dir);
|
||||||
|
} */
|
||||||
|
{
|
||||||
|
// vec3 rDotn = -f_orig_view_dir * -sides;
|
||||||
|
// vec3 rDotn = f_orig_view_dir * sides;
|
||||||
|
// hit_yz_xz_xy = greaterThanEqual(rDotn, vec3(0.000001));
|
||||||
|
// vec3 s = -sides * (f_pos + delta_sides - cam_pos.xyz) / rDotn;
|
||||||
|
// dist_yz_xz_xy = abs(s * -f_orig_view_dir);
|
||||||
|
// vec3 s = -sides * (f_pos + delta_sides - cam_pos.xyz) / (-f_orig_view_dir * -sides);
|
||||||
|
// vec3 s = (f_pos + delta_sides - cam_pos.xyz) / -f_orig_view_dir;
|
||||||
|
// dist_yz_xz_xy = abs(s);
|
||||||
|
hit_yz_xz_xy = greaterThanEqual(f_orig_view_dir * sides, vec3(0.000001));
|
||||||
|
dist_yz_xz_xy = abs((f_pos + delta_sides - cam_pos.xyz) / f_orig_view_dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
// vec3 xy_point = f_pos, xz_point = f_pos, yz_point = f_pos;
|
||||||
|
// bool hit_xy = (/*ao_yz < 1.0 || ao_xz < 1.0*//*min(f_ao_vec.x, f_ao_vec.y)*//*f_ao_vec.z < 1.0*/true/*min(corner_xz.y, corner_yz.y) < 1.0*//*min(corner_xy.x, corner_xy.y) < 1.0*/) && IntersectRayPlane(cam_pos.xyz, -f_orig_view_dir, vec3(f_pos.x, f_pos.y, f_pos.z + delta_sides.z/* - sides.z*/), vec3(0.0, 0.0, -sides.z), xy_point);
|
||||||
|
// bool hit_xz = (/*ao_xy < 1.0 || ao_yz < 1.0*//*min(f_ao_vec.x, f_ao_vec.z)*//*f_ao_vec.y < 1.0*/true/*min(corner_xy.y, corner_yz.x) < 1.0*//*min(corner_xz.x, corner_xz.y) < 1.0*/) && IntersectRayPlane(cam_pos.xyz, -f_orig_view_dir, vec3(f_pos.x, f_pos.y + delta_sides.y/* - sides.y*/, f_pos.z), vec3(0.0, -sides.y, 0.0), xz_point);
|
||||||
|
// bool hit_yz = (/*ao_xy < 1.0 || ao_xz < 1.0*//*min(f_ao_vec.y, f_ao_vec.z) < 1.0*//*f_ao_vec.x < 1.0*/true/*true*//*min(corner_xy.x, corner_xz.x) < 1.0*//*min(corner_yz.x, corner_yz.y) < 1.0*/) && IntersectRayPlane(cam_pos.xyz, -f_orig_view_dir, vec3(f_pos.x + delta_sides.x/* - sides.x*/, f_pos.y, f_pos.z), vec3(-sides.x, 0.0, 0.0), yz_point);
|
||||||
|
// float xy_dist = distance(cam_pos.xyz, xy_point), xz_dist = distance(cam_pos.xyz, xz_point), yz_dist = distance(cam_pos.xyz, yz_point);
|
||||||
|
bool hit_xy = hit_yz_xz_xy.z, hit_xz = hit_yz_xz_xy.y, hit_yz = hit_yz_xz_xy.x;
|
||||||
|
float xy_dist = dist_yz_xz_xy.z, xz_dist = dist_yz_xz_xy.y, yz_dist = dist_yz_xz_xy.x;
|
||||||
|
// hit_xy = hit_xy && distance(f_pos.xy + delta_sides.xy, xy_point.xy) <= 1.0;
|
||||||
|
// hit_xz = hit_xz && distance(f_pos.xz + delta_sides.xz, xz_point.xz) <= 1.0;
|
||||||
|
// hit_yz = hit_yz && distance(f_pos.yz + delta_sides.yz, yz_point.yz) <= 1.0;
|
||||||
|
vec3 voxel_norm =
|
||||||
|
hit_yz ?
|
||||||
|
hit_xz ?
|
||||||
|
yz_dist < xz_dist ?
|
||||||
|
hit_xy ? yz_dist < xy_dist ? vec3(sides.x, 0.0, 0.0) : vec3(0.0, 0.0, sides.z) : vec3(sides.x, 0.0, 0.0) :
|
||||||
|
hit_xy ? xz_dist < xy_dist ? vec3(0.0, sides.y, 0.0) : vec3(0.0, 0.0, sides.z) : vec3(0.0, sides.y, 0.0) :
|
||||||
|
hit_xy ? yz_dist < xy_dist ? vec3(sides.x, 0.0, 0.0) : vec3(0.0, 0.0, sides.z) : vec3(sides.x, 0.0, 0.0) :
|
||||||
|
hit_xz ?
|
||||||
|
hit_xy ? xz_dist < xy_dist ? vec3(0.0, sides.y, 0.0) : vec3(0.0, 0.0, sides.z) : vec3(0.0, sides.y, 0.0) :
|
||||||
|
hit_xy ? vec3(0.0, 0.0, sides.z) : vec3(0.0, 0.0, 0.0);
|
||||||
|
// vec3 f_ao_view = max(vec3(dot(f_orig_view_dir.yz, sides.yz), dot(f_orig_view_dir.xz, sides.xz), dot(f_orig_view_dir.xy, sides.xy)), 0.0);
|
||||||
// delta_sides *= sqrt(1.0 - f_ao_view * f_ao_view);
|
// 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 - 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));
|
// delta_sides *= 1.0 - /*sign*/(max(vec3(dot(f_orig_view_dir.yz, sides.yz), dot(f_orig_view_dir.xz, sides.xz), dot(f_orig_view_dir.xy, sides.xy)), 0.0));
|
||||||
// f_ao = length(f_ao_vec);
|
// f_ao = length(f_ao_vec);
|
||||||
// f_ao = dot(f_ao_vec, vec3(1.0)) / 3.0;
|
// 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 = 1.0 / sqrt(3.0) * sqrt(dot(f_ao_vec, vec3(1.0)));
|
||||||
@ -256,10 +357,21 @@ void main() {
|
|||||||
// abs(delta_sides.y) * f_ao_vec.y < abs(delta_sides.z) * f_ao_vec.z ? f_ao_vec.y : 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 = 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 = 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 = /*abs(sides)*/max(sign(1.0 + f_orig_view_dir * sides), 0.0) * f_ao);
|
||||||
// f_ao = mix(f_ao, 1.0, dist_lerp);
|
// f_ao = mix(f_ao, 1.0, dist_lerp);
|
||||||
|
|
||||||
// vec3 voxel_norm = f_norm;
|
// vec3 voxel_norm = f_norm;
|
||||||
|
// 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 =
|
// vec3 voxel_norm =
|
||||||
// /*f_ao_vec.x < 1.0*/true ?
|
// /*f_ao_vec.x < 1.0*/true ?
|
||||||
// /*f_ao_vec.y < 1.0*/true ?
|
// /*f_ao_vec.y < 1.0*/true ?
|
||||||
@ -290,16 +402,39 @@ void main() {
|
|||||||
// f_ao_vec.y < 1.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 ? 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);
|
// 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);
|
// vec3 voxel_norm = vec3(0.0);
|
||||||
// voxel_norm = mix(voxel_norm, f_norm, dist_lerp);
|
// voxel_norm = mix(voxel_norm, f_norm, dist_lerp);
|
||||||
|
|
||||||
f_pos.xyz -= abs(voxel_norm) * delta_sides;
|
/* vec3 sun_dir = get_sun_dir(time_of_day.x);
|
||||||
|
vec3 moon_dir = get_moon_dir(time_of_day.x); */
|
||||||
|
// voxel_norm = vec3(0.0);
|
||||||
|
|
||||||
|
#if (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_MAP || FLUID_MODE == FLUID_MODE_SHINY)
|
||||||
|
float shadow_alt = /*f_pos.z;*/alt_at(f_pos.xy);//max(alt_at(f_pos.xy), f_pos.z);
|
||||||
|
// float shadow_alt = f_pos.z;
|
||||||
|
#elif (SHADOW_MODE == SHADOW_MODE_NONE || FLUID_MODE == FLUID_MODE_CHEAP)
|
||||||
|
float shadow_alt = f_pos.z;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_MAP)
|
||||||
|
vec4 f_shadow = textureBicubic(t_horizon, pos_to_tex(f_pos.xy));
|
||||||
|
float sun_shade_frac = horizon_at2(f_shadow, shadow_alt, f_pos, sun_dir);
|
||||||
|
// float sun_shade_frac = 1.0;
|
||||||
|
#elif (SHADOW_MODE == SHADOW_MODE_NONE)
|
||||||
|
float sun_shade_frac = 1.0;//horizon_at2(f_shadow, shadow_alt, f_pos, sun_dir);
|
||||||
|
#endif
|
||||||
|
float moon_shade_frac = 1.0;//horizon_at2(f_shadow, shadow_alt, f_pos, moon_dir);
|
||||||
|
|
||||||
|
f_pos.xyz += abs(voxel_norm) * delta_sides;
|
||||||
voxel_norm = voxel_norm == vec3(0.0) ? f_norm : voxel_norm;
|
voxel_norm = voxel_norm == vec3(0.0) ? f_norm : voxel_norm;
|
||||||
|
|
||||||
|
f_col = /*srgb_to_linear*/(f_col + hash(vec4(floor(f_pos * 3.0 - voxel_norm * 0.5), 0)) * 0.01/* - 0.01*/); // Small-scale noise
|
||||||
|
|
||||||
// f_ao = 1.0;
|
// f_ao = 1.0;
|
||||||
// f_ao = dot(f_ao_vec, sqrt(1.0 - delta_sides * delta_sides));
|
// 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(f_ao_vec, abs(voxel_norm));
|
||||||
|
// f_ao = sqrt(dot(f_ao_vec * abs(voxel_norm), sqrt(1.0 - delta_sides * delta_sides)) / 3.0);
|
||||||
|
|
||||||
// vec3 ao_pos2 = min(fract(f_pos), 1.0 - fract(f_pos));
|
// vec3 ao_pos2 = min(fract(f_pos), 1.0 - fract(f_pos));
|
||||||
// f_ao = sqrt(dot(ao_pos2, ao_pos2));
|
// f_ao = sqrt(dot(ao_pos2, ao_pos2));
|
||||||
@ -336,27 +471,31 @@ void main() {
|
|||||||
// vec3 view_dir = normalize(f_pos - cam_pos.xyz);
|
// 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);
|
||||||
// float sun_light = get_sun_brightness(sun_dir);
|
// // float sun_light = get_sun_brightness(sun_dir);
|
||||||
// float moon_light = get_moon_brightness(moon_dir);
|
// // float moon_light = get_moon_brightness(moon_dir);
|
||||||
// float my_alt = f_pos.z;//alt_at_real(f_pos.xy);
|
// // float my_alt = f_pos.z;//alt_at_real(f_pos.xy);
|
||||||
// vec3 f_norm = my_norm;
|
// // vec3 f_norm = my_norm;
|
||||||
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 my_alt = alt_at(f_pos.xy);
|
// // float shadow_alt = /*f_pos.z;*/alt_at(f_pos.xy);//max(alt_at(f_pos.xy), f_pos.z);
|
||||||
float shadow_alt = /*f_pos.z;*/alt_at(f_pos.xy);
|
// // float my_alt = alt_at(f_pos.xy);
|
||||||
float sun_shade_frac = horizon_at2(f_shadow, shadow_alt, f_pos, sun_dir);
|
// float sun_shade_frac = horizon_at2(f_shadow, shadow_alt, f_pos, sun_dir);
|
||||||
float moon_shade_frac = horizon_at2(f_shadow, shadow_alt, f_pos, moon_dir);
|
// float moon_shade_frac = horizon_at2(f_shadow, shadow_alt, f_pos, moon_dir);
|
||||||
// float sun_shade_frac = horizon_at(/*f_shadow, f_pos.z, */f_pos, sun_dir);
|
// // float sun_shade_frac = horizon_at(/*f_shadow, f_pos.z, */f_pos, sun_dir);
|
||||||
// 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);
|
||||||
// Globbal illumination "estimate" used to light the faces of voxels which are parallel to the sun or moon (which is a very common occurrence).
|
// // Globbal illumination "estimate" used to light the faces of voxels which are parallel to the sun or moon (which is a very common occurrence).
|
||||||
// Will be attenuated by k_d, which is assumed to carry any additional ambient occlusion information (e.g. about shadowing).
|
// // Will be attenuated by k_d, which is assumed to carry any additional ambient occlusion information (e.g. about shadowing).
|
||||||
// float ambient_sides = clamp(mix(0.5, 0.0, abs(dot(-f_norm, sun_dir)) * 10000.0), 0.0, 0.5);
|
// // float ambient_sides = clamp(mix(0.5, 0.0, abs(dot(-f_norm, sun_dir)) * 10000.0), 0.0, 0.5);
|
||||||
// NOTE: current assumption is that moon and sun shouldn't be out at the sae time.
|
// // NOTE: current assumption is that moon and sun shouldn't be out at the sae time.
|
||||||
// This assumption is (or can at least easily be) wrong, but if we pretend it's true we avoids having to explicitly pass in a separate shadow
|
// // This assumption is (or can at least easily be) wrong, but if we pretend it's true we avoids having to explicitly pass in a separate shadow
|
||||||
// for the sun and moon (since they have different brightnesses / colors so the shadows shouldn't attenuate equally).
|
// // for the sun and moon (since they have different brightnesses / colors so the shadows shouldn't attenuate equally).
|
||||||
float shade_frac = sun_shade_frac + moon_shade_frac;
|
// // float shade_frac = sun_shade_frac + moon_shade_frac;
|
||||||
// float brightness_denominator = (ambient_sides + vec3(SUN_AMBIANCE * sun_light + moon_light);
|
// // float brightness_denominator = (ambient_sides + vec3(SUN_AMBIANCE * sun_light + moon_light);
|
||||||
|
|
||||||
|
// DirectionalLight sun_info = get_sun_info(sun_dir, sun_shade_frac, light_pos);
|
||||||
|
DirectionalLight sun_info = get_sun_info(sun_dir, sun_shade_frac, /*sun_pos*/f_pos);
|
||||||
|
DirectionalLight moon_info = get_moon_info(moon_dir, moon_shade_frac/*, light_pos*/);
|
||||||
|
|
||||||
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.5;
|
const float n2 = 1.5;
|
||||||
@ -368,7 +507,7 @@ void main() {
|
|||||||
float fluid_alt = medium.x == 1u ? max(cam_alt + 1, floor(shadow_alt)) : view_distance.w;
|
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);
|
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.
|
// NOTE: Default intersection point is camera position, meaning if we fail to intersect we assume the whole camera is in water.
|
||||||
@ -376,14 +515,14 @@ void main() {
|
|||||||
// 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, 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);
|
max_light += get_sun_diffuse2(sun_info, moon_info, voxel_norm/*l_norm*/, 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, voxel_norm, 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))
|
// dot(diffuse_factor, /*R_r * */vec4(abs(norm) * (1.0 - dist), dist))
|
||||||
@ -406,10 +545,10 @@ void main() {
|
|||||||
// vec3(0.0, /*2.0 * SAMPLE_W*/square.w - square.y, alty1 - alty0)
|
// vec3(0.0, /*2.0 * SAMPLE_W*/square.w - square.y, alty1 - alty0)
|
||||||
// ));
|
// ));
|
||||||
// vec3 norm = normalize(vec3(
|
// vec3 norm = normalize(vec3(
|
||||||
// (altx0 - altx1) / (square.z - square.x),
|
// (altx0 - altx1) / (square.z - square.x),
|
||||||
// (alty0 - alty1) / (square.w - square.y),
|
// (alty0 - alty1) / (square.w - square.y),
|
||||||
// 1.0
|
// 1.0
|
||||||
// //(abs(square.w - square.y) + abs(square.z - square.x)) / (slope + 0.00001) // Avoid NaN
|
// //(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;
|
// If a side coordinate is 0, then it counts as no AO;
|
||||||
@ -423,32 +562,35 @@ void main() {
|
|||||||
// f_ao = /*sqrt*/1.0 - (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 * (dot(ao_pos, ao_pos)/* / 2.0*/);
|
||||||
// f_ao = /*sqrt*/1.0 - 2.0 * sqrt(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 = f_ao;// /*pow(f_ao, 0.5)*/f_ao * 0.9 + 0.1;
|
||||||
emitted_light *= ao;
|
emitted_light *= ao;
|
||||||
reflected_light *= ao;
|
reflected_light *= ao;
|
||||||
|
|
||||||
// emitted_light += 0.5 * vec3(SUN_AMBIANCE * sun_shade_frac * sun_light + moon_shade_frac * moon_light) * f_col * (ambient_sides + 1.0);
|
// emitted_light += 0.5 * vec3(SUN_AMBIANCE * sun_shade_frac * sun_light + moon_shade_frac * moon_light) * f_col * (ambient_sides + 1.0);
|
||||||
|
|
||||||
// Ambient lighting attempt: vertical light.
|
// Ambient lighting attempt: vertical light.
|
||||||
// reflected_light += /*0.0125*/0.15 * 0.25 * _col * light_reflection_factor(f_norm, cam_to_frag, vec3(0, 0, -1.0), 0.5 * f_col, 0.5 * f_col, 2.0);
|
// reflected_light += /*0.0125*/0.15 * 0.25 * _col * light_reflection_factor(f_norm, cam_to_frag, vec3(0, 0, -1.0), 0.5 * f_col, 0.5 * f_col, 2.0);
|
||||||
// emitted_light += /*0.0125*/0.25 * f_col * ;
|
// emitted_light += /*0.0125*/0.25 * f_col * ;
|
||||||
// vec3 light, diffuse_light, ambient_light;
|
// vec3 light, diffuse_light, ambient_light;
|
||||||
// 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, view_dir, 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);
|
||||||
|
|
||||||
vec4 clouds;
|
#if (CLOUD_MODE == CLOUD_MODE_REGULAR)
|
||||||
vec3 fog_color = get_sky_color(cam_to_frag/*view_dir*/, time_of_day.x, cam_pos.xyz, f_pos, 1.0, true, clouds);
|
vec4 clouds;
|
||||||
vec3 color = mix(mix(surf_color, fog_color, fog_level), clouds.rgb, clouds.a);
|
vec3 fog_color = get_sky_color(cam_to_frag/*view_dir*/, time_of_day.x, cam_pos.xyz, f_pos, 1.0, /*true*/false, clouds);
|
||||||
// vec3 color = surf_color;
|
vec3 color = mix(mix(surf_color, fog_color, fog_level), clouds.rgb, clouds.a);
|
||||||
|
#elif (CLOUD_MODE == CLOUD_MODE_NONE)
|
||||||
|
vec3 color = surf_color;
|
||||||
|
#endif
|
||||||
|
|
||||||
// float mist_factor = max(1 - (f_pos.z + (texture(t_noise, f_pos.xy * 0.0005 + time_of_day.x * 0.0003).x - 0.5) * 128.0) / 400.0, 0.0);
|
// float mist_factor = max(1 - (f_pos.z + (texture(t_noise, f_pos.xy * 0.0005 + time_of_day.x * 0.0003).x - 0.5) * 128.0) / 400.0, 0.0);
|
||||||
// //float mist_factor = f_norm.z * 2.0;
|
// //float mist_factor = f_norm.z * 2.0;
|
||||||
// color = mix(color, vec3(1.0) * /*diffuse_light*/reflected_light, clamp(mist_factor * 0.00005 * distance(f_pos.xy, focus_pos.xy), 0, 0.3));
|
// color = mix(color, vec3(1.0) * /*diffuse_light*/reflected_light, clamp(mist_factor * 0.00005 * distance(f_pos.xy, focus_pos.xy), 0, 0.3));
|
||||||
// color = surf_color;
|
// color = surf_color;
|
||||||
|
|
||||||
tgt_color = vec4(color, 1.0);
|
tgt_color = vec4(color, 1.0);
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ uniform u_locals {
|
|||||||
|
|
||||||
out vec3 f_pos;
|
out vec3 f_pos;
|
||||||
out vec3 f_norm;
|
out vec3 f_norm;
|
||||||
out vec2 v_pos_orig;
|
// out vec2 v_pos_orig;
|
||||||
// out vec4 f_square;
|
// out vec4 f_square;
|
||||||
// out vec4 f_shadow;
|
// out vec4 f_shadow;
|
||||||
// out float f_light;
|
// out float f_light;
|
||||||
@ -40,7 +40,7 @@ void main() {
|
|||||||
vec2 dims = vec2(1.0 / view_distance.y);
|
vec2 dims = vec2(1.0 / view_distance.y);
|
||||||
vec4 f_square = focus_pos.xyxy + vec4(splay(v_pos - dims), splay(v_pos + dims));
|
vec4 f_square = focus_pos.xyxy + vec4(splay(v_pos - dims), splay(v_pos + dims));
|
||||||
f_norm = lod_norm(f_pos.xy, f_square);
|
f_norm = lod_norm(f_pos.xy, f_square);
|
||||||
v_pos_orig = v_pos;
|
// v_pos_orig = v_pos;
|
||||||
|
|
||||||
// f_pos = lod_pos(focus_pos.xy + splay(v_pos) * /*1000000.0*/(1 << 20), square);
|
// f_pos = lod_pos(focus_pos.xy + splay(v_pos) * /*1000000.0*/(1 << 20), square);
|
||||||
|
|
||||||
@ -92,10 +92,13 @@ void main() {
|
|||||||
// f_light = 1.0;
|
// f_light = 1.0;
|
||||||
|
|
||||||
gl_Position =
|
gl_Position =
|
||||||
proj_mat *
|
/* proj_mat *
|
||||||
view_mat *
|
view_mat * */
|
||||||
|
all_mat *
|
||||||
vec4(f_pos/*newRay*/, 1);
|
vec4(f_pos/*newRay*/, 1);
|
||||||
// gl_Position.z = -gl_Position.z / gl_Position.w;
|
// gl_Position.z = -gl_Position.z / gl_Position.w;
|
||||||
|
// gl_Position.z = -gl_Position.z / gl_Position.w;
|
||||||
|
// gl_Position.z = -gl_Position.z * gl_Position.w;
|
||||||
// gl_Position.z = -gl_Position.z / 100.0;
|
// gl_Position.z = -gl_Position.z / 100.0;
|
||||||
gl_Position.z = -1000.0 / (gl_Position.z + 10000.0);
|
// gl_Position.z = -1000.0 / (gl_Position.z + 10000.0);
|
||||||
}
|
}
|
||||||
|
@ -18,18 +18,21 @@ in vec3 f_pos;
|
|||||||
in vec3 f_col;
|
in vec3 f_col;
|
||||||
flat in vec3 f_norm;
|
flat in vec3 f_norm;
|
||||||
in float f_ao;
|
in float f_ao;
|
||||||
in float f_alt;
|
// in float f_alt;
|
||||||
in vec4 f_shadow;
|
// in vec4 f_shadow;
|
||||||
|
|
||||||
layout (std140)
|
layout (std140)
|
||||||
uniform u_locals {
|
uniform u_locals {
|
||||||
mat4 model_mat;
|
mat4 model_mat;
|
||||||
vec4 model_col;
|
vec4 model_col;
|
||||||
|
ivec4 atlas_offs;
|
||||||
|
vec3 model_pos;
|
||||||
int flags;
|
int flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BoneData {
|
struct BoneData {
|
||||||
mat4 bone_mat;
|
mat4 bone_mat;
|
||||||
|
mat4 normals_mat;
|
||||||
};
|
};
|
||||||
|
|
||||||
layout (std140)
|
layout (std140)
|
||||||
@ -44,17 +47,17 @@ uniform u_bones {
|
|||||||
out vec4 tgt_color;
|
out vec4 tgt_color;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
float distance = distance(vec3(cam_pos), focus_pos.xyz) - 2;
|
// float distance = distance(vec3(cam_pos), focus_pos.xyz) - 2;
|
||||||
|
|
||||||
float opacity = clamp(distance / distance_divider, 0, 1);
|
// float opacity = clamp(distance / distance_divider, 0, 1);
|
||||||
|
|
||||||
if(threshold_matrix[int(gl_FragCoord.x) % 4][int(gl_FragCoord.y) % 4] > opacity) {
|
// if(threshold_matrix[int(gl_FragCoord.x) % 4][int(gl_FragCoord.y) % 4] > opacity) {
|
||||||
discard;
|
// discard;
|
||||||
}
|
// }
|
||||||
|
|
||||||
if(threshold_matrix[int(gl_FragCoord.x) % 4][int(gl_FragCoord.y) % 4] > shadow_dithering) {
|
// if(threshold_matrix[int(gl_FragCoord.x) % 4][int(gl_FragCoord.y) % 4] > shadow_dithering) {
|
||||||
discard;
|
// discard;
|
||||||
}
|
// }
|
||||||
|
|
||||||
tgt_color = vec4(0.0,0.0,0.0, 1.0);
|
tgt_color = vec4(0.0,0.0,0.0, 1.0);
|
||||||
}
|
}
|
||||||
|
@ -144,9 +144,9 @@ vec3 illuminate(float max_light, vec3 view_dir, /*vec3 max_light, */vec3 emitted
|
|||||||
void main() {
|
void main() {
|
||||||
vec2 uv = (f_pos + 1.0) * 0.5;
|
vec2 uv = (f_pos + 1.0) * 0.5;
|
||||||
|
|
||||||
if (medium.x == 1u) {
|
/* if (medium.x == 1u) {
|
||||||
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 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;
|
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;
|
||||||
@ -186,9 +186,11 @@ void main() {
|
|||||||
|
|
||||||
vec4 final_color = pow(aa_color, gamma);
|
vec4 final_color = pow(aa_color, gamma);
|
||||||
|
|
||||||
/* if (medium.x == 1u) {
|
#if (FLUID_MODE == FLUID_MODE_CHEAP)
|
||||||
|
if (medium.x == 1u) {
|
||||||
final_color *= vec4(0.2, 0.2, 0.8, 1.0);
|
final_color *= vec4(0.2, 0.2, 0.8, 1.0);
|
||||||
} */
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
tgt_color = vec4(final_color.rgb, 1);
|
tgt_color = vec4(final_color.rgb, 1);
|
||||||
}
|
}
|
||||||
|
@ -30,5 +30,5 @@ out vec2 f_pos;
|
|||||||
void main() {
|
void main() {
|
||||||
f_pos = v_pos;
|
f_pos = v_pos;
|
||||||
|
|
||||||
gl_Position = vec4(v_pos, 0.0, 1.0);
|
gl_Position = vec4(v_pos, -1.0, 1.0);
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,8 @@ uniform u_locals {
|
|||||||
out vec4 tgt_color;
|
out vec4 tgt_color;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
// tgt_color = vec4(MU_SCATTER, 1.0);
|
||||||
|
// return;
|
||||||
vec4 _clouds;
|
vec4 _clouds;
|
||||||
|
|
||||||
vec3 cam_dir = normalize(f_pos - cam_pos.xyz);
|
vec3 cam_dir = normalize(f_pos - cam_pos.xyz);
|
||||||
|
@ -28,12 +28,22 @@ uniform u_locals {
|
|||||||
out vec3 f_pos;
|
out vec3 f_pos;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
/* vec3 v_pos = v_pos;
|
||||||
|
v_pos.y = -v_pos.y; */
|
||||||
f_pos = v_pos;
|
f_pos = v_pos;
|
||||||
|
|
||||||
// TODO: Make this position-independent to avoid rounding error jittering
|
// TODO: Make this position-independent to avoid rounding error jittering
|
||||||
gl_Position =
|
gl_Position =
|
||||||
proj_mat *
|
/* proj_mat *
|
||||||
view_mat *
|
view_mat * */
|
||||||
vec4(v_pos * 100000.0 + cam_pos.xyz, 1);
|
all_mat *
|
||||||
gl_Position.z = 0.0;
|
/* proj_mat *
|
||||||
|
view_mat * */
|
||||||
|
vec4(/*100000 * */v_pos + cam_pos.xyz, 1);
|
||||||
|
// vec4(v_pos * (100000.0/* + 0.5*/) + cam_pos.xyz, 1);
|
||||||
|
// gl_Position = vec4(gl_Position.xy, sign(gl_Position.z) * gl_Position.w, gl_Position.w);
|
||||||
|
gl_Position.z = gl_Position.w;
|
||||||
|
// gl_Position.z = gl_Position.w - 0.000001;//0.0;
|
||||||
|
// gl_Position.z = 1.0;
|
||||||
|
// gl_Position.z = -1.0;
|
||||||
}
|
}
|
||||||
|
@ -12,15 +12,32 @@
|
|||||||
|
|
||||||
#define LIGHTING_DISTRIBUTION LIGHTING_DISTRIBUTION_BECKMANN
|
#define LIGHTING_DISTRIBUTION LIGHTING_DISTRIBUTION_BECKMANN
|
||||||
|
|
||||||
// #define HAS_SHADOW_MAPS
|
#define HAS_SHADOW_MAPS
|
||||||
|
|
||||||
#include <globals.glsl>
|
#include <globals.glsl>
|
||||||
|
|
||||||
in vec3 f_pos;
|
in vec3 f_pos;
|
||||||
flat in vec3 f_norm;
|
flat in vec3 f_norm;
|
||||||
in vec3 f_col;
|
flat in float f_light;
|
||||||
in float f_ao;
|
// flat in vec3 f_pos_norm;
|
||||||
|
in vec2 f_uv_pos;
|
||||||
|
// flat in uint f_atlas_pos;
|
||||||
|
// in vec3 f_col;
|
||||||
|
// in float f_ao;
|
||||||
// in float f_light;
|
// in float f_light;
|
||||||
|
// in vec4 light_pos[2];
|
||||||
|
|
||||||
|
uniform sampler2D t_col_light;
|
||||||
|
|
||||||
|
//struct ShadowLocals {
|
||||||
|
// mat4 shadowMatrices;
|
||||||
|
// mat4 texture_mat;
|
||||||
|
//};
|
||||||
|
//
|
||||||
|
//layout (std140)
|
||||||
|
//uniform u_light_shadows {
|
||||||
|
// ShadowLocals shadowMats[/*MAX_LAYER_FACES*/192];
|
||||||
|
//};
|
||||||
|
|
||||||
out vec4 tgt_color;
|
out vec4 tgt_color;
|
||||||
|
|
||||||
@ -31,19 +48,70 @@ out vec4 tgt_color;
|
|||||||
const float FADE_DIST = 32.0;
|
const float FADE_DIST = 32.0;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
/* if (f_uv_pos.x < 757) {
|
||||||
|
discard;
|
||||||
|
} */
|
||||||
|
// vec2 f_uv_pos = vec2(768,1) + 0.5;
|
||||||
|
// vec2 f_uv_pos = vec2(760, 380);// + 0.5;
|
||||||
|
// vec2 f_uv_pos = vec2((uvec2(f_atlas_pos) >> uvec2(0, 16)) & uvec2(0xFFFFu, 0xFFFFu)) + 0.5;
|
||||||
|
/* if (f_uv_pos.x < 757) {
|
||||||
|
discard;
|
||||||
|
} */
|
||||||
|
// vec3 du = dFdx(f_pos);
|
||||||
|
// vec3 dv = dFdy(f_pos);
|
||||||
|
// vec3 f_norm = normalize(cross(du, dv));
|
||||||
|
|
||||||
|
// vec4 f_col_light = texture(t_col_light, (f_uv_pos + 0.5) / textureSize(t_col_light, 0)/* + uv_delta*//* - f_norm * 0.00001*/);
|
||||||
|
// vec4 f_col_light = textureGrad(t_col_light, (f_uv_pos + 0.5) / textureSize(t_col_light, 0), vec2(0.5), vec2(0.5));
|
||||||
|
vec4 f_col_light = texelFetch(t_col_light, ivec2(f_uv_pos)/* + uv_delta*//* - f_norm * 0.00001*/, 0);
|
||||||
|
vec3 f_col = /*linear_to_srgb*//*srgb_to_linear*/(f_col_light.rgb);
|
||||||
|
// vec3 f_col = vec3(1.0);
|
||||||
|
// vec2 texSize = textureSize(t_col_light, 0);
|
||||||
|
// float f_ao = f_col_light.a;
|
||||||
|
// float f_ao = f_col_light.a + length(vec2(dFdx(f_col_light.a), dFdy(f_col_light.a)));
|
||||||
|
float f_ao = texture(t_col_light, (f_uv_pos + 0.5) / textureSize(t_col_light, 0)).a;//1.0;//f_col_light.a * 4.0;// f_light = float(v_col_light & 0x3Fu) / 64.0;
|
||||||
|
// float f_ao = 1.0;
|
||||||
|
// float /*f_light*/f_ao = textureProj(t_col_light, vec3(f_uv_pos, texSize)).a;//1.0;//f_col_light.a * 4.0;// f_light = float(v_col_light & 0x3Fu) / 64.0;
|
||||||
|
|
||||||
|
// vec3 my_chunk_pos = f_pos_norm;
|
||||||
|
// tgt_color = vec4(hash(floor(vec4(my_chunk_pos.x, 0, 0, 0))), hash(floor(vec4(0, my_chunk_pos.y, 0, 1))), hash(floor(vec4(0, 0, my_chunk_pos.z, 2))), 1.0);
|
||||||
|
// tgt_color = vec4(f_uv_pos / texSize, 0.0, 1.0);
|
||||||
|
// tgt_color = vec4(f_col.rgb, 1.0);
|
||||||
|
// return;
|
||||||
|
// vec4 light_pos[2];
|
||||||
|
//#if (SHADOW_MODE == SHADOW_MODE_MAP)
|
||||||
|
// // for (uint i = 0u; i < light_shadow_count.z; ++i) {
|
||||||
|
// // light_pos[i] = /*vec3(*/shadowMats[i].texture_mat * vec4(f_pos, 1.0)/*)*/;
|
||||||
|
// // }
|
||||||
|
// vec4 sun_pos = /*vec3(*/shadowMats[0].texture_mat * vec4(f_pos, 1.0)/*)*/;
|
||||||
|
//#elif (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_NONE)
|
||||||
|
// vec4 sun_pos = vec4(0.0);
|
||||||
|
//#endif
|
||||||
vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz);
|
vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz);
|
||||||
// vec4 vert_pos4 = view_mat * vec4(f_pos, 1.0);
|
// vec4 vert_pos4 = view_mat * vec4(f_pos, 1.0);
|
||||||
// vec3 view_dir = normalize(-vec3(vert_pos4)/* / vert_pos4.w*/);
|
// vec3 view_dir = normalize(-vec3(vert_pos4)/* / vert_pos4.w*/);
|
||||||
vec3 view_dir = -cam_to_frag;
|
vec3 view_dir = -cam_to_frag;
|
||||||
|
|
||||||
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); */
|
||||||
// float sun_light = get_sun_brightness(sun_dir);
|
// float sun_light = get_sun_brightness(sun_dir);
|
||||||
// float moon_light = get_moon_brightness(moon_dir);
|
// float moon_light = get_moon_brightness(moon_dir);
|
||||||
|
|
||||||
|
#if (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_MAP || FLUID_MODE == FLUID_MODE_SHINY)
|
||||||
float f_alt = alt_at(f_pos.xy);
|
float f_alt = alt_at(f_pos.xy);
|
||||||
|
// float f_alt = f_pos.z;
|
||||||
|
#elif (SHADOW_MODE == SHADOW_MODE_NONE || FLUID_MODE == FLUID_MODE_CHEAP)
|
||||||
|
float f_alt = f_pos.z;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_MAP)
|
||||||
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 sun_shade_frac = horizon_at2(f_shadow, f_alt, f_pos, sun_dir);
|
float sun_shade_frac = horizon_at2(f_shadow, f_alt, f_pos, sun_dir);
|
||||||
float moon_shade_frac = horizon_at2(f_shadow, f_alt, f_pos, moon_dir);
|
// float sun_shade_frac = 1.0;//horizon_at2(f_shadow, f_alt, f_pos, sun_dir);
|
||||||
|
#elif (SHADOW_MODE == SHADOW_MODE_NONE)
|
||||||
|
float sun_shade_frac = 1.0;//horizon_at2(f_shadow, f_alt, f_pos, sun_dir);
|
||||||
|
#endif
|
||||||
|
float moon_shade_frac = 1.0;//horizon_at2(f_shadow, f_alt, f_pos, moon_dir);
|
||||||
// float sun_shade_frac = horizon_at(f_pos, sun_dir);
|
// float sun_shade_frac = horizon_at(f_pos, sun_dir);
|
||||||
// float moon_shade_frac = horizon_at(f_pos, moon_dir);
|
// float moon_shade_frac = horizon_at(f_pos, moon_dir);
|
||||||
// Globbal illumination "estimate" used to light the faces of voxels which are parallel to the sun or moon (which is a very common occurrence).
|
// Globbal illumination "estimate" used to light the faces of voxels which are parallel to the sun or moon (which is a very common occurrence).
|
||||||
@ -52,7 +120,12 @@ void main() {
|
|||||||
// NOTE: current assumption is that moon and sun shouldn't be out at the sae time.
|
// NOTE: current assumption is that moon and sun shouldn't be out at the sae time.
|
||||||
// This assumption is (or can at least easily be) wrong, but if we pretend it's true we avoids having to explicitly pass in a separate shadow
|
// This assumption is (or can at least easily be) wrong, but if we pretend it's true we avoids having to explicitly pass in a separate shadow
|
||||||
// for the sun and moon (since they have different brightnesses / colors so the shadows shouldn't attenuate equally).
|
// for the sun and moon (since they have different brightnesses / colors so the shadows shouldn't attenuate equally).
|
||||||
float shade_frac = sun_shade_frac + moon_shade_frac;
|
// float shade_frac = sun_shade_frac + moon_shade_frac;
|
||||||
|
|
||||||
|
// DirectionalLight sun_info = get_sun_info(sun_dir, sun_shade_frac, light_pos);
|
||||||
|
float point_shadow = shadow_at(f_pos, f_norm);
|
||||||
|
DirectionalLight sun_info = get_sun_info(sun_dir, point_shadow * sun_shade_frac, /*sun_pos*/f_pos);
|
||||||
|
DirectionalLight moon_info = get_moon_info(moon_dir, point_shadow * moon_shade_frac/*, light_pos*/);
|
||||||
|
|
||||||
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;
|
||||||
@ -69,7 +142,6 @@ void main() {
|
|||||||
|
|
||||||
vec3 emitted_light, reflected_light;
|
vec3 emitted_light, reflected_light;
|
||||||
|
|
||||||
float point_shadow = shadow_at(f_pos, f_norm);
|
|
||||||
// To account for prior saturation.
|
// To account for prior saturation.
|
||||||
// float vert_light = pow(f_light, 1.5);
|
// float vert_light = pow(f_light, 1.5);
|
||||||
// vec3 light_frac = 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 = light_reflection_factor(f_norm/*vec3(0, 0, 1.0)*/, view_dir, vec3(0, 0, -1.0), vec3(1.0), vec3(R_s), alpha);
|
||||||
@ -85,10 +157,13 @@ void main() {
|
|||||||
// vec3 surf_color = srgb_to_linear(vec3(0.2, 0.5, 1.0));
|
// vec3 surf_color = srgb_to_linear(vec3(0.2, 0.5, 1.0));
|
||||||
// vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz);
|
// vec3 cam_to_frag = normalize(f_pos - cam_pos.xyz);
|
||||||
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*/view_dir, k_a/* * (shade_frac * 0.5 + light_frac * 0.5)*/, k_d, k_s, alpha, emitted_light, reflected_light);
|
max_light += get_sun_diffuse2(sun_info, moon_info, f_norm, /*time_of_day.x, *//*cam_to_frag*/view_dir, k_a * f_light/* * (shade_frac * 0.5 + light_frac * 0.5)*/, k_d, k_s, alpha, emitted_light, reflected_light);
|
||||||
reflected_light *= /*vert_light * */point_shadow * shade_frac;
|
// reflected_light *= /*vert_light * */point_shadow * shade_frac;
|
||||||
emitted_light *= /*vert_light * */point_shadow * max(shade_frac, MIN_SHADOW);
|
// emitted_light *= /*vert_light * */point_shadow * max(shade_frac, MIN_SHADOW);
|
||||||
max_light *= /*vert_light * */point_shadow * shade_frac;
|
// max_light *= /*vert_light * */point_shadow * shade_frac;
|
||||||
|
// emitted_light *= point_shadow;
|
||||||
|
// reflected_light *= point_shadow;
|
||||||
|
// max_light *= point_shadow;
|
||||||
// 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);
|
||||||
// float point_shadow = shadow_at(f_pos, f_norm);
|
// float point_shadow = shadow_at(f_pos, f_norm);
|
||||||
// diffuse_light *= f_light * point_shadow;
|
// diffuse_light *= f_light * point_shadow;
|
||||||
@ -102,17 +177,23 @@ void main() {
|
|||||||
emitted_light += point_light;
|
emitted_light += point_light;
|
||||||
reflected_light += point_light; */
|
reflected_light += point_light; */
|
||||||
|
|
||||||
float ao = /*pow(f_ao, 0.5)*/f_ao * 0.85 + 0.15;
|
// float ao = /*pow(f_ao, 0.5)*/f_ao * 0.85 + 0.15;
|
||||||
|
float ao = f_ao;
|
||||||
emitted_light *= ao;
|
emitted_light *= ao;
|
||||||
reflected_light *= ao;
|
reflected_light *= ao;
|
||||||
|
|
||||||
surf_color = illuminate(max_light, view_dir, 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);
|
||||||
|
|
||||||
|
#if (CLOUD_MODE == CLOUD_MODE_REGULAR)
|
||||||
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;
|
||||||
vec3 fog_color = get_sky_color(cam_to_frag/*view_dir*/, time_of_day.x, cam_pos.xyz, f_pos, 0.5, true, clouds);
|
vec3 fog_color = get_sky_color(cam_to_frag/*view_dir*/, time_of_day.x, cam_pos.xyz, f_pos, 0.5, false, clouds);
|
||||||
vec3 color = mix(mix(surf_color, fog_color, fog_level), clouds.rgb, clouds.a);
|
vec3 color = mix(mix(surf_color, fog_color, fog_level), clouds.rgb, clouds.a);
|
||||||
|
#elif (CLOUD_MODE == CLOUD_MODE_NONE)
|
||||||
|
vec3 color = surf_color;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// tgt_color = vec4(color, 1.0);
|
||||||
tgt_color = vec4(color, 1.0 - clamp((distance(focus_pos.xy, f_pos.xy) - (sprite_render_distance - FADE_DIST)) / FADE_DIST, 0, 1));
|
tgt_color = vec4(color, 1.0 - clamp((distance(focus_pos.xy, f_pos.xy) - (sprite_render_distance - FADE_DIST)) / FADE_DIST, 0, 1));
|
||||||
}
|
}
|
||||||
|
@ -14,64 +14,223 @@
|
|||||||
|
|
||||||
#include <globals.glsl>
|
#include <globals.glsl>
|
||||||
#include <srgb.glsl>
|
#include <srgb.glsl>
|
||||||
|
#include <sky.glsl>
|
||||||
|
|
||||||
in vec3 v_pos;
|
in vec3 v_pos;
|
||||||
in uint v_col;
|
in uint v_atlas_pos;
|
||||||
|
// in uint v_col;
|
||||||
in uint v_norm_ao;
|
in uint v_norm_ao;
|
||||||
|
in uint inst_pos_ori;
|
||||||
in vec4 inst_mat0;
|
in vec4 inst_mat0;
|
||||||
in vec4 inst_mat1;
|
in vec4 inst_mat1;
|
||||||
in vec4 inst_mat2;
|
in vec4 inst_mat2;
|
||||||
in vec4 inst_mat3;
|
in vec4 inst_mat3;
|
||||||
in vec3 inst_col;
|
// in vec3 inst_col;
|
||||||
in float inst_wind_sway;
|
in float inst_wind_sway;
|
||||||
|
|
||||||
|
struct SpriteLocals {
|
||||||
|
mat4 mat;
|
||||||
|
vec4 wind_sway;
|
||||||
|
vec4 offs;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout (std140)
|
||||||
|
uniform u_locals {
|
||||||
|
mat4 mat;
|
||||||
|
vec4 wind_sway;
|
||||||
|
vec4 offs;
|
||||||
|
// SpriteLocals sprites[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
// struct Instance {
|
||||||
|
// mat4 inst_mat;
|
||||||
|
// vec3 inst_col;
|
||||||
|
// float inst_wind_sway;
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// layout (std140)
|
||||||
|
// uniform u_ibuf {
|
||||||
|
// Instance sprite_instances[/*MAX_LAYER_FACES*/512];
|
||||||
|
// };
|
||||||
|
|
||||||
|
//struct ShadowLocals {
|
||||||
|
// mat4 shadowMatrices;
|
||||||
|
// mat4 texture_mat;
|
||||||
|
//};
|
||||||
|
//
|
||||||
|
//layout (std140)
|
||||||
|
//uniform u_light_shadows {
|
||||||
|
// ShadowLocals shadowMats[/*MAX_LAYER_FACES*/192];
|
||||||
|
//};
|
||||||
|
|
||||||
|
layout (std140)
|
||||||
|
uniform u_terrain_locals {
|
||||||
|
vec3 model_offs;
|
||||||
|
float load_time;
|
||||||
|
ivec4 atlas_offs;
|
||||||
|
};
|
||||||
|
|
||||||
out vec3 f_pos;
|
out vec3 f_pos;
|
||||||
flat out vec3 f_norm;
|
flat out vec3 f_norm;
|
||||||
out vec3 f_col;
|
flat out float f_light;
|
||||||
out float f_ao;
|
// flat out vec3 f_pos_norm;
|
||||||
|
// out vec3 f_col;
|
||||||
|
// out float f_ao;
|
||||||
|
out vec2 f_uv_pos;
|
||||||
|
// flat out uint f_atlas_pos;
|
||||||
|
// out vec3 light_pos[2];
|
||||||
// out float f_light;
|
// out float f_light;
|
||||||
|
|
||||||
const float SCALE = 1.0 / 11.0;
|
const float SCALE = 1.0 / 11.0;
|
||||||
|
const float SCALE_FACTOR = pow(SCALE, 1.3) * 0.2;
|
||||||
|
|
||||||
|
const int EXTRA_NEG_Z = 32768;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
mat4 inst_mat;
|
// vec3 inst_chunk_pos = vec3(ivec3((uvec3(inst_pos_ori) >> uvec3(0, 6, 12)) & uvec3(0x3Fu, 0x3Fu, 0xFFFFu)) - ivec3(0, 0, EXTRA_NEG_Z));
|
||||||
inst_mat[0] = inst_mat0;
|
// uint inst_ori = (inst_pos_ori >> 29) & 0x7u;
|
||||||
inst_mat[1] = inst_mat1;
|
// SpriteLocals locals = sprites[inst_ori];
|
||||||
inst_mat[2] = inst_mat2;
|
// SpriteLocals locals = sprites;
|
||||||
inst_mat[3] = inst_mat3;
|
// mat4 inst_mat = locals.mat;
|
||||||
|
// float inst_wind_sway = locals.wind_sway.w;
|
||||||
|
|
||||||
vec3 sprite_pos = (inst_mat * vec4(0, 0, 0, 1)).xyz;
|
// mat4 inst_mat = mat4(vec4(1, 0, 0, 0), vec4(0, 1, 0, 0), vec4(0, 0, 1, 0), vec4(5.5, 5.5, 0, 1));
|
||||||
|
// float inst_wind_sway = 0.0;
|
||||||
|
mat4 inst_mat;
|
||||||
|
inst_mat[0] = inst_mat0;
|
||||||
|
inst_mat[1] = inst_mat1;
|
||||||
|
inst_mat[2] = inst_mat2;
|
||||||
|
inst_mat[3] = inst_mat3;
|
||||||
|
/* Instance instances = sprite_instances[gl_InstanceID & 1023];
|
||||||
|
mat4 inst_mat = instances.inst_mat;
|
||||||
|
vec3 inst_col = instances.inst_col;
|
||||||
|
float inst_wind_sway = instances.inst_wind_sway; */
|
||||||
|
vec3 inst_offs = model_offs - focus_off.xyz;
|
||||||
|
// mat3 inst_mat;
|
||||||
|
// inst_mat[0] = inst_mat0.xyz;
|
||||||
|
// inst_mat[1] = inst_mat1.xyz;
|
||||||
|
// inst_mat[2] = inst_mat2.xyz;
|
||||||
|
// /* Instance instances = sprite_instances[gl_InstanceID & 1023];
|
||||||
|
// mat4 inst_mat = instances.inst_mat;
|
||||||
|
// vec3 inst_col = instances.inst_col;
|
||||||
|
// float inst_wind_sway = instances.inst_wind_sway; */
|
||||||
|
// float inst_wind_sway = wind_sway.w;
|
||||||
|
// vec3 inst_offs = model_offs - focus_off.xyz;
|
||||||
|
|
||||||
f_pos = (inst_mat * vec4(v_pos * SCALE, 1)).xyz;
|
// vec3 sprite_pos = floor(inst_mat3.xyz * SCALE) + inst_offs;
|
||||||
f_pos.z -= min(32.0, 25.0 * pow(distance(focus_pos.xy, f_pos.xy) / view_distance.x, 20.0));
|
|
||||||
|
|
||||||
// Wind waving
|
// f_pos_norm = v_pos;
|
||||||
f_pos += inst_wind_sway * vec3(
|
|
||||||
sin(tick.x * 1.5 + f_pos.y * 0.1) * sin(tick.x * 0.35),
|
|
||||||
sin(tick.x * 1.5 + f_pos.x * 0.1) * sin(tick.x * 0.25),
|
|
||||||
0.0
|
|
||||||
) * pow(abs(v_pos.z) * SCALE, 1.3) * 0.2;
|
|
||||||
|
|
||||||
// First 3 normals are negative, next 3 are positive
|
// vec3 sprite_pos = (inst_mat * vec4(0, 0, 0, 1)).xyz;
|
||||||
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 sprite_pos = floor((inst_mat * vec4(0, 0, 0, 1)).xyz * SCALE/* - vec3(0.5, 0.5, 0.0)*/) + inst_offs;
|
||||||
f_norm = (inst_mat * vec4(normals[(v_norm_ao >> 0) & 0x7u], 0)).xyz;
|
// vec3 sprite_pos = /*round*/floor(((inst_mat * vec4(0, 0, 0, 1)).xyz - /* wind_sway.xyz * */offs.xyz) * SCALE/* - vec3(0.5, 0.5, 0.0)*/) - inst_offs;
|
||||||
|
// vec3 sprite_pos = /*round*/floor(((inst_mat * vec4(-offs.xyz, 1)).xyz) * SCALE/* - vec3(0.5, 0.5, 0.0)*/) + inst_offs;
|
||||||
|
|
||||||
vec3 col = vec3((uvec3(v_col) >> uvec3(0, 8, 16)) & uvec3(0xFFu)) / 255.0;
|
// vec3 v_pos = vec3(gl_VertexID * 32, gl_VertexID % 32, 1.0);
|
||||||
f_col = srgb_to_linear(col) * srgb_to_linear(inst_col);
|
// f_pos = v_pos + (model_offs - focus_off.xyz);
|
||||||
f_ao = float((v_norm_ao >> 3) & 0x3u) / 4.0;
|
|
||||||
|
|
||||||
// Select glowing
|
// vec3 v_pos = /*inst_mat*//*locals.*/wind_sway.xyz * v_pos;
|
||||||
if (select_pos.w > 0 && select_pos.xyz == floor(sprite_pos)) {
|
vec3 v_pos_ = /*inst_mat*//*locals.*//*sprites[0].*/wind_sway.xyz * v_pos;
|
||||||
f_col *= 4.0;
|
// vec3 v_pos = (/*inst_mat*/locals.mat * vec4(v_pos, 1)).xyz + vec3(0.5, 0.5, 0.0);
|
||||||
}
|
// f_pos = v_pos * SCALE + (inst_chunk_pos + model_offs - focus_off.xyz);
|
||||||
|
|
||||||
// f_light = 1.0;
|
// vec3 v_pos_ = (inst_mat * vec4(v_pos/* * SCALE*/, 1)).xyz;
|
||||||
|
// vec3 v_pos = (inst_mat * vec4(v_pos, 1)).xyz;
|
||||||
|
// f_pos = v_pos + (model_offs - focus_off.xyz);
|
||||||
|
|
||||||
gl_Position =
|
f_pos = (inst_mat * vec4(v_pos_, 1.0)).xyz * SCALE + inst_offs;
|
||||||
all_mat *
|
// f_pos = (inst_mat * v_pos_) * SCALE + sprite_pos;
|
||||||
vec4(f_pos, 1);
|
|
||||||
// gl_Position.z = -gl_Position.z / gl_Position.w;
|
// f_pos = (inst_mat * vec4(v_pos * SCALE, 1)).xyz + (model_offs - focus_off.xyz);
|
||||||
// gl_Position.z = -gl_Position.z / 100.0;
|
// f_pos = v_pos_ + (inst_chunk_pos + model_offs - focus_off.xyz + vec3(0.5, 0.5, 0.0));
|
||||||
// gl_Position.z = -gl_Position.z / 100.0;
|
// f_pos.z -= min(32.0, 25.0 * pow(distance(focus_pos.xy, f_pos.xy) / view_distance.x, 20.0));
|
||||||
gl_Position.z = -1000.0 / (gl_Position.z + 10000.0);
|
|
||||||
|
// Wind waving
|
||||||
|
/* const float x_scale = sin(tick.x * 1.5 + f_pos.x * 0.1);
|
||||||
|
const float y_scale = sin(tick.x * 1.5 + f_pos.y * 0.1);
|
||||||
|
const float z_scale = pow(abs(v_pos_.z), 1.3) * SCALE_FACTOR;
|
||||||
|
const float xy_bias = sin(tick.x * 0.25);
|
||||||
|
const float z_bias = xy_bias * t_scale;
|
||||||
|
mat3 shear = mat4(
|
||||||
|
vec3(x_scale , 0.0, 0.0, 0.0),
|
||||||
|
vec3(0.0, y_scale, 0.0, 0.0),
|
||||||
|
vec3(0.0, 0.0, z_bias, 0.0),
|
||||||
|
vec3(0.0, 0.0, (1.0 / z_bias), 0.0)
|
||||||
|
); */
|
||||||
|
// const float x_scale = sin(tick.x * 1.5 + f_pos.x * 0.1);
|
||||||
|
// const float y_scale = sin(tick.x * 1.5 + f_pos.y * 0.1);
|
||||||
|
// const float z_scale = pow(abs(v_pos_.z), 1.3) * SCALE_FACTOR;
|
||||||
|
// const float xy_bias = sin(tick.x * 0.25);
|
||||||
|
// const float z_bias = xy_bias * t_scale;
|
||||||
|
// vec3 rotate = inst_wind_sway * vec3(
|
||||||
|
// sin(tick.x * 1.5 + f_pos.y * 0.1) * sin(tick.x * 0.35),
|
||||||
|
// sin(tick.x * 1.5 + f_pos.x * 0.1) * sin(tick.x * 0.25),
|
||||||
|
// 0.0
|
||||||
|
// ) * pow(abs(v_pos_.z/* + sprites[0].offs.z*/)/* * SCALE*/, 1.3) * /*0.2;*/SCALE_FACTOR;
|
||||||
|
//
|
||||||
|
// mat3 shear = mat4(
|
||||||
|
// vec3(x_scale * , 0.0, 0.0, 0.0),
|
||||||
|
// vec3(0.0, y_scale, 0.0, 0.0),
|
||||||
|
// vec3(0.0, 0.0, z_bias, 0.0),
|
||||||
|
// vec3(0.0, 0.0, (1.0 / z_bias), 0.0)
|
||||||
|
// );
|
||||||
|
if (wind_sway.w >= 0.4) {
|
||||||
|
f_pos += /*inst_wind_sway*/wind_sway.w * vec3(
|
||||||
|
sin(tick.x * 1.5 + f_pos.y * 0.1) * sin(tick.x * 0.35),
|
||||||
|
sin(tick.x * 1.5 + f_pos.x * 0.1) * sin(tick.x * 0.25),
|
||||||
|
0.0
|
||||||
|
) * pow(abs(v_pos_.z/* + sprites[0].offs.z*/)/* * SCALE*/, 1.3) * /*0.2;*/SCALE_FACTOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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));
|
||||||
|
// uint norm_idx = (v_norm_ao >> 0) & 0x7u;
|
||||||
|
// f_norm = (inst_mat * vec4(normals[], 0)).xyz;
|
||||||
|
|
||||||
|
// TODO: Consider adding a second, already-normalized (i.e. unscaled) matrix.
|
||||||
|
// vec3 norm = /*normalize*/(inst_mat/*locals.mat*/[(v_norm_ao >> 1u) & 3u].xyz);
|
||||||
|
// vec3 norm = /*normalize*/(inst_mat/*locals.mat*/[(v_norm_ao >> 1u) & 3u]);
|
||||||
|
|
||||||
|
// vec3 norm = bone_data.normals_mat[axis_idx].xyz;
|
||||||
|
// norm = normalize(norm);
|
||||||
|
// norm = norm / SCALE_FACTOR / locals.wind_sway.xyz;
|
||||||
|
// norm = norm / (norm.x + norm.y + norm.z);
|
||||||
|
// vec3 norm = norm_mat * vec4(uvec3(1 << axis_idx) & uvec3(0x1u, 0x3u, 0x7u), 1);
|
||||||
|
|
||||||
|
// // Calculate normal here rather than for each pixel in the fragment shader
|
||||||
|
// f_norm = normalize((
|
||||||
|
// combined_mat *
|
||||||
|
// vec4(norm, 0)
|
||||||
|
// ).xyz);
|
||||||
|
|
||||||
|
vec3 norm = /*normalize*/(inst_mat/*locals.mat*/[(v_norm_ao >> 1u) & 3u].xyz);
|
||||||
|
f_norm = mix(-norm, norm, v_norm_ao & 1u);
|
||||||
|
|
||||||
|
/* vec3 col = vec3((uvec3(v_col) >> uvec3(0, 8, 16)) & uvec3(0xFFu)) / 255.0;
|
||||||
|
f_col = srgb_to_linear(col) * srgb_to_linear(inst_col);
|
||||||
|
f_ao = float((v_norm_ao >> 3) & 0x3u) / 4.0; */
|
||||||
|
f_uv_pos = vec2((uvec2(v_atlas_pos) >> uvec2(0, 16)) & uvec2(0xFFFFu, 0xFFFFu));/* + 0.5*/;
|
||||||
|
// f_atlas_pos = v_atlas_pos;
|
||||||
|
/* for (uint i = 0u; i < light_shadow_count.z; ++i) {
|
||||||
|
light_pos[i] = vec3(shadowMats[i].texture_mat * vec4(f_pos, 1.0));
|
||||||
|
} */
|
||||||
|
|
||||||
|
// // Select glowing
|
||||||
|
// if (select_pos.w > 0 && select_pos.xyz == floor(sprite_pos)) {
|
||||||
|
// f_col *= 4.0;
|
||||||
|
// }
|
||||||
|
// f_light = 1.0;
|
||||||
|
// if (select_pos.w > 0) */{
|
||||||
|
vec3 sprite_pos = /*round*/floor(((inst_mat * vec4(-offs.xyz, 1)).xyz) * SCALE/* - vec3(0.5, 0.5, 0.0)*/) + inst_offs;
|
||||||
|
f_light = (select_pos.w > 0 && select_pos.xyz == sprite_pos/* - vec3(0.5, 0.5, 0.0) * SCALE*/) ? 1.0 / PERSISTENT_AMBIANCE : 1.0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
gl_Position =
|
||||||
|
all_mat *
|
||||||
|
vec4(f_pos, 1);
|
||||||
|
// gl_Position.z = -gl_Position.z;
|
||||||
|
// gl_Position.z = -gl_Position.z / gl_Position.w;
|
||||||
|
// gl_Position.z = -gl_Position.z / 100.0;
|
||||||
|
// gl_Position.z = -gl_Position.z / 100.0;
|
||||||
|
// gl_Position.z = -1000.0 / (gl_Position.z + 10000.0);
|
||||||
}
|
}
|
||||||
|
@ -23,13 +23,35 @@
|
|||||||
#include <random.glsl>
|
#include <random.glsl>
|
||||||
|
|
||||||
in vec3 f_pos;
|
in vec3 f_pos;
|
||||||
in vec3 f_chunk_pos;
|
// in float f_ao;
|
||||||
|
// in vec3 f_chunk_pos;
|
||||||
|
// #ifdef FLUID_MODE_SHINY
|
||||||
flat in uint f_pos_norm;
|
flat in uint f_pos_norm;
|
||||||
|
// #else
|
||||||
|
// const uint f_pos_norm = 0u;
|
||||||
|
// #endif
|
||||||
// in float f_alt;
|
// in float f_alt;
|
||||||
// in vec4 f_shadow;
|
// in vec4 f_shadow;
|
||||||
in vec3 f_col;
|
// in vec3 f_col;
|
||||||
in float f_light;
|
// in float f_light;
|
||||||
in float f_ao;
|
/*centroid */in vec2 f_uv_pos;
|
||||||
|
// in vec3 light_pos[2];
|
||||||
|
// const vec3 light_pos[6] = vec3[](vec3(0), vec3(0), vec3(00), vec3(0), vec3(0), vec3(0));
|
||||||
|
|
||||||
|
/* #if (SHADOW_MODE == SHADOW_MODE_MAP)
|
||||||
|
in vec4 sun_pos;
|
||||||
|
#elif (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_NONE)
|
||||||
|
const vec4 sun_pos = vec4(0.0);
|
||||||
|
#endif */
|
||||||
|
|
||||||
|
uniform sampler2D t_col_light;
|
||||||
|
|
||||||
|
layout (std140)
|
||||||
|
uniform u_locals {
|
||||||
|
vec3 model_offs;
|
||||||
|
float load_time;
|
||||||
|
ivec4 atlas_offs;
|
||||||
|
};
|
||||||
|
|
||||||
out vec4 tgt_color;
|
out vec4 tgt_color;
|
||||||
|
|
||||||
@ -38,6 +60,44 @@ out vec4 tgt_color;
|
|||||||
#include <lod.glsl>
|
#include <lod.glsl>
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
// discard;
|
||||||
|
// vec4 f_col_light = textureGrad(t_col_light, f_uv_pos / texSize, 0.25, 0.25);
|
||||||
|
// vec4 f_col_light = texture(t_col_light, (f_uv_pos) / texSize);
|
||||||
|
|
||||||
|
// First 3 normals are negative, next 3 are positive
|
||||||
|
const vec3 normals[8] = 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(0,0,0), vec3(0,0,0));
|
||||||
|
|
||||||
|
// uint norm_index = (f_pos_norm >> 29) & 0x7u;
|
||||||
|
// vec2 uv_delta = (norm_index & 0u) == 0u ? vec2(-1.0) : vec2(0);
|
||||||
|
|
||||||
|
vec2 f_uv_pos = f_uv_pos + atlas_offs.xy;
|
||||||
|
// vec4 f_col_light = textureProj(t_col_light, vec3(f_uv_pos + 0.5, textureSize(t_col_light, 0)));//(f_uv_pos/* + 0.5*/) / texSize);
|
||||||
|
// float f_light = textureProj(t_col_light, vec3(f_uv_pos + 0.5, textureSize(t_col_light, 0))).a;//1.0;//f_col_light.a * 4.0;// f_light = float(v_col_light & 0x3Fu) / 64.0;
|
||||||
|
vec4 f_col_light = texelFetch(t_col_light, ivec2(f_uv_pos)/* + uv_delta*//* - f_norm * 0.00001*/, 0);
|
||||||
|
// float f_light = f_col_light.a;
|
||||||
|
// vec4 f_col_light = texelFetch(t_col_light, ivec2(int(f_uv_pos.x), int(f_uv_pos.y)/* + uv_delta*//* - f_norm * 0.00001*/), 0);
|
||||||
|
vec3 f_col = /*linear_to_srgb*//*srgb_to_linear*/(f_col_light.rgb);
|
||||||
|
// vec3 f_col = vec3(1.0);
|
||||||
|
float f_light = texture(t_col_light, (f_uv_pos + 0.5) / textureSize(t_col_light, 0)).a;//1.0;//f_col_light.a * 4.0;// f_light = float(v_col_light & 0x3Fu) / 64.0;
|
||||||
|
// vec2 texSize = textureSize(t_col_light, 0);
|
||||||
|
// float f_light = texture(t_col_light, f_uv_pos/* + vec2(atlas_offs.xy)*/).a;//1.0;//f_col_light.a * 4.0;// f_light = float(v_col_light & 0x3Fu) / 64.0;
|
||||||
|
// float f_light = textureProj(t_col_light, vec3(f_uv_pos/* + vec2(atlas_offs.xy)*/, texSize.x)).a;//1.0;//f_col_light.a * 4.0;// f_light = float(v_col_light & 0x3Fu) / 64.0;
|
||||||
|
// float f_light = textureProjLod(t_col_light, vec3(f_uv_pos/* + vec2(atlas_offs.xy)*/, texSize.x), 0).a;//1.0;//f_col_light.a * 4.0;// f_light = float(v_col_light & 0x3Fu) / 64.0;
|
||||||
|
// float f_light = textureGrad(t_col_light, (f_uv_pos + 0.5) / texSize, vec2(0.1, 0.0), vec2(0.0, 0.1)).a;//1.0;//f_col_light.a * 4.0;// f_light = float(v_col_light & 0x3Fu) / 64.0;
|
||||||
|
// f_light = sqrt(f_light);
|
||||||
|
// f_light = sqrt(f_light);
|
||||||
|
// f_col = vec3((uvec3(v_col_light) >> uvec3(8, 16, 24)) & uvec3(0xFFu)) / 255.0;
|
||||||
|
// vec3 f_col = light_col.rgb;//vec4(1.0, 0.0, 0.0, 1.0);
|
||||||
|
|
||||||
|
// float f_ao = 1.0;
|
||||||
|
|
||||||
|
// vec3 my_chunk_pos = vec3(ivec3((uvec3(f_pos_norm) >> uvec3(0, 6, 12)) & uvec3(0x3Fu, 0x3Fu, 0xFFFFu)));
|
||||||
|
// tgt_color = vec4(hash(floor(vec4(my_chunk_pos.x, 0, 0, 0))), hash(floor(vec4(0, my_chunk_pos.y, 0, 1))), hash(floor(vec4(0, 0, my_chunk_pos.z, 2))), 1.0);
|
||||||
|
// tgt_color.rgb *= f_light;
|
||||||
|
// tgt_color = vec4(vec3(f_light), 1.0);
|
||||||
|
// tgt_color = vec4(f_col, 1.0);
|
||||||
|
// return;
|
||||||
|
// vec4 light_pos[2];
|
||||||
// vec4 light_col = vec4(
|
// vec4 light_col = vec4(
|
||||||
// hash(floor(vec4(f_pos.x, 0, 0, 0))),
|
// hash(floor(vec4(f_pos.x, 0, 0, 0))),
|
||||||
// hash(floor(vec4(0, f_pos.y, 0, 1))),
|
// hash(floor(vec4(0, f_pos.y, 0, 1))),
|
||||||
@ -46,7 +106,7 @@ void main() {
|
|||||||
// );
|
// );
|
||||||
// vec3 f_col = light_col.rgb;//vec4(1.0, 0.0, 0.0, 1.0);
|
// vec3 f_col = light_col.rgb;//vec4(1.0, 0.0, 0.0, 1.0);
|
||||||
// tgt_color = vec4(f_col, 1.0);
|
// tgt_color = vec4(f_col, 1.0);
|
||||||
// return;
|
// tgt_color = vec4(light_shadow_count.x <= 31u ? f_col : vec3(0.0), 1.0);
|
||||||
// tgt_color = vec4(0.0, 0.0, 0.0, 1.0);
|
// tgt_color = vec4(0.0, 0.0, 0.0, 1.0);
|
||||||
// float sum = 0.0;
|
// float sum = 0.0;
|
||||||
// for (uint i = 0u; i < /* 6 * */light_shadow_count.x; i ++) {
|
// for (uint i = 0u; i < /* 6 * */light_shadow_count.x; i ++) {
|
||||||
@ -91,6 +151,18 @@ void main() {
|
|||||||
// sum += light_strength;
|
// sum += light_strength;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
// // Increase array access by 3 to access positive values
|
||||||
|
// uint norm_dir = ((f_pos_norm >> 29) & 0x1u) * 3u;
|
||||||
|
// Use an array to avoid conditional branching
|
||||||
|
// uint norm_index = (f_pos_norm >> 29) & 0x7u;
|
||||||
|
// vec3 f_norm = normals[norm_index];
|
||||||
|
vec3 f_norm = normals[(f_pos_norm >> 29) & 0x7u];
|
||||||
|
// vec3 du = dFdx(f_pos);
|
||||||
|
// vec3 dv = dFdy(f_pos);
|
||||||
|
// vec3 f_norm = normalize(cross(du, dv));
|
||||||
|
|
||||||
// /* if (light_shadow_count.x == 1) {
|
// /* if (light_shadow_count.x == 1) {
|
||||||
// tgt_color.rgb = vec3(0.0);
|
// tgt_color.rgb = vec3(0.0);
|
||||||
// } */
|
// } */
|
||||||
@ -98,16 +170,6 @@ void main() {
|
|||||||
// tgt_color.rgb /= sum;
|
// tgt_color.rgb /= sum;
|
||||||
// }
|
// }
|
||||||
// return;
|
// return;
|
||||||
|
|
||||||
// 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));
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
// // Increase array access by 3 to access positive values
|
|
||||||
// uint norm_dir = ((f_pos_norm >> 29) & 0x1u) * 3u;
|
|
||||||
// Use an array to avoid conditional branching
|
|
||||||
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.
|
||||||
bool faces_fluid = bool((f_pos_norm >> 28) & 0x1u);
|
bool faces_fluid = bool((f_pos_norm >> 28) & 0x1u);
|
||||||
|
|
||||||
@ -117,11 +179,14 @@ void main() {
|
|||||||
vec3 view_dir = -cam_to_frag;
|
vec3 view_dir = -cam_to_frag;
|
||||||
// vec3 view_dir = normalize(f_pos - cam_pos.xyz);
|
// 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); */
|
||||||
|
|
||||||
|
#if (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_MAP || FLUID_MODE == FLUID_MODE_SHINY)
|
||||||
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));
|
#elif (SHADOW_MODE == SHADOW_MODE_NONE || FLUID_MODE == FLUID_MODE_CHEAP)
|
||||||
|
float f_alt = f_pos.z;
|
||||||
|
#endif
|
||||||
|
|
||||||
float alpha = 1.0;//0.0001;//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.
|
||||||
@ -145,15 +210,25 @@ void main() {
|
|||||||
float moon_shade_frac = horizon_at(f_pos, moon_dir); */
|
float moon_shade_frac = horizon_at(f_pos, moon_dir); */
|
||||||
// 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));
|
||||||
|
#if (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_MAP)
|
||||||
|
vec4 f_shadow = textureBicubic(t_horizon, pos_to_tex(f_pos.xy));
|
||||||
float sun_shade_frac = horizon_at2(f_shadow, f_alt, f_pos, sun_dir);
|
float sun_shade_frac = horizon_at2(f_shadow, f_alt, f_pos, sun_dir);
|
||||||
float moon_shade_frac = horizon_at2(f_shadow, f_alt, f_pos, moon_dir);
|
#elif (SHADOW_MODE == SHADOW_MODE_NONE)
|
||||||
|
float sun_shade_frac = 1.0;//horizon_at2(f_shadow, f_alt, f_pos, sun_dir);
|
||||||
|
#endif
|
||||||
|
float moon_shade_frac = 1.0;//horizon_at2(f_shadow, f_alt, f_pos, moon_dir);
|
||||||
// Globbal illumination "estimate" used to light the faces of voxels which are parallel to the sun or moon (which is a very common occurrence).
|
// Globbal illumination "estimate" used to light the faces of voxels which are parallel to the sun or moon (which is a very common occurrence).
|
||||||
// Will be attenuated by k_d, which is assumed to carry any additional ambient occlusion information (e.g. about shadowing).
|
// Will be attenuated by k_d, which is assumed to carry any additional ambient occlusion information (e.g. about shadowing).
|
||||||
// float ambient_sides = clamp(mix(0.5, 0.0, abs(dot(-f_norm, sun_dir)) * 10000.0), 0.0, 0.5);
|
// float ambient_sides = clamp(mix(0.5, 0.0, abs(dot(-f_norm, sun_dir)) * 10000.0), 0.0, 0.5);
|
||||||
// NOTE: current assumption is that moon and sun shouldn't be out at the sae time.
|
// NOTE: current assumption is that moon and sun shouldn't be out at the sae time.
|
||||||
// This assumption is (or can at least easily be) wrong, but if we pretend it's true we avoids having to explicitly pass in a separate shadow
|
// This assumption is (or can at least easily be) wrong, but if we pretend it's true we avoids having to explicitly pass in a separate shadow
|
||||||
// for the sun and moon (since they have different brightnesses / colors so the shadows shouldn't attenuate equally).
|
// for the sun and moon (since they have different brightnesses / colors so the shadows shouldn't attenuate equally).
|
||||||
float shade_frac = /*1.0;*/sun_shade_frac + moon_shade_frac;
|
// float shade_frac = /*1.0;*/sun_shade_frac + moon_shade_frac;
|
||||||
|
|
||||||
|
// DirectionalLight sun_info = get_sun_info(sun_dir, sun_shade_frac, light_pos);
|
||||||
|
float point_shadow = shadow_at(f_pos, f_norm);
|
||||||
|
DirectionalLight sun_info = get_sun_info(sun_dir, point_shadow * sun_shade_frac, /*sun_pos*/f_pos);
|
||||||
|
DirectionalLight moon_info = get_moon_info(moon_dir, point_shadow * moon_shade_frac/*, light_pos*/);
|
||||||
|
|
||||||
float max_light = 0.0;
|
float max_light = 0.0;
|
||||||
|
|
||||||
@ -171,21 +246,26 @@ void main() {
|
|||||||
// Computing light attenuation from water.
|
// Computing light attenuation from water.
|
||||||
vec3 emitted_light, reflected_light;
|
vec3 emitted_light, reflected_light;
|
||||||
// To account for prior saturation
|
// To account for prior saturation
|
||||||
float f_light = faces_fluid ? 1.0 : pow(f_light, 1.5);
|
/*float */f_light = faces_fluid ? 1.0 : pow(f_light, 1.5);
|
||||||
float point_shadow = shadow_at(f_pos, f_norm);
|
|
||||||
max_light += get_sun_diffuse2(f_norm, /*time_of_day.x, */sun_dir, moon_dir, view_dir, f_pos, mu, cam_attenuation, fluid_alt, k_a/* * (shade_frac * 0.5 + light_frac * 0.5)*/, k_d, k_s, alpha, 1.0, emitted_light, reflected_light);
|
|
||||||
|
|
||||||
emitted_light *= f_light * point_shadow * max(shade_frac, MIN_SHADOW);
|
emitted_light = vec3(1.0);
|
||||||
reflected_light *= f_light * point_shadow * shade_frac;
|
reflected_light = vec3(1.0);
|
||||||
max_light *= f_light * point_shadow * shade_frac;
|
max_light += get_sun_diffuse2(/*time_of_day.x, */sun_info, moon_info, f_norm, view_dir, f_pos, mu, cam_attenuation, fluid_alt, k_a/* * (shade_frac * 0.5 + light_frac * 0.5)*/, k_d, k_s, alpha, f_norm, 1.0, 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);
|
// emitted_light *= f_light * point_shadow * max(shade_frac, MIN_SHADOW);
|
||||||
|
// reflected_light *= f_light * point_shadow * shade_frac;
|
||||||
|
// max_light *= f_light * point_shadow * shade_frac;
|
||||||
|
emitted_light *= f_light;
|
||||||
|
reflected_light *= f_light;
|
||||||
|
max_light *= f_light;
|
||||||
|
|
||||||
|
max_light += lights_at(f_pos, f_norm, view_dir, mu, cam_attenuation, fluid_alt, k_a, k_d, k_s, alpha, f_norm, 1.0, emitted_light, reflected_light);
|
||||||
|
|
||||||
// float f_ao = 1.0;
|
// float f_ao = 1.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;
|
||||||
/* vec3 point_light = light_at(f_pos, f_norm);
|
/* vec3 point_light = light_at(f_pos, f_norm);
|
||||||
emitted_light += point_light;
|
emitted_light += point_light;
|
||||||
reflected_light += point_light; */
|
reflected_light += point_light; */
|
||||||
@ -208,14 +288,19 @@ void main() {
|
|||||||
// light_reflection_factorplight_reflection_factor
|
// light_reflection_factorplight_reflection_factor
|
||||||
|
|
||||||
// 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 f_chunk_pos = f_pos - (model_offs - focus_off.xyz);
|
||||||
|
vec3 col = /*srgb_to_linear*/(f_col + hash(vec4(floor(f_chunk_pos * 3.0 - f_norm * 0.5), 0)) * 0.01/* - 0.01*/); // Small-scale noise
|
||||||
|
// vec3 col = /*srgb_to_linear*/(f_col + hash(vec4(floor(f_pos * 3.0 - f_norm * 0.5), 0)) * 0.01); // Small-scale noise
|
||||||
vec3 surf_color = illuminate(max_light, view_dir, 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);
|
#if (CLOUD_MODE == CLOUD_MODE_REGULAR)
|
||||||
|
float fog_level = fog(f_pos.xyz, focus_pos.xyz, medium.x);
|
||||||
vec4 clouds;
|
vec4 clouds;
|
||||||
vec3 fog_color = get_sky_color(cam_to_frag/*view_dir*/, time_of_day.x, cam_pos.xyz, f_pos, 1.0, true, clouds);
|
vec3 fog_color = get_sky_color(cam_to_frag/*view_dir*/, time_of_day.x, cam_pos.xyz, f_pos, 1.0, false, clouds);
|
||||||
// vec3 color = surf_color;
|
|
||||||
vec3 color = mix(mix(surf_color, fog_color, fog_level), clouds.rgb, clouds.a);
|
vec3 color = mix(mix(surf_color, fog_color, fog_level), clouds.rgb, clouds.a);
|
||||||
|
#elif (CLOUD_MODE == CLOUD_MODE_NONE)
|
||||||
|
vec3 color = surf_color;
|
||||||
|
#endif
|
||||||
|
|
||||||
tgt_color = vec4(color, 1.0);
|
tgt_color = vec4(color, 1.0);
|
||||||
}
|
}
|
||||||
|
@ -16,52 +16,97 @@
|
|||||||
|
|
||||||
#define LIGHTING_DISTRIBUTION LIGHTING_DISTRIBUTION_BECKMANN
|
#define LIGHTING_DISTRIBUTION LIGHTING_DISTRIBUTION_BECKMANN
|
||||||
|
|
||||||
|
// #define HAS_SHADOW_MAPS
|
||||||
|
|
||||||
#include <globals.glsl>
|
#include <globals.glsl>
|
||||||
#include <srgb.glsl>
|
#include <srgb.glsl>
|
||||||
#include <lod.glsl>
|
#include <lod.glsl>
|
||||||
|
#include <shadows.glsl>
|
||||||
|
|
||||||
|
|
||||||
in uint v_pos_norm;
|
in uint v_pos_norm;
|
||||||
in uint v_col_light;
|
// in uint v_col_light;
|
||||||
|
in uint v_atlas_pos;
|
||||||
|
|
||||||
layout (std140)
|
layout (std140)
|
||||||
uniform u_locals {
|
uniform u_locals {
|
||||||
vec3 model_offs;
|
vec3 model_offs;
|
||||||
float load_time;
|
float load_time;
|
||||||
|
ivec4 atlas_offs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//struct ShadowLocals {
|
||||||
|
// mat4 shadowMatrices;
|
||||||
|
// mat4 texture_mat;
|
||||||
|
//};
|
||||||
|
//
|
||||||
|
//layout (std140)
|
||||||
|
//uniform u_light_shadows {
|
||||||
|
// ShadowLocals shadowMats[/*MAX_LAYER_FACES*/192];
|
||||||
|
//};
|
||||||
|
|
||||||
out vec3 f_pos;
|
out vec3 f_pos;
|
||||||
out vec3 f_chunk_pos;
|
// #ifdef FLUID_MODE_SHINY
|
||||||
flat out uint f_pos_norm;
|
flat out uint f_pos_norm;
|
||||||
|
|
||||||
|
// #if (SHADOW_MODE == SHADOW_MODE_MAP)
|
||||||
|
// out vec4 sun_pos;
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #endif
|
||||||
// out float f_alt;
|
// out float f_alt;
|
||||||
// out vec4 f_shadow;
|
// out vec4 f_shadow;
|
||||||
out vec3 f_col;
|
// out vec3 f_col;
|
||||||
out float f_light;
|
// out vec3 f_chunk_pos;
|
||||||
out float f_ao;
|
// out float f_ao;
|
||||||
|
/*centroid */out vec2 f_uv_pos;
|
||||||
|
// out vec3 light_pos[2];
|
||||||
|
// out float f_light;
|
||||||
|
|
||||||
|
// uniform sampler2DRect t_col_light;
|
||||||
|
|
||||||
const int EXTRA_NEG_Z = 32768;
|
const int EXTRA_NEG_Z = 32768;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
// over it (if this vertex to see if it intersects.
|
// over it (if this vertex to see if it intersects.
|
||||||
f_chunk_pos = vec3(ivec3((uvec3(v_pos_norm) >> uvec3(0, 6, 12)) & uvec3(0x3Fu, 0x3Fu, 0xFFFFu)) - ivec3(0, 0, EXTRA_NEG_Z));
|
// f_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;
|
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 - focus_off.xyz;
|
||||||
|
|
||||||
// f_pos.z -= 250.0 * (1.0 - min(1.0001 - 0.02 / pow(tick.x - load_time, 10.0), 1.0));
|
// f_pos.z -= 250.0 * (1.0 - min(1.0001 - 0.02 / pow(tick.x - load_time, 10.0), 1.0));
|
||||||
// f_pos.z -= min(32.0, 25.0 * pow(distance(focus_pos.xy, f_pos.xy) / view_distance.x, 20.0));
|
// f_pos.z -= min(32.0, 25.0 * pow(distance(focus_pos.xy, f_pos.xy) / view_distance.x, 20.0));
|
||||||
|
|
||||||
// vec3 light_col = vec3(
|
// vec3 light_col = vec3(
|
||||||
// hash(floor(vec4(f_pos.x, 0, 0, 0))),
|
// hash(floor(vec4(f_chunk_pos.x, 0, 0, 0))),
|
||||||
// hash(floor(vec4(0, f_pos.y, 0, 1))),
|
// hash(floor(vec4(0, f_chunk_pos.y, 0, 1))),
|
||||||
// hash(floor(vec4(0, 0, f_pos.z, 2)))
|
// hash(floor(vec4(0, 0, f_chunk_pos.z, 2)))
|
||||||
// );
|
// );
|
||||||
|
|
||||||
// f_col = light_col;// f_col = vec3((uvec3(v_col_light) >> uvec3(8, 16, 24)) & uvec3(0xFFu)) / 255.0;
|
// f_col = light_col;// f_col = vec3((uvec3(v_col_light) >> uvec3(8, 16, 24)) & uvec3(0xFFu)) / 255.0;
|
||||||
// f_light = 1.0;//float(v_col_light & 0x3Fu) / 64.0;
|
// f_light = 1.0;//float(v_col_light & 0x3Fu) / 64.0;
|
||||||
// f_ao = 1.0;//float((v_col_light >> 6u) & 3u) / 4.0;
|
// f_ao = 1.0;//float((v_col_light >> 6u) & 3u) / 4.0;
|
||||||
f_col = f_col = vec3((uvec3(v_col_light) >> uvec3(8, 16, 24)) & uvec3(0xFFu)) / 255.0;
|
// f_col = f_col = vec3((uvec3(v_col_light) >> uvec3(8, 16, 24)) & uvec3(0xFFu)) / 255.0;
|
||||||
f_light = float(v_col_light & 0x3Fu) / 64.0;
|
// f_light = float(v_col_light & 0x3Fu) / 64.0;
|
||||||
f_ao = float((v_col_light >> 6u) & 3u) / 4.0;
|
// f_ao = float((v_col_light >> 6u) & 3u) / 4.0;
|
||||||
|
|
||||||
|
// for (uint i = 0u; i < 1u/*light_shadow_count.z*/; ++i) {
|
||||||
|
// light_pos[i] = vec3(shadowMats[i].texture_mat * vec4(f_pos, 1.0));
|
||||||
|
// }
|
||||||
|
// vec2 texSize = textureSize(t_col_light, 0);
|
||||||
|
f_uv_pos = vec2((uvec2(v_atlas_pos) >> uvec2(0, 16)) & uvec2(0xFFFFu, 0xFFFFu));
|
||||||
|
|
||||||
|
// #if (SHADOW_MODE == SHADOW_MODE_MAP)
|
||||||
|
// // for (uint i = 0u; i < light_shadow_count.z; ++i) {
|
||||||
|
// // light_pos[i] = /*vec3(*/shadowMats[i].texture_mat * vec4(f_pos, 1.0)/*)*/;
|
||||||
|
// // }
|
||||||
|
// sun_pos = /*vec3(*/shadowMats[0].texture_mat * vec4(f_pos, 1.0)/*)*/;
|
||||||
|
// // #elif (SHADOW_MODE == SHADOW_MODE_CHEAP || SHADOW_MODE == SHADOW_MODE_NONE)
|
||||||
|
// // vec4 sun_pos = vec4(0.0);
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef FLUID_MODE_SHINY
|
||||||
f_pos_norm = v_pos_norm;
|
f_pos_norm = v_pos_norm;
|
||||||
|
// #endif
|
||||||
|
|
||||||
// Also precalculate shadow texture and estimated terrain altitude.
|
// Also precalculate shadow texture and estimated terrain altitude.
|
||||||
// f_alt = alt_at(f_pos.xy);
|
// f_alt = alt_at(f_pos.xy);
|
||||||
@ -104,11 +149,23 @@ void main() {
|
|||||||
// // wPoint -= wRayDir3 * wRayLength * n2 / n1;
|
// // wPoint -= wRayDir3 * wRayLength * n2 / n1;
|
||||||
// vec3 newRay = dot(wRayDir, wRayNormal) < 0.0 && wIntersectsSurface ? wPoint - wRayDir3 * wRayLength * n2 / n1 : f_pos;// - (wRayfinal - wPoint) * n2 / n1; // wPoint + n2 * (wRayfinal - wPoint) - n2 / n1 * wRayLength * wRayDir3;
|
// vec3 newRay = dot(wRayDir, wRayNormal) < 0.0 && wIntersectsSurface ? wPoint - wRayDir3 * wRayLength * n2 / n1 : f_pos;// - (wRayfinal - wPoint) * n2 / n1; // wPoint + n2 * (wRayfinal - wPoint) - n2 / n1 * wRayLength * wRayDir3;
|
||||||
|
|
||||||
|
#ifdef HAS_SHADOW_MAPS
|
||||||
gl_Position =
|
gl_Position =
|
||||||
all_mat *
|
/*all_mat*/shadowMats[0].shadowMatrices/*texture_mat*/ *
|
||||||
vec4(f_pos/*newRay*/, 1);
|
vec4(f_pos/*newRay*/, 1);
|
||||||
|
gl_Position.z = clamp(gl_Position.z, -abs(gl_Position.w), abs(gl_Position.w));
|
||||||
|
#else
|
||||||
|
gl_Position = all_mat * vec4(f_pos/*newRay*/, 1);
|
||||||
|
#endif
|
||||||
|
// gl_Position.y /= gl_Position.w;
|
||||||
|
// gl_Position.w = 1.0;
|
||||||
|
// gl_Position.z = -gl_Position.z;
|
||||||
// gl_Position.z = -gl_Position.z / gl_Position.w;
|
// gl_Position.z = -gl_Position.z / gl_Position.w;
|
||||||
|
// gl_Position.z = -gl_Position.z / gl_Position.w;
|
||||||
|
// gl_Position.z = -gl_Position.z *gl_Position.w;
|
||||||
|
// gl_Position.z = gl_Position.z / 100.0;
|
||||||
|
// gl_Position.z = gl_Position.z / 10000.0;
|
||||||
// gl_Position.z = -gl_Position.z / 100.0;
|
// gl_Position.z = -gl_Position.z / 100.0;
|
||||||
// gl_Position.z = -gl_Position.z / 100.0;
|
// gl_Position.z = -1000.0 / (gl_Position.z + 10000.0);
|
||||||
gl_Position.z = -1000.0 / (gl_Position.z + 10000.0);
|
// gl_Position.z = -1000.0 / (gl_Position.z + 10000.0);
|
||||||
}
|
}
|
||||||
|
@ -22,17 +22,21 @@ out vec4 f_color;
|
|||||||
void main() {
|
void main() {
|
||||||
f_color = v_color;
|
f_color = v_color;
|
||||||
|
|
||||||
|
// vec2 v_pos = vec2(-1.0,1.0) * v_pos;
|
||||||
|
/* f_uv = vec2(1.0,1.0) * v_uv; */
|
||||||
|
// vec2 v_uv = vec2(1.0,-1.0) * v_uv;
|
||||||
|
|
||||||
if (w_pos.w == 1.0) {
|
if (w_pos.w == 1.0) {
|
||||||
f_uv = v_uv;
|
f_uv = v_uv;
|
||||||
// Fixed scale In-game element
|
// Fixed scale In-game element
|
||||||
vec4 projected_pos = proj_mat * view_mat * vec4(w_pos.xyz, 1.0);
|
vec4 projected_pos = /*proj_mat * view_mat*/all_mat * vec4(w_pos.xyz - focus_off.xyz, 1.0);
|
||||||
gl_Position = vec4(projected_pos.xy / projected_pos.w + v_pos, 0.0, 1.0);
|
gl_Position = vec4(projected_pos.xy / projected_pos.w + v_pos/* * projected_pos.w*/, -1.0, /*projected_pos.w*/1.0);
|
||||||
} else if (v_mode == uint(3)) {
|
} else if (v_mode == uint(3)) {
|
||||||
// HACK: North facing source rectangle.
|
// HACK: North facing source rectangle.
|
||||||
vec2 look_at_dir = normalize(vec2(-view_mat[0][2], -view_mat[1][2]));
|
vec2 look_at_dir = normalize(vec2(-view_mat[0][2], -view_mat[1][2]));
|
||||||
mat2 look_at = mat2(look_at_dir.y, look_at_dir.x, -look_at_dir.x, look_at_dir.y);
|
mat2 look_at = mat2(look_at_dir.y, look_at_dir.x, -look_at_dir.x, look_at_dir.y);
|
||||||
f_uv = v_center + look_at * (v_uv - v_center);
|
f_uv = v_center + look_at * (v_uv - v_center);
|
||||||
gl_Position = vec4(v_pos, 0.0, 1.0);
|
gl_Position = vec4(v_pos, -1.0, 1.0);
|
||||||
} else if (v_mode == uint(5)) {
|
} else if (v_mode == uint(5)) {
|
||||||
// HACK: North facing target rectangle.
|
// HACK: North facing target rectangle.
|
||||||
f_uv = v_uv;
|
f_uv = v_uv;
|
||||||
@ -41,11 +45,11 @@ void main() {
|
|||||||
mat2 look_at = mat2(look_at_dir.y, -look_at_dir.x, look_at_dir.x, look_at_dir.y);
|
mat2 look_at = mat2(look_at_dir.y, -look_at_dir.x, look_at_dir.x, look_at_dir.y);
|
||||||
vec2 v_len = v_pos - v_center;
|
vec2 v_len = v_pos - v_center;
|
||||||
vec2 v_proj = look_at * vec2(v_len.x, v_len.y / aspect_ratio);
|
vec2 v_proj = look_at * vec2(v_len.x, v_len.y / aspect_ratio);
|
||||||
gl_Position = vec4(v_center + vec2(v_proj.x, v_proj.y * aspect_ratio), 0.0, 1.0);
|
gl_Position = vec4(v_center + vec2(v_proj.x, v_proj.y * aspect_ratio), -1.0, 1.0);
|
||||||
} else {
|
} else {
|
||||||
// Interface element
|
// Interface element
|
||||||
f_uv = v_uv;
|
f_uv = v_uv;
|
||||||
gl_Position = vec4(v_pos, 0.0, 1.0);
|
gl_Position = vec4(v_pos, -1.0, 1.0);
|
||||||
}
|
}
|
||||||
f_mode = v_mode;
|
f_mode = v_mode;
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,6 @@ num_cpus = "1.10.1"
|
|||||||
log = "0.4.8"
|
log = "0.4.8"
|
||||||
rayon = "^1.3.0"
|
rayon = "^1.3.0"
|
||||||
specs = "0.15.1"
|
specs = "0.15.1"
|
||||||
vek = { version = "0.10.0", features = ["serde"] }
|
vek = { version = "0.11.2", features = ["serde"] }
|
||||||
hashbrown = { version = "0.6.2", features = ["rayon", "serde", "nightly"] }
|
hashbrown = { version = "0.6.2", features = ["rayon", "serde", "nightly"] }
|
||||||
authc = { git = "https://gitlab.com/veloren/auth.git", rev = "65571ade0d954a0e0bd995fdb314854ff146ab97" }
|
authc = { git = "https://gitlab.com/veloren/auth.git", rev = "65571ade0d954a0e0bd995fdb314854ff146ab97" }
|
||||||
|
@ -11,7 +11,7 @@ no-assets = []
|
|||||||
specs-idvs = { git = "https://gitlab.com/veloren/specs-idvs.git" }
|
specs-idvs = { git = "https://gitlab.com/veloren/specs-idvs.git" }
|
||||||
|
|
||||||
specs = { version = "0.15.1", features = ["serde", "nightly", "storage-event-control"] }
|
specs = { version = "0.15.1", features = ["serde", "nightly", "storage-event-control"] }
|
||||||
vek = { version = "0.10.0", features = ["serde"] }
|
vek = { version = "0.11.2", features = ["serde"] }
|
||||||
dot_vox = "4.0.0"
|
dot_vox = "4.0.0"
|
||||||
fxhash = "0.2.1"
|
fxhash = "0.2.1"
|
||||||
image = "0.22.3"
|
image = "0.22.3"
|
||||||
|
@ -19,6 +19,79 @@ use specs::{Component, FlaggedStorage};
|
|||||||
use specs_idvs::IDVStorage;
|
use specs_idvs::IDVStorage;
|
||||||
use std::{fs::File, io::BufReader};
|
use std::{fs::File, io::BufReader};
|
||||||
|
|
||||||
|
/* pub trait PerBody {
|
||||||
|
type Humanoid;
|
||||||
|
type QuadrupedSmall;
|
||||||
|
type QuadrupedMedium;
|
||||||
|
type BirdMedium;
|
||||||
|
type FishMedium;
|
||||||
|
type Dragon;
|
||||||
|
type BirdSmall;
|
||||||
|
type FishSmall;
|
||||||
|
type BipedLarge;
|
||||||
|
type Object;
|
||||||
|
type Golem;
|
||||||
|
type Critter;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
|
#[repr(u32)]
|
||||||
|
pub enum Body<Meta = BodyType, BodyMeta = ()>
|
||||||
|
where Meta: PerBody,
|
||||||
|
{
|
||||||
|
Humanoid(Meta::Humanoid) = 0,
|
||||||
|
QuadrupedSmall(Meta::QuadrupedSmall) = 1,
|
||||||
|
QuadrupedMedium(Meta::QuadrupedMedium) = 2,
|
||||||
|
BirdMedium(Meta::BirdMedium) = 3,
|
||||||
|
FishMedium(Meta::FishMedium) = 4,
|
||||||
|
Dragon(Meta::Dragon) = 5,
|
||||||
|
BirdSmall(Meta::BirdSmall) = 6,
|
||||||
|
FishSmall(Meta::FishSmall) = 7,
|
||||||
|
BipedLarge(Meta::BipedLarge) = 8,
|
||||||
|
Object(Meta::Object) = 9,
|
||||||
|
Golem(Meta::Golem) = 10,
|
||||||
|
Critter(Meta::Critter) = 11,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Metadata intended to be stored per-body, together with data intended to be
|
||||||
|
/// stored for each species for each body.
|
||||||
|
///
|
||||||
|
/// NOTE: Deliberately don't (yet?) implement serialize.
|
||||||
|
#[derive(Clone, Debug, Deserialize)]
|
||||||
|
pub struct AllBodies<BodyMeta, PerBodyMeta: Meta> {
|
||||||
|
pub humanoid: BodyData<BodyMeta, humanoid::AllSpecies<SpeciesMeta>>,
|
||||||
|
pub quadruped_small: BodyData<BodyMeta, quadruped_small::AllSpecies<SpeciesMeta>>,
|
||||||
|
pub quadruped_medium: BodyData<BodyMeta, quadruped_medium::AllSpecies<SpeciesMeta>>,
|
||||||
|
pub bird_medium: BodyData<BodyMeta, bird_medium::AllSpecies<SpeciesMeta>>,
|
||||||
|
pub fish_medium: BodyData<BodyMeta, ()>,
|
||||||
|
pub dragon: BodyData<BodyMeta, dragon::AllSpecies<SpeciesMeta>>,
|
||||||
|
pub bird_small: BodyData<BodyMeta, ()>,
|
||||||
|
pub fish_small: BodyData<BodyMeta, ()>
|
||||||
|
pub biped_large: BodyData<BodyMeta, biped_large::AllSpecies<SpeciesMeta>>,
|
||||||
|
pub object: BodyData<BodyMeta, ()>,
|
||||||
|
pub golem: BodyData<BodyMeta, golem::AllSpecies<SpeciesMeta>>,
|
||||||
|
pub critter: BodyData<BodyMeta, critter::AllSpecies<SpeciesMeta>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
|
pub struct BodyType;
|
||||||
|
|
||||||
|
impl PerBody for BodyType {
|
||||||
|
type Humanoid = humanoid::Body;
|
||||||
|
type QuadrupedSmall = quadruped_small::Body;
|
||||||
|
type QuadrupedMedium = quadruped_medium::Body;
|
||||||
|
type BirdMedium = bird_medium::Body;
|
||||||
|
type FishMedium = fish_medium::Body;
|
||||||
|
type Dragon = dragon::Body;
|
||||||
|
type BirdSmall = bird_small::Body;
|
||||||
|
type FishSmall = fish_small::Body;
|
||||||
|
type BipedLarge = biped_large::Body;
|
||||||
|
type Object = object::Body;
|
||||||
|
type Golem = golem::Body;
|
||||||
|
type Critter = critter::Body;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||||
#[repr(u32)]
|
#[repr(u32)]
|
||||||
pub enum Body {
|
pub enum Body {
|
||||||
@ -57,10 +130,14 @@ pub struct AllBodies<BodyMeta, SpeciesMeta> {
|
|||||||
pub quadruped_small: BodyData<BodyMeta, quadruped_small::AllSpecies<SpeciesMeta>>,
|
pub quadruped_small: BodyData<BodyMeta, quadruped_small::AllSpecies<SpeciesMeta>>,
|
||||||
pub quadruped_medium: BodyData<BodyMeta, quadruped_medium::AllSpecies<SpeciesMeta>>,
|
pub quadruped_medium: BodyData<BodyMeta, quadruped_medium::AllSpecies<SpeciesMeta>>,
|
||||||
pub bird_medium: BodyData<BodyMeta, bird_medium::AllSpecies<SpeciesMeta>>,
|
pub bird_medium: BodyData<BodyMeta, bird_medium::AllSpecies<SpeciesMeta>>,
|
||||||
|
pub fish_medium: BodyData<BodyMeta, ()>,
|
||||||
|
pub dragon: BodyData<BodyMeta, dragon::AllSpecies<SpeciesMeta>>,
|
||||||
|
pub bird_small: BodyData<BodyMeta, ()>,
|
||||||
|
pub fish_small: BodyData<BodyMeta, ()>,
|
||||||
pub biped_large: BodyData<BodyMeta, biped_large::AllSpecies<SpeciesMeta>>,
|
pub biped_large: BodyData<BodyMeta, biped_large::AllSpecies<SpeciesMeta>>,
|
||||||
|
pub object: BodyData<BodyMeta, ()>,
|
||||||
pub golem: BodyData<BodyMeta, golem::AllSpecies<SpeciesMeta>>,
|
pub golem: BodyData<BodyMeta, golem::AllSpecies<SpeciesMeta>>,
|
||||||
pub critter: BodyData<BodyMeta, critter::AllSpecies<SpeciesMeta>>,
|
pub critter: BodyData<BodyMeta, critter::AllSpecies<SpeciesMeta>>,
|
||||||
pub dragon: BodyData<BodyMeta, dragon::AllSpecies<SpeciesMeta>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Can only retrieve body metadata by direct index.
|
/// Can only retrieve body metadata by direct index.
|
||||||
@ -82,6 +159,29 @@ impl<BodyMeta, SpeciesMeta> core::ops::Index<NpcKind> for AllBodies<BodyMeta, Sp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Can only retrieve body metadata by direct index.
|
||||||
|
impl<'a, BodyMeta, SpeciesMeta> core::ops::Index<&'a Body> for AllBodies<BodyMeta, SpeciesMeta> {
|
||||||
|
type Output = BodyMeta;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn index(&self, index: &Body) -> &Self::Output {
|
||||||
|
match index {
|
||||||
|
Body::Humanoid(_) => &self.humanoid.body,
|
||||||
|
Body::QuadrupedSmall(_) => &self.quadruped_small.body,
|
||||||
|
Body::QuadrupedMedium(_) => &self.quadruped_medium.body,
|
||||||
|
Body::BirdMedium(_) => &self.bird_medium.body,
|
||||||
|
Body::FishMedium(_) => &self.fish_medium.body,
|
||||||
|
Body::Dragon(_) => &self.dragon.body,
|
||||||
|
Body::BirdSmall(_) => &self.bird_small.body,
|
||||||
|
Body::FishSmall(_) => &self.fish_small.body,
|
||||||
|
Body::BipedLarge(_) => &self.biped_large.body,
|
||||||
|
Body::Object(_) => &self.object.body,
|
||||||
|
Body::Golem(_) => &self.golem.body,
|
||||||
|
Body::Critter(_) => &self.critter.body,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<
|
impl<
|
||||||
BodyMeta: Send + Sync + for<'de> serde::Deserialize<'de>,
|
BodyMeta: Send + Sync + for<'de> serde::Deserialize<'de>,
|
||||||
SpeciesMeta: Send + Sync + for<'de> serde::Deserialize<'de>,
|
SpeciesMeta: Send + Sync + for<'de> serde::Deserialize<'de>,
|
||||||
|
@ -25,7 +25,7 @@ pub trait BaseVol {
|
|||||||
type Vox: Vox;
|
type Vox: Vox;
|
||||||
type Error: Debug;
|
type Error: Debug;
|
||||||
|
|
||||||
fn scaled_by(&self, scale: Vec3<f32>) -> Scaled<Self>
|
fn scaled_by(self, scale: Vec3<f32>) -> Scaled<Self>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
|
@ -1,28 +1,36 @@
|
|||||||
use crate::vol::{BaseVol, ReadVol, SizedVol, Vox};
|
use crate::vol::{BaseVol, ReadVol, SizedVol, Vox};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
pub struct Scaled<'a, V> {
|
pub struct Scaled<V> {
|
||||||
pub inner: &'a V,
|
pub inner: V,
|
||||||
pub scale: Vec3<f32>,
|
pub scale: Vec3<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, V: BaseVol> BaseVol for Scaled<'a, V> {
|
impl<V: BaseVol> BaseVol for Scaled<V> {
|
||||||
type Error = V::Error;
|
type Error = V::Error;
|
||||||
type Vox = V::Vox;
|
type Vox = V::Vox;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, V: ReadVol> ReadVol for Scaled<'a, V> {
|
impl<V: ReadVol> ReadVol for Scaled<V> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn get(&self, pos: Vec3<i32>) -> Result<&Self::Vox, Self::Error> {
|
fn get(&self, pos: Vec3<i32>) -> Result<&Self::Vox, Self::Error> {
|
||||||
let ideal_pos = pos.map2(self.scale, |e, scale| e as f32 / scale);
|
// let ideal_pos = pos.map2(self.scale, |e, scale| (e as f32 + 0.5) / scale);
|
||||||
let pos = ideal_pos.map(|e| e.trunc() as i32);
|
// let pos = ideal_pos.map(|e| e.trunc() as i32);
|
||||||
|
let min_pos = pos.map2(self.scale, |e, scale| ((e as f32) / scale).floor() as i32);
|
||||||
|
let max_pos = pos.map2(self.scale, |e, scale| {
|
||||||
|
((e as f32 + 1.0) / scale).ceil() as i32
|
||||||
|
});
|
||||||
|
let pos = pos.map2(self.scale, |e, scale| {
|
||||||
|
(((e as f32 + 0.5) / scale) - 0.5).round() as i32
|
||||||
|
});
|
||||||
|
|
||||||
let ideal_search_size = Vec3::<f32>::one() / self.scale;
|
// let ideal_search_size = Vec3::<f32>::one() / self.scale;
|
||||||
let range_iter = |i: usize| {
|
let range_iter = |i: usize| {
|
||||||
std::iter::successors(Some(0), |p| Some(if *p < 0 { -*p } else { -(*p + 1) }))
|
std::iter::successors(Some(0), |p| Some(if *p < 0 { -*p } else { -(*p + 1) }))
|
||||||
.take_while(move |p| {
|
.take_while(move |p| {
|
||||||
((ideal_pos[i] - ideal_search_size[i] / 2.0).round() as i32
|
(min_pos[i]..max_pos[i])
|
||||||
..(ideal_pos[i] + ideal_search_size[i] / 2.0).round() as i32)
|
/* ((ideal_pos[i] - ideal_search_size[i] / 2.0).ceil() as i32
|
||||||
|
..(ideal_pos[i] + ideal_search_size[i] / 2.0).ceil() as i32) */
|
||||||
.contains(&(pos[i] + *p))
|
.contains(&(pos[i] + *p))
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
@ -36,7 +44,7 @@ impl<'a, V: ReadVol> ReadVol for Scaled<'a, V> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, V: SizedVol> SizedVol for Scaled<'a, V> {
|
impl<V: SizedVol> SizedVol for Scaled<V> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn lower_bound(&self) -> Vec3<i32> {
|
fn lower_bound(&self) -> Vec3<i32> {
|
||||||
self.inner
|
self.inner
|
||||||
@ -48,6 +56,6 @@ impl<'a, V: SizedVol> SizedVol for Scaled<'a, V> {
|
|||||||
fn upper_bound(&self) -> Vec3<i32> {
|
fn upper_bound(&self) -> Vec3<i32> {
|
||||||
self.inner
|
self.inner
|
||||||
.upper_bound()
|
.upper_bound()
|
||||||
.map2(self.scale, |e, scale| (e as f32 * scale).ceil() as i32 + 1)
|
.map2(self.scale, |e, scale| (e as f32 * scale).ceil() as i32)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ specs-idvs = { git = "https://gitlab.com/veloren/specs-idvs.git" }
|
|||||||
|
|
||||||
log = "0.4.8"
|
log = "0.4.8"
|
||||||
specs = { version = "0.15.1", features = ["shred-derive"] }
|
specs = { version = "0.15.1", features = ["shred-derive"] }
|
||||||
vek = "0.10.0"
|
vek = { version = "0.11.2", features = ["serde"] }
|
||||||
uvth = "3.1.1"
|
uvth = "3.1.1"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
scan_fmt = "0.2.4"
|
scan_fmt = "0.2.4"
|
||||||
|
@ -9,7 +9,7 @@ default-run = "veloren-voxygen"
|
|||||||
# autobins = false
|
# autobins = false
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
gl = ["gfx_device_gl"]
|
gl = ["gfx_device_gl", "gfx_gl"]
|
||||||
singleplayer = ["server"]
|
singleplayer = ["server"]
|
||||||
tweak = ["const-tweaker"]
|
tweak = ["const-tweaker"]
|
||||||
|
|
||||||
@ -22,6 +22,7 @@ client = { package = "veloren-client", path = "../client" }
|
|||||||
# Graphics
|
# Graphics
|
||||||
gfx = "0.18.2"
|
gfx = "0.18.2"
|
||||||
gfx_device_gl = { version = "0.16.2", optional = true }
|
gfx_device_gl = { version = "0.16.2", optional = true }
|
||||||
|
gfx_gl = { version = "0.6.1", optional = true }
|
||||||
gfx_window_glutin = "0.31.0"
|
gfx_window_glutin = "0.31.0"
|
||||||
glutin = "0.21.1"
|
glutin = "0.21.1"
|
||||||
winit = { version = "0.19.4", features = ["serde"] }
|
winit = { version = "0.19.4", features = ["serde"] }
|
||||||
@ -34,7 +35,7 @@ specs = "0.15.1"
|
|||||||
specs-idvs = { git = "https://gitlab.com/veloren/specs-idvs.git" }
|
specs-idvs = { git = "https://gitlab.com/veloren/specs-idvs.git" }
|
||||||
|
|
||||||
# Mathematics
|
# Mathematics
|
||||||
vek = { version = "0.10.0", features = ["serde"] }
|
vek = { version = "0.11.2", features = ["serde"] }
|
||||||
|
|
||||||
# Controller
|
# Controller
|
||||||
gilrs = { version = "0.7", features = ["serde"] }
|
gilrs = { version = "0.7", features = ["serde"] }
|
||||||
@ -51,7 +52,7 @@ image = "0.22.3"
|
|||||||
serde = "1.0.102"
|
serde = "1.0.102"
|
||||||
serde_derive = "1.0.102"
|
serde_derive = "1.0.102"
|
||||||
ron = "0.5.1"
|
ron = "0.5.1"
|
||||||
guillotiere = { git = "https://github.com/Imberflur/guillotiere" }
|
guillotiere = "0.5.2"
|
||||||
fern = { version = "0.5.8", features = ["colored"] }
|
fern = { version = "0.5.8", features = ["colored"] }
|
||||||
msgbox = { git = "https://github.com/bekker/msgbox-rs.git", rev = "68fe39a", optional = true }
|
msgbox = { git = "https://github.com/bekker/msgbox-rs.git", rev = "68fe39a", optional = true }
|
||||||
directories = "2.0.2"
|
directories = "2.0.2"
|
||||||
|
@ -131,7 +131,7 @@ pub fn criterion_benchmark(c: &mut Criterion) {
|
|||||||
c.bench(
|
c.bench(
|
||||||
"meshing",
|
"meshing",
|
||||||
Benchmark::new(&format!("Terrain mesh {}, {}", x, y), move |b| {
|
Benchmark::new(&format!("Terrain mesh {}, {}", x, y), move |b| {
|
||||||
b.iter(|| volume.generate_mesh(black_box(range)))
|
b.iter(|| volume.generate_mesh(black_box((range, Vec2::new(8192, 8192)))))
|
||||||
})
|
})
|
||||||
// Lower sample size to save time
|
// Lower sample size to save time
|
||||||
.sample_size(15),
|
.sample_size(15),
|
||||||
|
@ -14,17 +14,8 @@ fn main() {
|
|||||||
|
|
||||||
let (_context, device, factory, color_view, depth_view) = init_headless(context, dim);
|
let (_context, device, factory, color_view, depth_view) = init_headless(context, dim);
|
||||||
|
|
||||||
let mut renderer = render::Renderer::new(
|
let mut renderer =
|
||||||
device,
|
render::Renderer::new(device, factory, color_view, depth_view, Default::default()).unwrap();
|
||||||
factory,
|
|
||||||
color_view,
|
|
||||||
depth_view,
|
|
||||||
render::AaMode::SsaaX4,
|
|
||||||
render::CloudMode::Regular,
|
|
||||||
render::FluidMode::Shiny,
|
|
||||||
render::LightingMode::Ashikmin,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// Create character
|
// Create character
|
||||||
let body = comp::humanoid::Body::random();
|
let body = comp::humanoid::Body::random();
|
||||||
@ -62,7 +53,7 @@ fn main() {
|
|||||||
scene
|
scene
|
||||||
.camera_mut()
|
.camera_mut()
|
||||||
.update(0.0, 1.0 / 60.0, scene_data.mouse_smoothing);
|
.update(0.0, 1.0 / 60.0, scene_data.mouse_smoothing);
|
||||||
scene.maintain(&mut renderer, scene_data);
|
scene.maintain(&mut renderer, scene_data, None);
|
||||||
|
|
||||||
// Render
|
// Render
|
||||||
renderer.clear();
|
renderer.clear();
|
||||||
|
@ -8,7 +8,7 @@ pub use self::{idle::IdleAnimation, jump::JumpAnimation, run::RunAnimation};
|
|||||||
use super::{Bone, Skeleton};
|
use super::{Bone, Skeleton};
|
||||||
use crate::render::FigureBoneData;
|
use crate::render::FigureBoneData;
|
||||||
use common::comp::{self};
|
use common::comp::{self};
|
||||||
use vek::Vec3;
|
use vek::{Mat4, Vec3};
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub struct BipedLargeSkeleton {
|
pub struct BipedLargeSkeleton {
|
||||||
@ -35,7 +35,10 @@ impl Skeleton for BipedLargeSkeleton {
|
|||||||
|
|
||||||
fn bone_count(&self) -> usize { 11 }
|
fn bone_count(&self) -> usize { 11 }
|
||||||
|
|
||||||
fn compute_matrices(&self) -> ([FigureBoneData; 16], Vec3<f32>) {
|
fn compute_matrices<F: FnMut(Mat4<f32>) -> FigureBoneData>(
|
||||||
|
&self,
|
||||||
|
mut make_bone: F,
|
||||||
|
) -> ([FigureBoneData; 16], Vec3<f32>) {
|
||||||
let upper_torso_mat = self.upper_torso.compute_base_matrix();
|
let upper_torso_mat = self.upper_torso.compute_base_matrix();
|
||||||
let shoulder_l_mat = self.shoulder_l.compute_base_matrix();
|
let shoulder_l_mat = self.shoulder_l.compute_base_matrix();
|
||||||
let shoulder_r_mat = self.shoulder_r.compute_base_matrix();
|
let shoulder_r_mat = self.shoulder_r.compute_base_matrix();
|
||||||
@ -44,23 +47,17 @@ impl Skeleton for BipedLargeSkeleton {
|
|||||||
let torso_mat = self.torso.compute_base_matrix();
|
let torso_mat = self.torso.compute_base_matrix();
|
||||||
(
|
(
|
||||||
[
|
[
|
||||||
FigureBoneData::new(torso_mat * upper_torso_mat * self.head.compute_base_matrix()),
|
make_bone(torso_mat * upper_torso_mat * self.head.compute_base_matrix()),
|
||||||
FigureBoneData::new(torso_mat * upper_torso_mat),
|
make_bone(torso_mat * upper_torso_mat),
|
||||||
FigureBoneData::new(
|
make_bone(torso_mat * upper_torso_mat * self.lower_torso.compute_base_matrix()),
|
||||||
torso_mat * upper_torso_mat * self.lower_torso.compute_base_matrix(),
|
make_bone(torso_mat * upper_torso_mat * shoulder_l_mat),
|
||||||
),
|
make_bone(torso_mat * upper_torso_mat * shoulder_r_mat),
|
||||||
FigureBoneData::new(torso_mat * upper_torso_mat * shoulder_l_mat),
|
make_bone(torso_mat * upper_torso_mat * self.hand_l.compute_base_matrix()),
|
||||||
FigureBoneData::new(torso_mat * upper_torso_mat * shoulder_r_mat),
|
make_bone(torso_mat * upper_torso_mat * self.hand_r.compute_base_matrix()),
|
||||||
FigureBoneData::new(
|
make_bone(torso_mat * upper_torso_mat * leg_l_mat),
|
||||||
torso_mat * upper_torso_mat * self.hand_l.compute_base_matrix(),
|
make_bone(torso_mat * upper_torso_mat * leg_r_mat),
|
||||||
),
|
make_bone(self.foot_l.compute_base_matrix()),
|
||||||
FigureBoneData::new(
|
make_bone(self.foot_r.compute_base_matrix()),
|
||||||
torso_mat * upper_torso_mat * self.hand_r.compute_base_matrix(),
|
|
||||||
),
|
|
||||||
FigureBoneData::new(torso_mat * upper_torso_mat * leg_l_mat),
|
|
||||||
FigureBoneData::new(torso_mat * upper_torso_mat * leg_r_mat),
|
|
||||||
FigureBoneData::new(self.foot_l.compute_base_matrix()),
|
|
||||||
FigureBoneData::new(self.foot_r.compute_base_matrix()),
|
|
||||||
FigureBoneData::default(),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::default(),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::default(),
|
FigureBoneData::default(),
|
||||||
|
@ -8,7 +8,7 @@ pub use self::{fly::FlyAnimation, idle::IdleAnimation, run::RunAnimation};
|
|||||||
use super::{Bone, Skeleton};
|
use super::{Bone, Skeleton};
|
||||||
use crate::render::FigureBoneData;
|
use crate::render::FigureBoneData;
|
||||||
use common::comp::{self};
|
use common::comp::{self};
|
||||||
use vek::Vec3;
|
use vek::{Mat4, Vec3};
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub struct BirdMediumSkeleton {
|
pub struct BirdMediumSkeleton {
|
||||||
@ -30,18 +30,21 @@ impl Skeleton for BirdMediumSkeleton {
|
|||||||
|
|
||||||
fn bone_count(&self) -> usize { 7 }
|
fn bone_count(&self) -> usize { 7 }
|
||||||
|
|
||||||
fn compute_matrices(&self) -> ([FigureBoneData; 16], Vec3<f32>) {
|
fn compute_matrices<F: FnMut(Mat4<f32>) -> FigureBoneData>(
|
||||||
|
&self,
|
||||||
|
mut make_bone: F,
|
||||||
|
) -> ([FigureBoneData; 16], Vec3<f32>) {
|
||||||
let torso_mat = self.torso.compute_base_matrix();
|
let torso_mat = self.torso.compute_base_matrix();
|
||||||
|
|
||||||
(
|
(
|
||||||
[
|
[
|
||||||
FigureBoneData::new(torso_mat * self.head.compute_base_matrix()),
|
make_bone(torso_mat * self.head.compute_base_matrix()),
|
||||||
FigureBoneData::new(torso_mat),
|
make_bone(torso_mat),
|
||||||
FigureBoneData::new(torso_mat * self.tail.compute_base_matrix()),
|
make_bone(torso_mat * self.tail.compute_base_matrix()),
|
||||||
FigureBoneData::new(torso_mat * self.wing_l.compute_base_matrix()),
|
make_bone(torso_mat * self.wing_l.compute_base_matrix()),
|
||||||
FigureBoneData::new(torso_mat * self.wing_r.compute_base_matrix()),
|
make_bone(torso_mat * self.wing_r.compute_base_matrix()),
|
||||||
FigureBoneData::new(self.leg_l.compute_base_matrix()),
|
make_bone(self.leg_l.compute_base_matrix()),
|
||||||
FigureBoneData::new(self.leg_r.compute_base_matrix()),
|
make_bone(self.leg_r.compute_base_matrix()),
|
||||||
FigureBoneData::default(),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::default(),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::default(),
|
FigureBoneData::default(),
|
||||||
|
@ -8,7 +8,7 @@ pub use self::{idle::IdleAnimation, jump::JumpAnimation, run::RunAnimation};
|
|||||||
use super::{Bone, Skeleton};
|
use super::{Bone, Skeleton};
|
||||||
use crate::render::FigureBoneData;
|
use crate::render::FigureBoneData;
|
||||||
use common::comp::{self};
|
use common::comp::{self};
|
||||||
use vek::Vec3;
|
use vek::{Mat4, Vec3};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct BirdSmallSkeleton {
|
pub struct BirdSmallSkeleton {
|
||||||
@ -34,15 +34,18 @@ impl Skeleton for BirdSmallSkeleton {
|
|||||||
|
|
||||||
fn bone_count(&self) -> usize { 4 }
|
fn bone_count(&self) -> usize { 4 }
|
||||||
|
|
||||||
fn compute_matrices(&self) -> ([FigureBoneData; 16], Vec3<f32>) {
|
fn compute_matrices<F: FnMut(Mat4<f32>) -> FigureBoneData>(
|
||||||
|
&self,
|
||||||
|
mut make_bone: F,
|
||||||
|
) -> ([FigureBoneData; 16], Vec3<f32>) {
|
||||||
let torso_mat = self.torso.compute_base_matrix();
|
let torso_mat = self.torso.compute_base_matrix();
|
||||||
|
|
||||||
(
|
(
|
||||||
[
|
[
|
||||||
FigureBoneData::new(self.head.compute_base_matrix() * torso_mat),
|
make_bone(self.head.compute_base_matrix() * torso_mat),
|
||||||
FigureBoneData::new(torso_mat),
|
make_bone(torso_mat),
|
||||||
FigureBoneData::new(self.wing_l.compute_base_matrix() * torso_mat),
|
make_bone(self.wing_l.compute_base_matrix() * torso_mat),
|
||||||
FigureBoneData::new(self.wing_r.compute_base_matrix() * torso_mat),
|
make_bone(self.wing_r.compute_base_matrix() * torso_mat),
|
||||||
FigureBoneData::default(),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::default(),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::default(),
|
FigureBoneData::default(),
|
||||||
|
@ -31,7 +31,7 @@ pub use self::{
|
|||||||
use super::{Bone, Skeleton};
|
use super::{Bone, Skeleton};
|
||||||
use crate::render::FigureBoneData;
|
use crate::render::FigureBoneData;
|
||||||
use common::comp;
|
use common::comp;
|
||||||
use vek::{Vec3, Vec4};
|
use vek::{Mat4, Vec3, Vec4};
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub struct CharacterSkeleton {
|
pub struct CharacterSkeleton {
|
||||||
@ -65,7 +65,10 @@ impl Skeleton for CharacterSkeleton {
|
|||||||
|
|
||||||
fn bone_count(&self) -> usize { 15 }
|
fn bone_count(&self) -> usize { 15 }
|
||||||
|
|
||||||
fn compute_matrices(&self) -> ([FigureBoneData; 16], Vec3<f32>) {
|
fn compute_matrices<F: FnMut(Mat4<f32>) -> FigureBoneData>(
|
||||||
|
&self,
|
||||||
|
mut make_bone: F,
|
||||||
|
) -> ([FigureBoneData; 16], Vec3<f32>) {
|
||||||
let chest_mat = self.chest.compute_base_matrix();
|
let chest_mat = self.chest.compute_base_matrix();
|
||||||
let torso_mat = self.torso.compute_base_matrix();
|
let torso_mat = self.torso.compute_base_matrix();
|
||||||
let l_hand_mat = self.l_hand.compute_base_matrix();
|
let l_hand_mat = self.l_hand.compute_base_matrix();
|
||||||
@ -83,27 +86,21 @@ impl Skeleton for CharacterSkeleton {
|
|||||||
|
|
||||||
(
|
(
|
||||||
[
|
[
|
||||||
FigureBoneData::new(torso_mat * chest_mat * head_mat),
|
make_bone(torso_mat * chest_mat * head_mat),
|
||||||
FigureBoneData::new(torso_mat * chest_mat),
|
make_bone(torso_mat * chest_mat),
|
||||||
FigureBoneData::new(torso_mat * chest_mat * self.belt.compute_base_matrix()),
|
make_bone(torso_mat * chest_mat * self.belt.compute_base_matrix()),
|
||||||
FigureBoneData::new(torso_mat * chest_mat * self.back.compute_base_matrix()),
|
make_bone(torso_mat * chest_mat * self.back.compute_base_matrix()),
|
||||||
FigureBoneData::new(torso_mat * chest_mat * shorts_mat),
|
make_bone(torso_mat * chest_mat * shorts_mat),
|
||||||
FigureBoneData::new(
|
make_bone(torso_mat * chest_mat * control_mat * l_control_mat * l_hand_mat),
|
||||||
torso_mat * chest_mat * control_mat * l_control_mat * l_hand_mat,
|
make_bone(torso_mat * chest_mat * control_mat * r_control_mat * r_hand_mat),
|
||||||
),
|
make_bone(torso_mat * self.l_foot.compute_base_matrix()),
|
||||||
FigureBoneData::new(
|
make_bone(torso_mat * self.r_foot.compute_base_matrix()),
|
||||||
torso_mat * chest_mat * control_mat * r_control_mat * r_hand_mat,
|
make_bone(torso_mat * chest_mat * self.l_shoulder.compute_base_matrix()),
|
||||||
),
|
make_bone(torso_mat * chest_mat * self.r_shoulder.compute_base_matrix()),
|
||||||
FigureBoneData::new(torso_mat * self.l_foot.compute_base_matrix()),
|
make_bone(torso_mat * self.glider.compute_base_matrix()),
|
||||||
FigureBoneData::new(torso_mat * self.r_foot.compute_base_matrix()),
|
make_bone(torso_mat * chest_mat * control_mat * l_control_mat * main_mat),
|
||||||
FigureBoneData::new(torso_mat * chest_mat * self.l_shoulder.compute_base_matrix()),
|
make_bone(torso_mat * chest_mat * control_mat * r_control_mat * second_mat),
|
||||||
FigureBoneData::new(torso_mat * chest_mat * self.r_shoulder.compute_base_matrix()),
|
make_bone(lantern_final_mat),
|
||||||
FigureBoneData::new(torso_mat * self.glider.compute_base_matrix()),
|
|
||||||
FigureBoneData::new(torso_mat * chest_mat * control_mat * l_control_mat * main_mat),
|
|
||||||
FigureBoneData::new(
|
|
||||||
torso_mat * chest_mat * control_mat * r_control_mat * second_mat,
|
|
||||||
),
|
|
||||||
FigureBoneData::new(lantern_final_mat),
|
|
||||||
FigureBoneData::default(),
|
FigureBoneData::default(),
|
||||||
],
|
],
|
||||||
(lantern_final_mat * Vec4::new(0.0, 0.0, 0.0, 1.0)).xyz(),
|
(lantern_final_mat * Vec4::new(0.0, 0.0, 0.0, 1.0)).xyz(),
|
||||||
|
@ -8,7 +8,7 @@ pub use self::{idle::IdleAnimation, jump::JumpAnimation, run::RunAnimation};
|
|||||||
use super::{Bone, Skeleton};
|
use super::{Bone, Skeleton};
|
||||||
use crate::render::FigureBoneData;
|
use crate::render::FigureBoneData;
|
||||||
use common::comp::{self};
|
use common::comp::{self};
|
||||||
use vek::Vec3;
|
use vek::{Mat4, Vec3};
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub struct CritterSkeleton {
|
pub struct CritterSkeleton {
|
||||||
@ -35,14 +35,17 @@ impl Skeleton for CritterSkeleton {
|
|||||||
|
|
||||||
fn bone_count(&self) -> usize { 5 }
|
fn bone_count(&self) -> usize { 5 }
|
||||||
|
|
||||||
fn compute_matrices(&self) -> ([FigureBoneData; 16], Vec3<f32>) {
|
fn compute_matrices<F: FnMut(Mat4<f32>) -> FigureBoneData>(
|
||||||
|
&self,
|
||||||
|
mut make_bone: F,
|
||||||
|
) -> ([FigureBoneData; 16], Vec3<f32>) {
|
||||||
(
|
(
|
||||||
[
|
[
|
||||||
FigureBoneData::new(self.head.compute_base_matrix()),
|
make_bone(self.head.compute_base_matrix()),
|
||||||
FigureBoneData::new(self.chest.compute_base_matrix()),
|
make_bone(self.chest.compute_base_matrix()),
|
||||||
FigureBoneData::new(self.feet_f.compute_base_matrix()),
|
make_bone(self.feet_f.compute_base_matrix()),
|
||||||
FigureBoneData::new(self.feet_b.compute_base_matrix()),
|
make_bone(self.feet_b.compute_base_matrix()),
|
||||||
FigureBoneData::new(self.tail.compute_base_matrix()),
|
make_bone(self.tail.compute_base_matrix()),
|
||||||
FigureBoneData::default(),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::default(),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::default(),
|
FigureBoneData::default(),
|
||||||
|
@ -8,7 +8,7 @@ pub use self::{fly::FlyAnimation, idle::IdleAnimation, run::RunAnimation};
|
|||||||
use super::{Bone, Skeleton};
|
use super::{Bone, Skeleton};
|
||||||
use crate::render::FigureBoneData;
|
use crate::render::FigureBoneData;
|
||||||
use common::comp::{self};
|
use common::comp::{self};
|
||||||
use vek::Vec3;
|
use vek::{Mat4, Vec3};
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub struct DragonSkeleton {
|
pub struct DragonSkeleton {
|
||||||
@ -38,7 +38,10 @@ impl Skeleton for DragonSkeleton {
|
|||||||
|
|
||||||
fn bone_count(&self) -> usize { 15 }
|
fn bone_count(&self) -> usize { 15 }
|
||||||
|
|
||||||
fn compute_matrices(&self) -> ([FigureBoneData; 16], Vec3<f32>) {
|
fn compute_matrices<F: FnMut(Mat4<f32>) -> FigureBoneData>(
|
||||||
|
&self,
|
||||||
|
mut make_bone: F,
|
||||||
|
) -> ([FigureBoneData; 16], Vec3<f32>) {
|
||||||
let head_upper_mat = self.head_upper.compute_base_matrix();
|
let head_upper_mat = self.head_upper.compute_base_matrix();
|
||||||
let head_lower_mat = self.head_lower.compute_base_matrix();
|
let head_lower_mat = self.head_lower.compute_base_matrix();
|
||||||
let chest_front_mat = self.chest_front.compute_base_matrix();
|
let chest_front_mat = self.chest_front.compute_base_matrix();
|
||||||
@ -48,35 +51,31 @@ impl Skeleton for DragonSkeleton {
|
|||||||
let tail_front_mat = self.tail_front.compute_base_matrix();
|
let tail_front_mat = self.tail_front.compute_base_matrix();
|
||||||
(
|
(
|
||||||
[
|
[
|
||||||
FigureBoneData::new(chest_front_mat * head_lower_mat * head_upper_mat),
|
make_bone(chest_front_mat * head_lower_mat * head_upper_mat),
|
||||||
FigureBoneData::new(chest_front_mat * head_lower_mat),
|
make_bone(chest_front_mat * head_lower_mat),
|
||||||
FigureBoneData::new(
|
make_bone(
|
||||||
chest_front_mat
|
chest_front_mat
|
||||||
* head_lower_mat
|
* head_lower_mat
|
||||||
* head_upper_mat
|
* head_upper_mat
|
||||||
* self.jaw.compute_base_matrix(),
|
* self.jaw.compute_base_matrix(),
|
||||||
),
|
),
|
||||||
FigureBoneData::new(chest_front_mat),
|
make_bone(chest_front_mat),
|
||||||
FigureBoneData::new(chest_front_mat * self.chest_rear.compute_base_matrix()),
|
make_bone(chest_front_mat * self.chest_rear.compute_base_matrix()),
|
||||||
FigureBoneData::new(chest_front_mat * chest_rear_mat * tail_front_mat),
|
make_bone(chest_front_mat * chest_rear_mat * tail_front_mat),
|
||||||
FigureBoneData::new(
|
make_bone(
|
||||||
chest_front_mat
|
chest_front_mat
|
||||||
* chest_rear_mat
|
* chest_rear_mat
|
||||||
* tail_front_mat
|
* tail_front_mat
|
||||||
* self.tail_rear.compute_base_matrix(),
|
* self.tail_rear.compute_base_matrix(),
|
||||||
),
|
),
|
||||||
FigureBoneData::new(chest_front_mat * self.wing_in_l.compute_base_matrix()),
|
make_bone(chest_front_mat * self.wing_in_l.compute_base_matrix()),
|
||||||
FigureBoneData::new(chest_front_mat * self.wing_in_r.compute_base_matrix()),
|
make_bone(chest_front_mat * self.wing_in_r.compute_base_matrix()),
|
||||||
FigureBoneData::new(
|
make_bone(chest_front_mat * wing_in_l_mat * self.wing_out_l.compute_base_matrix()),
|
||||||
chest_front_mat * wing_in_l_mat * self.wing_out_l.compute_base_matrix(),
|
make_bone(chest_front_mat * wing_in_r_mat * self.wing_out_r.compute_base_matrix()),
|
||||||
),
|
make_bone(self.foot_fl.compute_base_matrix()),
|
||||||
FigureBoneData::new(
|
make_bone(self.foot_fr.compute_base_matrix()),
|
||||||
chest_front_mat * wing_in_r_mat * self.wing_out_r.compute_base_matrix(),
|
make_bone(self.foot_bl.compute_base_matrix()),
|
||||||
),
|
make_bone(self.foot_br.compute_base_matrix()),
|
||||||
FigureBoneData::new(self.foot_fl.compute_base_matrix()),
|
|
||||||
FigureBoneData::new(self.foot_fr.compute_base_matrix()),
|
|
||||||
FigureBoneData::new(self.foot_bl.compute_base_matrix()),
|
|
||||||
FigureBoneData::new(self.foot_br.compute_base_matrix()),
|
|
||||||
FigureBoneData::default(),
|
FigureBoneData::default(),
|
||||||
],
|
],
|
||||||
Vec3::default(),
|
Vec3::default(),
|
||||||
|
@ -8,7 +8,7 @@ pub use self::{idle::IdleAnimation, jump::JumpAnimation, run::RunAnimation};
|
|||||||
use super::{Bone, Skeleton};
|
use super::{Bone, Skeleton};
|
||||||
use crate::render::FigureBoneData;
|
use crate::render::FigureBoneData;
|
||||||
use common::comp::{self};
|
use common::comp::{self};
|
||||||
use vek::Vec3;
|
use vek::{Mat4, Vec3};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct FishMediumSkeleton {
|
pub struct FishMediumSkeleton {
|
||||||
@ -38,18 +38,21 @@ impl Skeleton for FishMediumSkeleton {
|
|||||||
|
|
||||||
fn bone_count(&self) -> usize { 6 }
|
fn bone_count(&self) -> usize { 6 }
|
||||||
|
|
||||||
fn compute_matrices(&self) -> ([FigureBoneData; 16], Vec3<f32>) {
|
fn compute_matrices<F: FnMut(Mat4<f32>) -> FigureBoneData>(
|
||||||
|
&self,
|
||||||
|
mut make_bone: F,
|
||||||
|
) -> ([FigureBoneData; 16], Vec3<f32>) {
|
||||||
let torso_mat = self.torso.compute_base_matrix();
|
let torso_mat = self.torso.compute_base_matrix();
|
||||||
let rear_mat = self.rear.compute_base_matrix();
|
let rear_mat = self.rear.compute_base_matrix();
|
||||||
|
|
||||||
(
|
(
|
||||||
[
|
[
|
||||||
FigureBoneData::new(self.head.compute_base_matrix() * torso_mat),
|
make_bone(self.head.compute_base_matrix() * torso_mat),
|
||||||
FigureBoneData::new(torso_mat),
|
make_bone(torso_mat),
|
||||||
FigureBoneData::new(rear_mat * torso_mat),
|
make_bone(rear_mat * torso_mat),
|
||||||
FigureBoneData::new(self.tail.compute_base_matrix() * rear_mat),
|
make_bone(self.tail.compute_base_matrix() * rear_mat),
|
||||||
FigureBoneData::new(self.fin_l.compute_base_matrix() * rear_mat),
|
make_bone(self.fin_l.compute_base_matrix() * rear_mat),
|
||||||
FigureBoneData::new(self.fin_r.compute_base_matrix() * rear_mat),
|
make_bone(self.fin_r.compute_base_matrix() * rear_mat),
|
||||||
FigureBoneData::default(),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::default(),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::default(),
|
FigureBoneData::default(),
|
||||||
|
@ -8,7 +8,7 @@ pub use self::{idle::IdleAnimation, jump::JumpAnimation, run::RunAnimation};
|
|||||||
use super::{Bone, Skeleton};
|
use super::{Bone, Skeleton};
|
||||||
use crate::render::FigureBoneData;
|
use crate::render::FigureBoneData;
|
||||||
use common::comp::{self};
|
use common::comp::{self};
|
||||||
use vek::Vec3;
|
use vek::{Mat4, Vec3};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct FishSmallSkeleton {
|
pub struct FishSmallSkeleton {
|
||||||
@ -30,13 +30,16 @@ impl Skeleton for FishSmallSkeleton {
|
|||||||
|
|
||||||
fn bone_count(&self) -> usize { 2 }
|
fn bone_count(&self) -> usize { 2 }
|
||||||
|
|
||||||
fn compute_matrices(&self) -> ([FigureBoneData; 16], Vec3<f32>) {
|
fn compute_matrices<F: FnMut(Mat4<f32>) -> FigureBoneData>(
|
||||||
|
&self,
|
||||||
|
mut make_bone: F,
|
||||||
|
) -> ([FigureBoneData; 16], Vec3<f32>) {
|
||||||
let torso_mat = self.torso.compute_base_matrix();
|
let torso_mat = self.torso.compute_base_matrix();
|
||||||
|
|
||||||
(
|
(
|
||||||
[
|
[
|
||||||
FigureBoneData::new(torso_mat),
|
make_bone(torso_mat),
|
||||||
FigureBoneData::new(self.tail.compute_base_matrix() * torso_mat),
|
make_bone(self.tail.compute_base_matrix() * torso_mat),
|
||||||
FigureBoneData::default(),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::default(),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::default(),
|
FigureBoneData::default(),
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use super::Skeleton;
|
use super::Skeleton;
|
||||||
use crate::render::FigureBoneData;
|
use crate::render::FigureBoneData;
|
||||||
use vek::Vec3;
|
use vek::{Mat4, Vec3};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct FixtureSkeleton;
|
pub struct FixtureSkeleton;
|
||||||
@ -16,25 +16,28 @@ impl Skeleton for FixtureSkeleton {
|
|||||||
|
|
||||||
fn bone_count(&self) -> usize { 1 }
|
fn bone_count(&self) -> usize { 1 }
|
||||||
|
|
||||||
fn compute_matrices(&self) -> ([FigureBoneData; 16], Vec3<f32>) {
|
fn compute_matrices<F: FnMut(Mat4<f32>) -> FigureBoneData>(
|
||||||
|
&self,
|
||||||
|
_make_bone: F,
|
||||||
|
) -> ([FigureBoneData; 16], Vec3<f32>) {
|
||||||
(
|
(
|
||||||
[
|
[
|
||||||
FigureBoneData::new(vek::Mat4::identity()), // <-- This is actually a bone!
|
FigureBoneData::default(), // <-- This is actually a bone!
|
||||||
FigureBoneData::new(vek::Mat4::identity()),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::new(vek::Mat4::identity()),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::new(vek::Mat4::identity()),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::new(vek::Mat4::identity()),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::new(vek::Mat4::identity()),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::new(vek::Mat4::identity()),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::new(vek::Mat4::identity()),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::new(vek::Mat4::identity()),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::new(vek::Mat4::identity()),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::new(vek::Mat4::identity()),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::new(vek::Mat4::identity()),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::new(vek::Mat4::identity()),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::new(vek::Mat4::identity()),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::new(vek::Mat4::identity()),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::new(vek::Mat4::identity()),
|
FigureBoneData::default(),
|
||||||
],
|
],
|
||||||
Vec3::default(),
|
Vec3::default(),
|
||||||
)
|
)
|
||||||
|
@ -8,7 +8,7 @@ pub use self::{idle::IdleAnimation, jump::JumpAnimation, run::RunAnimation};
|
|||||||
use super::{Bone, Skeleton};
|
use super::{Bone, Skeleton};
|
||||||
use crate::render::FigureBoneData;
|
use crate::render::FigureBoneData;
|
||||||
use common::comp::{self};
|
use common::comp::{self};
|
||||||
use vek::Vec3;
|
use vek::{Mat4, Vec3};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct GolemSkeleton {
|
pub struct GolemSkeleton {
|
||||||
@ -46,7 +46,10 @@ impl GolemSkeleton {
|
|||||||
impl Skeleton for GolemSkeleton {
|
impl Skeleton for GolemSkeleton {
|
||||||
type Attr = SkeletonAttr;
|
type Attr = SkeletonAttr;
|
||||||
|
|
||||||
fn compute_matrices(&self) -> ([FigureBoneData; 16], Vec3<f32>) {
|
fn compute_matrices<F: FnMut(Mat4<f32>) -> FigureBoneData>(
|
||||||
|
&self,
|
||||||
|
mut make_bone: F,
|
||||||
|
) -> ([FigureBoneData; 16], Vec3<f32>) {
|
||||||
let upper_torso_mat = self.upper_torso.compute_base_matrix();
|
let upper_torso_mat = self.upper_torso.compute_base_matrix();
|
||||||
let shoulder_l_mat = self.shoulder_l.compute_base_matrix();
|
let shoulder_l_mat = self.shoulder_l.compute_base_matrix();
|
||||||
let shoulder_r_mat = self.shoulder_r.compute_base_matrix();
|
let shoulder_r_mat = self.shoulder_r.compute_base_matrix();
|
||||||
@ -57,20 +60,16 @@ impl Skeleton for GolemSkeleton {
|
|||||||
let foot_r_mat = self.foot_r.compute_base_matrix();
|
let foot_r_mat = self.foot_r.compute_base_matrix();
|
||||||
(
|
(
|
||||||
[
|
[
|
||||||
FigureBoneData::new(torso_mat * upper_torso_mat * self.head.compute_base_matrix()),
|
make_bone(torso_mat * upper_torso_mat * self.head.compute_base_matrix()),
|
||||||
FigureBoneData::new(torso_mat * upper_torso_mat),
|
make_bone(torso_mat * upper_torso_mat),
|
||||||
FigureBoneData::new(torso_mat * upper_torso_mat * shoulder_l_mat),
|
make_bone(torso_mat * upper_torso_mat * shoulder_l_mat),
|
||||||
FigureBoneData::new(torso_mat * upper_torso_mat * shoulder_r_mat),
|
make_bone(torso_mat * upper_torso_mat * shoulder_r_mat),
|
||||||
FigureBoneData::new(
|
make_bone(torso_mat * upper_torso_mat * self.hand_l.compute_base_matrix()),
|
||||||
torso_mat * upper_torso_mat * self.hand_l.compute_base_matrix(),
|
make_bone(torso_mat * upper_torso_mat * self.hand_r.compute_base_matrix()),
|
||||||
),
|
make_bone(foot_l_mat * leg_l_mat),
|
||||||
FigureBoneData::new(
|
make_bone(foot_r_mat * leg_r_mat),
|
||||||
torso_mat * upper_torso_mat * self.hand_r.compute_base_matrix(),
|
make_bone(foot_l_mat),
|
||||||
),
|
make_bone(foot_r_mat),
|
||||||
FigureBoneData::new(foot_l_mat * leg_l_mat),
|
|
||||||
FigureBoneData::new(foot_r_mat * leg_r_mat),
|
|
||||||
FigureBoneData::new(foot_l_mat),
|
|
||||||
FigureBoneData::new(foot_r_mat),
|
|
||||||
FigureBoneData::default(),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::default(),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::default(),
|
FigureBoneData::default(),
|
||||||
|
@ -54,7 +54,10 @@ pub trait Skeleton: Send + Sync + 'static {
|
|||||||
|
|
||||||
fn bone_count(&self) -> usize { 16 }
|
fn bone_count(&self) -> usize { 16 }
|
||||||
|
|
||||||
fn compute_matrices(&self) -> ([FigureBoneData; 16], Vec3<f32>);
|
fn compute_matrices<F: FnMut(Mat4<f32>) -> FigureBoneData>(
|
||||||
|
&self,
|
||||||
|
make_bone: F,
|
||||||
|
) -> ([FigureBoneData; 16], Vec3<f32>);
|
||||||
|
|
||||||
/// Change the current skeleton to be more like `target`.
|
/// Change the current skeleton to be more like `target`.
|
||||||
fn interpolate(&mut self, target: &Self, dt: f32);
|
fn interpolate(&mut self, target: &Self, dt: f32);
|
||||||
|
@ -17,25 +17,28 @@ impl Skeleton for ObjectSkeleton {
|
|||||||
|
|
||||||
fn bone_count(&self) -> usize { 1 }
|
fn bone_count(&self) -> usize { 1 }
|
||||||
|
|
||||||
fn compute_matrices(&self) -> ([FigureBoneData; 16], Vec3<f32>) {
|
fn compute_matrices<F: FnMut(Mat4<f32>) -> FigureBoneData>(
|
||||||
|
&self,
|
||||||
|
mut make_bone: F,
|
||||||
|
) -> ([FigureBoneData; 16], Vec3<f32>) {
|
||||||
(
|
(
|
||||||
[
|
[
|
||||||
FigureBoneData::new(Mat4::scaling_3d(Vec3::broadcast(SCALE))),
|
make_bone(Mat4::scaling_3d(Vec3::broadcast(SCALE))),
|
||||||
FigureBoneData::new(vek::Mat4::identity()),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::new(vek::Mat4::identity()),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::new(vek::Mat4::identity()),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::new(vek::Mat4::identity()),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::new(vek::Mat4::identity()),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::new(vek::Mat4::identity()),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::new(vek::Mat4::identity()),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::new(vek::Mat4::identity()),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::new(vek::Mat4::identity()),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::new(vek::Mat4::identity()),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::new(vek::Mat4::identity()),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::new(vek::Mat4::identity()),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::new(vek::Mat4::identity()),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::new(vek::Mat4::identity()),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::new(vek::Mat4::identity()),
|
FigureBoneData::default(),
|
||||||
],
|
],
|
||||||
Vec3::default(),
|
Vec3::default(),
|
||||||
)
|
)
|
||||||
|
@ -8,7 +8,7 @@ pub use self::{idle::IdleAnimation, jump::JumpAnimation, run::RunAnimation};
|
|||||||
use super::{Bone, Skeleton};
|
use super::{Bone, Skeleton};
|
||||||
use crate::render::FigureBoneData;
|
use crate::render::FigureBoneData;
|
||||||
use common::comp::{self};
|
use common::comp::{self};
|
||||||
use vek::Vec3;
|
use vek::{Mat4, Vec3};
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub struct QuadrupedMediumSkeleton {
|
pub struct QuadrupedMediumSkeleton {
|
||||||
@ -34,24 +34,27 @@ impl Skeleton for QuadrupedMediumSkeleton {
|
|||||||
|
|
||||||
fn bone_count(&self) -> usize { 11 }
|
fn bone_count(&self) -> usize { 11 }
|
||||||
|
|
||||||
fn compute_matrices(&self) -> ([FigureBoneData; 16], Vec3<f32>) {
|
fn compute_matrices<F: FnMut(Mat4<f32>) -> FigureBoneData>(
|
||||||
|
&self,
|
||||||
|
mut make_bone: F,
|
||||||
|
) -> ([FigureBoneData; 16], Vec3<f32>) {
|
||||||
let ears_mat = self.ears.compute_base_matrix();
|
let ears_mat = self.ears.compute_base_matrix();
|
||||||
let head_upper_mat = self.head_upper.compute_base_matrix();
|
let head_upper_mat = self.head_upper.compute_base_matrix();
|
||||||
let head_lower_mat = self.head_lower.compute_base_matrix();
|
let head_lower_mat = self.head_lower.compute_base_matrix();
|
||||||
let torso_mid_mat = self.torso_mid.compute_base_matrix();
|
let torso_mid_mat = self.torso_mid.compute_base_matrix();
|
||||||
(
|
(
|
||||||
[
|
[
|
||||||
FigureBoneData::new(head_upper_mat),
|
make_bone(head_upper_mat),
|
||||||
FigureBoneData::new(head_upper_mat * head_lower_mat),
|
make_bone(head_upper_mat * head_lower_mat),
|
||||||
FigureBoneData::new(head_upper_mat * self.jaw.compute_base_matrix()),
|
make_bone(head_upper_mat * self.jaw.compute_base_matrix()),
|
||||||
FigureBoneData::new(torso_mid_mat * self.tail.compute_base_matrix()),
|
make_bone(torso_mid_mat * self.tail.compute_base_matrix()),
|
||||||
FigureBoneData::new(self.torso_back.compute_base_matrix()),
|
make_bone(self.torso_back.compute_base_matrix()),
|
||||||
FigureBoneData::new(torso_mid_mat),
|
make_bone(torso_mid_mat),
|
||||||
FigureBoneData::new(head_upper_mat * ears_mat),
|
make_bone(head_upper_mat * ears_mat),
|
||||||
FigureBoneData::new(self.foot_lf.compute_base_matrix()),
|
make_bone(self.foot_lf.compute_base_matrix()),
|
||||||
FigureBoneData::new(self.foot_rf.compute_base_matrix()),
|
make_bone(self.foot_rf.compute_base_matrix()),
|
||||||
FigureBoneData::new(self.foot_lb.compute_base_matrix()),
|
make_bone(self.foot_lb.compute_base_matrix()),
|
||||||
FigureBoneData::new(self.foot_rb.compute_base_matrix()),
|
make_bone(self.foot_rb.compute_base_matrix()),
|
||||||
FigureBoneData::default(),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::default(),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::default(),
|
FigureBoneData::default(),
|
||||||
|
@ -8,7 +8,7 @@ pub use self::{idle::IdleAnimation, jump::JumpAnimation, run::RunAnimation};
|
|||||||
use super::{Bone, Skeleton};
|
use super::{Bone, Skeleton};
|
||||||
use crate::render::FigureBoneData;
|
use crate::render::FigureBoneData;
|
||||||
use common::comp::{self};
|
use common::comp::{self};
|
||||||
use vek::Vec3;
|
use vek::{Mat4, Vec3};
|
||||||
|
|
||||||
#[derive(Clone, Default)]
|
#[derive(Clone, Default)]
|
||||||
pub struct QuadrupedSmallSkeleton {
|
pub struct QuadrupedSmallSkeleton {
|
||||||
@ -29,15 +29,18 @@ impl Skeleton for QuadrupedSmallSkeleton {
|
|||||||
|
|
||||||
fn bone_count(&self) -> usize { 6 }
|
fn bone_count(&self) -> usize { 6 }
|
||||||
|
|
||||||
fn compute_matrices(&self) -> ([FigureBoneData; 16], Vec3<f32>) {
|
fn compute_matrices<F: FnMut(Mat4<f32>) -> FigureBoneData>(
|
||||||
|
&self,
|
||||||
|
mut make_bone: F,
|
||||||
|
) -> ([FigureBoneData; 16], Vec3<f32>) {
|
||||||
(
|
(
|
||||||
[
|
[
|
||||||
FigureBoneData::new(self.head.compute_base_matrix()),
|
make_bone(self.head.compute_base_matrix()),
|
||||||
FigureBoneData::new(self.chest.compute_base_matrix()),
|
make_bone(self.chest.compute_base_matrix()),
|
||||||
FigureBoneData::new(self.leg_lf.compute_base_matrix()),
|
make_bone(self.leg_lf.compute_base_matrix()),
|
||||||
FigureBoneData::new(self.leg_rf.compute_base_matrix()),
|
make_bone(self.leg_rf.compute_base_matrix()),
|
||||||
FigureBoneData::new(self.leg_lb.compute_base_matrix()),
|
make_bone(self.leg_lb.compute_base_matrix()),
|
||||||
FigureBoneData::new(self.leg_rb.compute_base_matrix()),
|
make_bone(self.leg_rb.compute_base_matrix()),
|
||||||
FigureBoneData::default(),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::default(),
|
FigureBoneData::default(),
|
||||||
FigureBoneData::default(),
|
FigureBoneData::default(),
|
||||||
|
@ -37,7 +37,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, LightingMode, Renderer},
|
render::{Consts, Globals, RenderMode, 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},
|
||||||
@ -231,9 +231,6 @@ pub enum Event {
|
|||||||
ChangeGamma(f32),
|
ChangeGamma(f32),
|
||||||
AdjustWindowSize([u16; 2]),
|
AdjustWindowSize([u16; 2]),
|
||||||
ToggleFullscreen,
|
ToggleFullscreen,
|
||||||
ChangeAaMode(AaMode),
|
|
||||||
ChangeCloudMode(CloudMode),
|
|
||||||
ChangeFluidMode(FluidMode),
|
|
||||||
CrosshairTransp(f32),
|
CrosshairTransp(f32),
|
||||||
ChatTransp(f32),
|
ChatTransp(f32),
|
||||||
CrosshairType(CrosshairType),
|
CrosshairType(CrosshairType),
|
||||||
@ -256,7 +253,7 @@ pub enum Event {
|
|||||||
ChangeLanguage(LanguageMetadata),
|
ChangeLanguage(LanguageMetadata),
|
||||||
ChangeBinding(GameInput),
|
ChangeBinding(GameInput),
|
||||||
ChangeFreeLookBehavior(PressBehavior),
|
ChangeFreeLookBehavior(PressBehavior),
|
||||||
ChangeLightingMode(LightingMode),
|
ChangeRenderMode(RenderMode),
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Are these the possible layouts we want?
|
// TODO: Are these the possible layouts we want?
|
||||||
@ -1897,20 +1894,11 @@ impl Hud {
|
|||||||
settings_window::Event::AdjustGamma(new_gamma) => {
|
settings_window::Event::AdjustGamma(new_gamma) => {
|
||||||
events.push(Event::ChangeGamma(new_gamma));
|
events.push(Event::ChangeGamma(new_gamma));
|
||||||
},
|
},
|
||||||
settings_window::Event::ChangeAaMode(new_aa_mode) => {
|
|
||||||
events.push(Event::ChangeAaMode(new_aa_mode));
|
|
||||||
},
|
|
||||||
settings_window::Event::ChangeCloudMode(new_cloud_mode) => {
|
|
||||||
events.push(Event::ChangeCloudMode(new_cloud_mode));
|
|
||||||
},
|
|
||||||
settings_window::Event::ChangeFluidMode(new_fluid_mode) => {
|
|
||||||
events.push(Event::ChangeFluidMode(new_fluid_mode));
|
|
||||||
},
|
|
||||||
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) => {
|
settings_window::Event::ChangeRenderMode(new_render_mode) => {
|
||||||
events.push(Event::ChangeLightingMode(new_lighting_mode));
|
events.push(Event::ChangeRenderMode(new_render_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, LightingMode},
|
render::{AaMode, CloudMode, FluidMode, LightingMode, RenderMode, ShadowMode},
|
||||||
ui::{fonts::ConrodVoxygenFonts, ImageSlider, ScaleMode, ToggleButton},
|
ui::{fonts::ConrodVoxygenFonts, ImageSlider, ScaleMode, ToggleButton},
|
||||||
window::GameInput,
|
window::GameInput,
|
||||||
GlobalState,
|
GlobalState,
|
||||||
@ -117,6 +117,8 @@ widget_ids! {
|
|||||||
fullscreen_label,
|
fullscreen_label,
|
||||||
lighting_mode_text,
|
lighting_mode_text,
|
||||||
lighting_mode_list,
|
lighting_mode_list,
|
||||||
|
shadow_mode_text,
|
||||||
|
shadow_mode_list,
|
||||||
save_window_size_button,
|
save_window_size_button,
|
||||||
audio_volume_slider,
|
audio_volume_slider,
|
||||||
audio_volume_text,
|
audio_volume_text,
|
||||||
@ -227,10 +229,7 @@ pub enum Event {
|
|||||||
AdjustGamma(f32),
|
AdjustGamma(f32),
|
||||||
AdjustWindowSize([u16; 2]),
|
AdjustWindowSize([u16; 2]),
|
||||||
ToggleFullscreen,
|
ToggleFullscreen,
|
||||||
ChangeAaMode(AaMode),
|
ChangeRenderMode(RenderMode),
|
||||||
ChangeCloudMode(CloudMode),
|
|
||||||
ChangeFluidMode(FluidMode),
|
|
||||||
ChangeLightingMode(LightingMode),
|
|
||||||
AdjustMusicVolume(f32),
|
AdjustMusicVolume(f32),
|
||||||
AdjustSfxVolume(f32),
|
AdjustSfxVolume(f32),
|
||||||
ChangeAudioDevice(String),
|
ChangeAudioDevice(String),
|
||||||
@ -1774,7 +1773,7 @@ impl<'a> Widget for SettingsWindow<'a> {
|
|||||||
// Get which AA mode is currently active
|
// Get which AA mode is currently active
|
||||||
let selected = mode_list
|
let selected = mode_list
|
||||||
.iter()
|
.iter()
|
||||||
.position(|x| *x == self.global_state.settings.graphics.aa_mode);
|
.position(|x| *x == self.global_state.settings.graphics.render_mode.aa);
|
||||||
|
|
||||||
if let Some(clicked) = DropDownList::new(&mode_label_list, selected)
|
if let Some(clicked) = DropDownList::new(&mode_label_list, selected)
|
||||||
.w_h(400.0, 22.0)
|
.w_h(400.0, 22.0)
|
||||||
@ -1784,7 +1783,10 @@ impl<'a> Widget for SettingsWindow<'a> {
|
|||||||
.down_from(state.ids.aa_mode_text, 8.0)
|
.down_from(state.ids.aa_mode_text, 8.0)
|
||||||
.set(state.ids.aa_mode_list, ui)
|
.set(state.ids.aa_mode_list, ui)
|
||||||
{
|
{
|
||||||
events.push(Event::ChangeAaMode(mode_list[clicked]));
|
events.push(Event::ChangeRenderMode(RenderMode {
|
||||||
|
aa: mode_list[clicked],
|
||||||
|
..self.global_state.settings.graphics.render_mode
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// CloudMode
|
// CloudMode
|
||||||
@ -1810,7 +1812,7 @@ impl<'a> Widget for SettingsWindow<'a> {
|
|||||||
// Get which cloud rendering mode is currently active
|
// Get which cloud rendering mode is currently active
|
||||||
let selected = mode_list
|
let selected = mode_list
|
||||||
.iter()
|
.iter()
|
||||||
.position(|x| *x == self.global_state.settings.graphics.cloud_mode);
|
.position(|x| *x == self.global_state.settings.graphics.render_mode.cloud);
|
||||||
|
|
||||||
if let Some(clicked) = DropDownList::new(&mode_label_list, selected)
|
if let Some(clicked) = DropDownList::new(&mode_label_list, selected)
|
||||||
.w_h(400.0, 22.0)
|
.w_h(400.0, 22.0)
|
||||||
@ -1820,7 +1822,10 @@ impl<'a> Widget for SettingsWindow<'a> {
|
|||||||
.down_from(state.ids.cloud_mode_text, 8.0)
|
.down_from(state.ids.cloud_mode_text, 8.0)
|
||||||
.set(state.ids.cloud_mode_list, ui)
|
.set(state.ids.cloud_mode_list, ui)
|
||||||
{
|
{
|
||||||
events.push(Event::ChangeCloudMode(mode_list[clicked]));
|
events.push(Event::ChangeRenderMode(RenderMode {
|
||||||
|
cloud: mode_list[clicked],
|
||||||
|
..self.global_state.settings.graphics.render_mode
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// FluidMode
|
// FluidMode
|
||||||
@ -1848,7 +1853,7 @@ impl<'a> Widget for SettingsWindow<'a> {
|
|||||||
// Get which fluid rendering mode is currently active
|
// Get which fluid rendering mode is currently active
|
||||||
let selected = mode_list
|
let selected = mode_list
|
||||||
.iter()
|
.iter()
|
||||||
.position(|x| *x == self.global_state.settings.graphics.fluid_mode);
|
.position(|x| *x == self.global_state.settings.graphics.render_mode.fluid);
|
||||||
|
|
||||||
if let Some(clicked) = DropDownList::new(&mode_label_list, selected)
|
if let Some(clicked) = DropDownList::new(&mode_label_list, selected)
|
||||||
.w_h(400.0, 22.0)
|
.w_h(400.0, 22.0)
|
||||||
@ -1858,7 +1863,10 @@ impl<'a> Widget for SettingsWindow<'a> {
|
|||||||
.down_from(state.ids.fluid_mode_text, 8.0)
|
.down_from(state.ids.fluid_mode_text, 8.0)
|
||||||
.set(state.ids.fluid_mode_list, ui)
|
.set(state.ids.fluid_mode_list, ui)
|
||||||
{
|
{
|
||||||
events.push(Event::ChangeFluidMode(mode_list[clicked]));
|
events.push(Event::ChangeRenderMode(RenderMode {
|
||||||
|
fluid: mode_list[clicked],
|
||||||
|
..self.global_state.settings.graphics.render_mode
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// LightingMode
|
// LightingMode
|
||||||
@ -1893,7 +1901,7 @@ impl<'a> Widget for SettingsWindow<'a> {
|
|||||||
// Get which lighting rendering mode is currently active
|
// Get which lighting rendering mode is currently active
|
||||||
let selected = mode_list
|
let selected = mode_list
|
||||||
.iter()
|
.iter()
|
||||||
.position(|x| *x == self.global_state.settings.graphics.lighting_mode);
|
.position(|x| *x == self.global_state.settings.graphics.render_mode.lighting);
|
||||||
|
|
||||||
if let Some(clicked) = DropDownList::new(&mode_label_list, selected)
|
if let Some(clicked) = DropDownList::new(&mode_label_list, selected)
|
||||||
.w_h(400.0, 22.0)
|
.w_h(400.0, 22.0)
|
||||||
@ -1903,14 +1911,61 @@ impl<'a> Widget for SettingsWindow<'a> {
|
|||||||
.down_from(state.ids.lighting_mode_text, 8.0)
|
.down_from(state.ids.lighting_mode_text, 8.0)
|
||||||
.set(state.ids.lighting_mode_list, ui)
|
.set(state.ids.lighting_mode_list, ui)
|
||||||
{
|
{
|
||||||
events.push(Event::ChangeLightingMode(mode_list[clicked]));
|
events.push(Event::ChangeRenderMode(RenderMode {
|
||||||
|
lighting: mode_list[clicked],
|
||||||
|
..self.global_state.settings.graphics.render_mode
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShadowMode
|
||||||
|
Text::new(
|
||||||
|
&self
|
||||||
|
.localized_strings
|
||||||
|
.get("hud.settings.shadow_rendering_mode"),
|
||||||
|
)
|
||||||
|
.down_from(state.ids.lighting_mode_list, 8.0)
|
||||||
|
.font_size(self.fonts.cyri.scale(14))
|
||||||
|
.font_id(self.fonts.cyri.conrod_id)
|
||||||
|
.color(TEXT_COLOR)
|
||||||
|
.set(state.ids.shadow_mode_text, ui);
|
||||||
|
|
||||||
|
let mode_list = [ShadowMode::None, ShadowMode::Cheap, ShadowMode::Map];
|
||||||
|
let mode_label_list = [
|
||||||
|
&self
|
||||||
|
.localized_strings
|
||||||
|
.get("hud.settings.shadow_rendering_mode.none"),
|
||||||
|
&self
|
||||||
|
.localized_strings
|
||||||
|
.get("hud.settings.shadow_rendering_mode.cheap"),
|
||||||
|
&self
|
||||||
|
.localized_strings
|
||||||
|
.get("hud.settings.shadow_rendering_mode.map"),
|
||||||
|
];
|
||||||
|
|
||||||
|
// Get which shadow rendering mode is currently active
|
||||||
|
let selected = mode_list
|
||||||
|
.iter()
|
||||||
|
.position(|x| *x == self.global_state.settings.graphics.render_mode.shadow);
|
||||||
|
|
||||||
|
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.shadow_mode_text, 8.0)
|
||||||
|
.set(state.ids.shadow_mode_list, ui)
|
||||||
|
{
|
||||||
|
events.push(Event::ChangeRenderMode(RenderMode {
|
||||||
|
shadow: mode_list[clicked],
|
||||||
|
..self.global_state.settings.graphics.render_mode
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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.lighting_mode_list, 8.0)
|
.down_from(state.ids.shadow_mode_list, 8.0)
|
||||||
.color(TEXT_COLOR)
|
.color(TEXT_COLOR)
|
||||||
.set(state.ids.fullscreen_label, ui);
|
.set(state.ids.fullscreen_label, ui);
|
||||||
|
|
||||||
|
@ -61,7 +61,9 @@ impl PlayState for CharSelectionState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
global_state.window.renderer_mut().clear();
|
let renderer = global_state.window.renderer_mut();
|
||||||
|
renderer.clear();
|
||||||
|
renderer.clear_shadows();
|
||||||
|
|
||||||
// Maintain the UI.
|
// Maintain the UI.
|
||||||
let events = self
|
let events = self
|
||||||
@ -123,6 +125,7 @@ impl PlayState for CharSelectionState {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Maintain the scene.
|
// Maintain the scene.
|
||||||
|
let loadout = self.char_selection_ui.get_loadout();
|
||||||
{
|
{
|
||||||
let client = self.client.borrow();
|
let client = self.client.borrow();
|
||||||
let scene_data = scene::SceneData {
|
let scene_data = scene::SceneData {
|
||||||
@ -138,12 +141,14 @@ impl PlayState for CharSelectionState {
|
|||||||
.figure_lod_render_distance
|
.figure_lod_render_distance
|
||||||
as f32,
|
as f32,
|
||||||
};
|
};
|
||||||
self.scene
|
self.scene.maintain(
|
||||||
.maintain(global_state.window.renderer_mut(), scene_data);
|
global_state.window.renderer_mut(),
|
||||||
|
scene_data,
|
||||||
|
loadout.as_ref(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render the scene.
|
// Render the scene.
|
||||||
let loadout = self.char_selection_ui.get_loadout();
|
|
||||||
self.scene.render(
|
self.scene.render(
|
||||||
global_state.window.renderer_mut(),
|
global_state.window.renderer_mut(),
|
||||||
self.client.borrow().get_tick(),
|
self.client.borrow().get_tick(),
|
||||||
|
778
voxygen/src/mesh/greedy.rs
Normal file
778
voxygen/src/mesh/greedy.rs
Normal file
@ -0,0 +1,778 @@
|
|||||||
|
use crate::render::{self, mesh::Quad, ColLightFmt, ColLightInfo, TerrainPipeline};
|
||||||
|
use vek::*;
|
||||||
|
|
||||||
|
type TerrainVertex = <TerrainPipeline as render::Pipeline>::Vertex;
|
||||||
|
|
||||||
|
/// A suspended greedy mesh, with enough information to recover color data.
|
||||||
|
///
|
||||||
|
/// The reason this exists is that greedy meshing is split into two parts.
|
||||||
|
/// First, the meshing itself needs to be performed; secondly, we generate a
|
||||||
|
/// texture atlas. We do things in this order to avoid having to copy all the
|
||||||
|
/// old vertices to the correct location. However, when trying to use the same
|
||||||
|
/// texture atlas for more than one model, this approach runs into the
|
||||||
|
/// problem that enough model information needs to be remembered to be able to
|
||||||
|
/// generate the colors after the function returns, so we box up the actual
|
||||||
|
/// coloring part as a continuation. When called with a final tile size and
|
||||||
|
/// vector, the continuation will consume the color data and write it to the
|
||||||
|
/// vector.
|
||||||
|
pub type SuspendedMesh<'a> = dyn for<'r> FnOnce(&'r mut ColLightInfo) + 'a;
|
||||||
|
|
||||||
|
/// Shared state for a greedy mesh, potentially passed along to multiple models.
|
||||||
|
///
|
||||||
|
/// For an explanation of why we want this, see `SuspendedMesh`.
|
||||||
|
pub struct GreedyMesh<'a> {
|
||||||
|
atlas: guillotiere::SimpleAtlasAllocator,
|
||||||
|
col_lights_size: Vec2<u16>,
|
||||||
|
max_size: guillotiere::Size,
|
||||||
|
suspended: Vec<Box<SuspendedMesh<'a>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> GreedyMesh<'a> {
|
||||||
|
pub fn new(max_size: guillotiere::Size) -> Self {
|
||||||
|
let min_max_dim = max_size.width.min(max_size.height);
|
||||||
|
assert!(
|
||||||
|
min_max_dim >= 4,
|
||||||
|
"min_max_dim={:?} >= 4 ({:?}",
|
||||||
|
min_max_dim,
|
||||||
|
max_size
|
||||||
|
);
|
||||||
|
// TODO: Collect information to see if we can choose a good value here.
|
||||||
|
let large_size_threshold = 256.min(min_max_dim / 2 + 1);
|
||||||
|
let small_size_threshold = 33.min(large_size_threshold / 2 + 1);
|
||||||
|
let size = guillotiere::Size::new(32, 32).min(max_size);
|
||||||
|
let atlas =
|
||||||
|
guillotiere::SimpleAtlasAllocator::with_options(size, &guillotiere::AllocatorOptions {
|
||||||
|
snap_size: 1,
|
||||||
|
small_size_threshold,
|
||||||
|
large_size_threshold,
|
||||||
|
});
|
||||||
|
let col_lights_size = Vec2::new(1u16, 1u16);
|
||||||
|
Self {
|
||||||
|
atlas,
|
||||||
|
col_lights_size,
|
||||||
|
max_size,
|
||||||
|
suspended: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn push</* S: render::Pipeline, *//*O: render::Pipeline, */ M: PartialEq, D: 'a>(
|
||||||
|
&mut self,
|
||||||
|
data: D,
|
||||||
|
draw_delta: Vec3<i32>,
|
||||||
|
greedy_size: Vec3<usize>,
|
||||||
|
greedy_size_cross: Vec3<usize>,
|
||||||
|
get_light: impl for<'r> FnMut(&'r mut D, Vec3<i32>) -> f32 + 'a,
|
||||||
|
get_color: impl for<'r> FnMut(&'r mut D, Vec3<i32>) -> Rgb<u8> + 'a,
|
||||||
|
get_opacity: impl for<'r> FnMut(&'r mut D, Vec3<i32>) -> bool + 'a,
|
||||||
|
should_draw: impl for<'r> FnMut(
|
||||||
|
&'r mut D,
|
||||||
|
Vec3<i32>,
|
||||||
|
Vec3<i32>,
|
||||||
|
Vec2<Vec3<i32>>,
|
||||||
|
) -> Option<(bool, M)>,
|
||||||
|
// create_shadow: impl for<'r> Fn(Vec3<f32>, Vec3<f32>, &'r M) -> S::Vertex,
|
||||||
|
// create_opaque: impl for<'r> Fn(Vec2<u16>, Vec3<f32>, Vec3<f32>, &'r M) -> O::Vertex,
|
||||||
|
push_quad: impl FnMut(Vec2<u16>, Vec2<Vec2<u16>>, Vec3<f32>, Vec2<Vec3<f32>>, Vec3<f32>, &M),
|
||||||
|
) -> Aabb<u16> {
|
||||||
|
let (bounds, /* opaque, *//*shadow, */ cont) = greedy_mesh(
|
||||||
|
&mut self.atlas,
|
||||||
|
&mut self.col_lights_size,
|
||||||
|
self.max_size,
|
||||||
|
data,
|
||||||
|
draw_delta,
|
||||||
|
greedy_size,
|
||||||
|
greedy_size_cross,
|
||||||
|
get_light,
|
||||||
|
get_color,
|
||||||
|
get_opacity,
|
||||||
|
should_draw,
|
||||||
|
// create_shadow,
|
||||||
|
// create_opaque,
|
||||||
|
push_quad,
|
||||||
|
);
|
||||||
|
self.suspended.push(cont);
|
||||||
|
bounds
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn finalize(self) -> ColLightInfo {
|
||||||
|
let cur_size = self.col_lights_size;
|
||||||
|
let col_lights = vec![/*Default::default()*/TerrainVertex::make_col_light(254, Rgb::broadcast(254)); usize::from(cur_size.x) * usize::from(cur_size.y)];
|
||||||
|
let mut col_lights_info = (col_lights, cur_size);
|
||||||
|
self.suspended.into_iter().for_each(|cont| {
|
||||||
|
cont(&mut col_lights_info);
|
||||||
|
});
|
||||||
|
col_lights_info
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn max_size(&self) -> guillotiere::Size { self.max_size }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Perform greedy meshing on a model, separately producing "pure" model data
|
||||||
|
/// (the shadow mesh), raw light and color data ready to be used as a texture
|
||||||
|
/// (the returned vector of ColLights, together with their width and height),
|
||||||
|
/// and the atlas positions (the opaque mesh) used to connect the shadow
|
||||||
|
/// information with the light and color information.
|
||||||
|
///
|
||||||
|
/// The opaque and shadow data are in the same order and it is intended that
|
||||||
|
/// they be used together as vertex buffers for display purposes. Thus, if you
|
||||||
|
/// perform further manipulation on the meshes after this function returns, such
|
||||||
|
/// as merges, please be sure that all those operations preserve this
|
||||||
|
/// relationship.
|
||||||
|
///
|
||||||
|
/// TODO: Consider supporting shared texture atlases (this might come in handy
|
||||||
|
/// for mobs or sprites, for instance).a
|
||||||
|
///
|
||||||
|
/// TODO: Add assertions to make this more robust.
|
||||||
|
///
|
||||||
|
/// Parameter description:
|
||||||
|
///
|
||||||
|
/// `max_size`:
|
||||||
|
/// The maximum allowable size of the texture atlas used to store the
|
||||||
|
/// light/color data for this mesh.
|
||||||
|
///
|
||||||
|
/// NOTE: It is an error to pass any size > u16::MAX.
|
||||||
|
///
|
||||||
|
/// Even aside from the above limitation, this will not necessarily always be
|
||||||
|
/// the same as the maximum atlas size supported by the hardware. For instance,
|
||||||
|
/// since we want to reserve 4 bits for a bone index for figures in their shadow
|
||||||
|
/// vertex, the atlas parameter for figures has to have at least 2 bits of the
|
||||||
|
/// normal; thus, it can only take up at most 30 bits total, meaning we are
|
||||||
|
/// restricted to "only" at most 2^15 × 2^15 atlases even if the hardware
|
||||||
|
/// supports larger ones.
|
||||||
|
///
|
||||||
|
/// `draw_delta`: The minimum position to mesh, in the coordinate system used
|
||||||
|
/// for queries against the volume.
|
||||||
|
///
|
||||||
|
/// `greedy_size`:
|
||||||
|
/// For each dimension i, for faces drawn in planes *parallel* to i, represents
|
||||||
|
/// the number of voxels considered along dimenson i in those planes, starting
|
||||||
|
/// from `draw_delta`.
|
||||||
|
///
|
||||||
|
/// `greedy_size_cross`:
|
||||||
|
/// For each dimension i, represents the number of planes considered
|
||||||
|
/// *orthogonal* to dimension i, starting from `draw_delta`. This should
|
||||||
|
/// usually be the same as greedy_size.
|
||||||
|
///
|
||||||
|
/// An important exception is during chunk rendering (where vertical faces at
|
||||||
|
/// chunk boundaries would otherwise be rendered twice, and also force us to use
|
||||||
|
/// more than 5 bits to represent x and y positions--though there may be a
|
||||||
|
/// clever way aruond the latter). Thus, for chunk rendering we set the number
|
||||||
|
/// of *vertical* planes to one less than the chunk size along the
|
||||||
|
/// x and y dimensions, but keep the number of *horizontal* planes large enough
|
||||||
|
/// to cover the whole chunk.
|
||||||
|
///
|
||||||
|
/// `get_light`:
|
||||||
|
/// Given a position, return the lighting information for the voxel at that
|
||||||
|
/// position.
|
||||||
|
///
|
||||||
|
/// `get_color`:
|
||||||
|
/// Given a position, return the color information for the voxel at that
|
||||||
|
/// position.
|
||||||
|
///
|
||||||
|
/// `get_opacity`:
|
||||||
|
/// Given a position, return the opacity information for the voxel at that
|
||||||
|
/// position. Currently, we don't support real translucent lighting, so the
|
||||||
|
/// value should either be `false` (for opaque blocks) or `true` (otherwise).
|
||||||
|
///
|
||||||
|
/// `should_draw`:
|
||||||
|
/// Given a position and a normal, should we draw the face between the position
|
||||||
|
/// and position - normal (i.e. the voxel "below" this vertex)? If so, provide
|
||||||
|
/// its orientation, together with any other meta information required for the
|
||||||
|
/// mesh that needs to split up faces. For example, terrain faces currently
|
||||||
|
/// record a bit indicating whether they are exposed to water or not, so we
|
||||||
|
/// should not merge faces where one is submerged in water and the other is not,
|
||||||
|
/// even if they otherwise have the same orientation, dimensions, and are
|
||||||
|
/// next to each other.
|
||||||
|
///
|
||||||
|
/// `create_shadow`:
|
||||||
|
/// Create a shadow vertex (used for both shadow and display rendering)
|
||||||
|
/// given its position, normal, and meta information. Note that the position
|
||||||
|
/// received here is relative to `draw_delta`--it still needs to be translated
|
||||||
|
/// to mesh coordinates.
|
||||||
|
///
|
||||||
|
/// `create_opaque`:
|
||||||
|
/// Create an opauqe vertex (used for only display rendering) from an atlas
|
||||||
|
/// position, normal, and meta information.
|
||||||
|
fn greedy_mesh<
|
||||||
|
'a, /* , S: render::Pipeline*//*, O: render::Pipeline */
|
||||||
|
M: PartialEq,
|
||||||
|
D: 'a,
|
||||||
|
>(
|
||||||
|
atlas: &mut guillotiere::SimpleAtlasAllocator,
|
||||||
|
col_lights_size: &mut Vec2<u16>,
|
||||||
|
max_size: guillotiere::Size,
|
||||||
|
mut data: D,
|
||||||
|
draw_delta: Vec3<i32>,
|
||||||
|
greedy_size: Vec3<usize>,
|
||||||
|
greedy_size_cross: Vec3<usize>,
|
||||||
|
get_light: impl for<'r> FnMut(&'r mut D, Vec3<i32>) -> f32 + 'a,
|
||||||
|
get_color: impl for<'r> FnMut(&'r mut D, Vec3<i32>) -> Rgb<u8> + 'a,
|
||||||
|
get_opacity: impl for<'r> FnMut(&'r mut D, Vec3<i32>) -> bool + 'a,
|
||||||
|
mut should_draw: impl for<'r> FnMut(
|
||||||
|
&'r mut D,
|
||||||
|
Vec3<i32>,
|
||||||
|
Vec3<i32>,
|
||||||
|
Vec2<Vec3<i32>>,
|
||||||
|
) -> Option<(bool, M)>,
|
||||||
|
// create_shadow: impl Fn(Vec3<f32>, Vec3<f32>, &M) -> S::Vertex,
|
||||||
|
// create_opaque: impl Fn(Vec2<u16>, Vec3<f32>, Vec3<f32>, &M) -> O::Vertex,
|
||||||
|
mut push_quad: impl FnMut(Vec2<u16>, Vec2<Vec2<u16>>, Vec3<f32>, Vec2<Vec3<f32>>, Vec3<f32>, &M),
|
||||||
|
) -> (
|
||||||
|
Aabb<u16>,
|
||||||
|
// Mesh<O>,
|
||||||
|
// Mesh<S>,
|
||||||
|
Box<SuspendedMesh<'a>>,
|
||||||
|
) {
|
||||||
|
// let mut opaque_mesh = Mesh::new();
|
||||||
|
// let mut shadow_mesh = Mesh::new();
|
||||||
|
|
||||||
|
// TODO: Collect information to see if we can choose a good value here.
|
||||||
|
let mut todo_rects = Vec::with_capacity(1024);
|
||||||
|
|
||||||
|
/* let mut bounds = Aabb {
|
||||||
|
min: Vec3::zero(),
|
||||||
|
max: Vec3::zero(),
|
||||||
|
}; */
|
||||||
|
|
||||||
|
/* let compute_bounds = |pos: Vec3<usize>, dim: Vec2<usize>, uv: Vec2<Vec3<u16>>/*, norm: Vec3<u16>, faces_forward: bool*/| {
|
||||||
|
Aabb {
|
||||||
|
min: pos,
|
||||||
|
max: pos + uv.x.map(usize::from) * dim.x + uv.y.map(usize::from) * dim.y,
|
||||||
|
}
|
||||||
|
}; */
|
||||||
|
|
||||||
|
// x (u = y, v = z)
|
||||||
|
greedy_mesh_cross_section(
|
||||||
|
Vec3::new(greedy_size.y, greedy_size.z, greedy_size_cross.x),
|
||||||
|
|pos| {
|
||||||
|
should_draw(
|
||||||
|
&mut data,
|
||||||
|
draw_delta + Vec3::new(pos.z, pos.x, pos.y),
|
||||||
|
Vec3::unit_x(), /* , pos.z, 0, x_size */
|
||||||
|
Vec2::new(Vec3::unit_y(), Vec3::unit_z()),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|pos, dim, &(faces_forward, ref meta)| {
|
||||||
|
let pos = Vec3::new(pos.z, pos.x, pos.y);
|
||||||
|
let uv = Vec2::new(Vec3::unit_y(), Vec3::unit_z());
|
||||||
|
let norm = Vec3::unit_x();
|
||||||
|
// bounds.expand_to_contain(compute_bounds(pos, dim, uv));
|
||||||
|
let atlas_pos = if let Some(atlas_pos) = add_to_atlas(
|
||||||
|
atlas,
|
||||||
|
&mut todo_rects,
|
||||||
|
pos,
|
||||||
|
uv,
|
||||||
|
dim,
|
||||||
|
norm,
|
||||||
|
faces_forward,
|
||||||
|
max_size,
|
||||||
|
col_lights_size,
|
||||||
|
) {
|
||||||
|
// assert!(atlas_pos.max.x - atlas_pos.min.x == dim.x as i32);
|
||||||
|
// assert!(atlas_pos.max.y - atlas_pos.min.y == dim.y as i32);
|
||||||
|
atlas_pos
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
create_quad_greedy(
|
||||||
|
// &mut shadow_mesh,
|
||||||
|
// &mut opaque_mesh,
|
||||||
|
/* Vec3::new(pos.z, pos.x, pos.y) */
|
||||||
|
pos,
|
||||||
|
dim,
|
||||||
|
uv,
|
||||||
|
norm,
|
||||||
|
faces_forward,
|
||||||
|
// Rgba::from_opaque(flat_get(pos).color),
|
||||||
|
// lightm
|
||||||
|
// ao,
|
||||||
|
meta,
|
||||||
|
atlas_pos,
|
||||||
|
// |pos| flat_get(pos),
|
||||||
|
// |pos, norm, meta| create_shadow(pos, norm, meta),
|
||||||
|
// |atlas_pos, pos, norm, meta| create_opaque(atlas_pos, pos, norm, meta),
|
||||||
|
|atlas_pos, dim, pos, draw_dim, norm, meta| {
|
||||||
|
push_quad(atlas_pos, dim, pos, draw_dim, norm, meta)
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// y (u = z, v = x)
|
||||||
|
greedy_mesh_cross_section(
|
||||||
|
Vec3::new(greedy_size.z, greedy_size.x, greedy_size_cross.y),
|
||||||
|
|pos| {
|
||||||
|
should_draw(
|
||||||
|
&mut data,
|
||||||
|
draw_delta + Vec3::new(pos.y, pos.z, pos.x),
|
||||||
|
Vec3::unit_y(),
|
||||||
|
Vec2::new(Vec3::unit_z(), Vec3::unit_x()),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|pos, dim, &(faces_forward, ref meta)| {
|
||||||
|
let pos = Vec3::new(pos.y, pos.z, pos.x);
|
||||||
|
let uv = Vec2::new(Vec3::unit_z(), Vec3::unit_x());
|
||||||
|
let norm = Vec3::unit_y();
|
||||||
|
// bounds.expand_to_contain(compute_bounds(pos, dim, uv));
|
||||||
|
let atlas_pos = if let Some(atlas_pos) = add_to_atlas(
|
||||||
|
atlas,
|
||||||
|
&mut todo_rects,
|
||||||
|
pos,
|
||||||
|
uv,
|
||||||
|
dim,
|
||||||
|
norm,
|
||||||
|
faces_forward,
|
||||||
|
max_size,
|
||||||
|
col_lights_size,
|
||||||
|
) {
|
||||||
|
atlas_pos
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
create_quad_greedy(
|
||||||
|
// &mut shadow_mesh,
|
||||||
|
// &mut opaque_mesh,
|
||||||
|
pos,
|
||||||
|
dim,
|
||||||
|
uv,
|
||||||
|
norm,
|
||||||
|
faces_forward,
|
||||||
|
// Rgba::from_opaque(flat_get(pos).color),
|
||||||
|
meta,
|
||||||
|
atlas_pos,
|
||||||
|
// |pos, norm, meta| create_shadow(pos, norm, meta),
|
||||||
|
// |atlas_pos, pos, norm, meta| create_opaque(atlas_pos, pos, norm, meta),
|
||||||
|
|atlas_pos, dim, pos, draw_dim, norm, meta| {
|
||||||
|
push_quad(atlas_pos, dim, pos, draw_dim, norm, meta)
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// z (u = x, v = y)
|
||||||
|
greedy_mesh_cross_section(
|
||||||
|
Vec3::new(greedy_size.x, greedy_size.y, greedy_size_cross.z),
|
||||||
|
|pos| {
|
||||||
|
/* if pos.z == 0 {
|
||||||
|
let pos = pos.map(|e| e as i32) + draw_delta; // - delta;
|
||||||
|
let to = flat_get(pos).is_opaque(); //map(|v| v.is_opaque()).unwrap_or(false);
|
||||||
|
if to { Some(false) } else { None }
|
||||||
|
} else */
|
||||||
|
{
|
||||||
|
should_draw(
|
||||||
|
&mut data,
|
||||||
|
draw_delta + Vec3::new(pos.x, pos.y, pos.z),
|
||||||
|
Vec3::unit_z(),
|
||||||
|
Vec2::new(Vec3::unit_x(), Vec3::unit_y()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|pos, dim, &(faces_forward, ref meta)| {
|
||||||
|
let pos = Vec3::new(pos.x, pos.y, pos.z);
|
||||||
|
let uv = Vec2::new(Vec3::unit_x(), Vec3::unit_y());
|
||||||
|
let norm = Vec3::unit_z();
|
||||||
|
// bounds.expand_to_contain(compute_bounds(pos, dim, uv));
|
||||||
|
let atlas_pos = if let Some(atlas_pos) = add_to_atlas(
|
||||||
|
atlas,
|
||||||
|
&mut todo_rects,
|
||||||
|
pos,
|
||||||
|
uv,
|
||||||
|
dim,
|
||||||
|
norm,
|
||||||
|
faces_forward,
|
||||||
|
max_size,
|
||||||
|
col_lights_size,
|
||||||
|
) {
|
||||||
|
atlas_pos
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
create_quad_greedy(
|
||||||
|
// &mut shadow_mesh,
|
||||||
|
// &mut opaque_mesh,
|
||||||
|
pos,
|
||||||
|
dim,
|
||||||
|
uv,
|
||||||
|
norm,
|
||||||
|
faces_forward,
|
||||||
|
// Rgba::from_opaque(flat_get(pos).color),
|
||||||
|
meta,
|
||||||
|
atlas_pos,
|
||||||
|
// |pos, norm, meta| create_shadow(pos, norm, meta),
|
||||||
|
// |atlas_pos, pos, norm, meta| create_opaque(atlas_pos, pos, norm, meta),
|
||||||
|
|atlas_pos, dim, pos, draw_dim, norm, meta| {
|
||||||
|
push_quad(atlas_pos, dim, pos, draw_dim, norm, meta)
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// NOTE: Safe because bound dimensions actually fit in a u16.
|
||||||
|
// let bounds = bounds.map(|e| e as u16);
|
||||||
|
// NOTE: Safe because draw_delta fits in i16.
|
||||||
|
let bounds = Aabb {
|
||||||
|
min: Vec3::zero(),
|
||||||
|
// NOTE: Safe because greedy_size fit in u16.
|
||||||
|
max: greedy_size.map(|e| e as u16),
|
||||||
|
};
|
||||||
|
(
|
||||||
|
bounds,
|
||||||
|
/* opaque_mesh, *//*shadow_mesh, */
|
||||||
|
Box::new(move |col_lights_info| {
|
||||||
|
let mut data = data;
|
||||||
|
draw_col_lights(
|
||||||
|
col_lights_info,
|
||||||
|
&mut data,
|
||||||
|
todo_rects,
|
||||||
|
draw_delta,
|
||||||
|
get_light,
|
||||||
|
get_color,
|
||||||
|
get_opacity,
|
||||||
|
TerrainVertex::make_col_light,
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Greedy meshing a single cross-section.
|
||||||
|
fn greedy_mesh_cross_section<M: PartialEq>(
|
||||||
|
/* mask: &mut [bool], */
|
||||||
|
dims: Vec3<usize>,
|
||||||
|
// Should we draw a face here (below this vertex)? If so, provide its meta information.
|
||||||
|
mut draw_face: impl FnMut(Vec3<i32>) -> Option<M>,
|
||||||
|
// Vertex, width and height, and meta information about the block.
|
||||||
|
mut push_quads: impl FnMut(Vec3<usize>, Vec2<usize>, &M),
|
||||||
|
) {
|
||||||
|
// mask represents which faces are either set while the other is unset, or unset
|
||||||
|
// while the other is set.
|
||||||
|
let mut mask = (0..dims.y * dims.x).map(|_| None).collect::<Vec<_>>();
|
||||||
|
(0..dims.z + 1).for_each(|d| {
|
||||||
|
// Compute mask
|
||||||
|
mask.iter_mut().enumerate().for_each(|(posi, mask)| {
|
||||||
|
let i = posi % dims.x;
|
||||||
|
let j = posi / dims.x;
|
||||||
|
// NOTE: Safe because dims.z actually fits in a u16.
|
||||||
|
*mask = draw_face(Vec3::new(i as i32, j as i32, d as i32));
|
||||||
|
});
|
||||||
|
|
||||||
|
(0..dims.y).for_each(|j| {
|
||||||
|
let mut i = 0;
|
||||||
|
while i < dims.x {
|
||||||
|
// Compute width (number of set x bits for this row and layer, starting at the
|
||||||
|
// current minimum column).
|
||||||
|
if let Some(ori) = &mask[j * dims.x + i] {
|
||||||
|
let width = 1 + mask[j * dims.x + i + 1..j * dims.x + dims.x]
|
||||||
|
.iter()
|
||||||
|
.take_while(move |&mask| mask.as_ref() == Some(ori))
|
||||||
|
.count();
|
||||||
|
let max_x = i + width;
|
||||||
|
// Compute height (number of rows having w set x bits for this layer, starting
|
||||||
|
// at the current minimum column and row).
|
||||||
|
let height = 1
|
||||||
|
+ (j + 1..dims.y)
|
||||||
|
.take_while(|h| {
|
||||||
|
mask[h * dims.x + i..h * dims.x + max_x]
|
||||||
|
.iter()
|
||||||
|
.all(|mask| mask.as_ref() == Some(ori))
|
||||||
|
})
|
||||||
|
.count();
|
||||||
|
let max_y = j + height;
|
||||||
|
// Add quad.
|
||||||
|
push_quads(Vec3::new(i, j, d /* + 1 */), Vec2::new(width, height), ori);
|
||||||
|
// Unset mask bits in drawn region, so we don't try to re-draw them.
|
||||||
|
(j..max_y).for_each(|l| {
|
||||||
|
mask[l * dims.x + i..l * dims.x + max_x]
|
||||||
|
.iter_mut()
|
||||||
|
.for_each(|mask| {
|
||||||
|
*mask = None;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// Update x value.
|
||||||
|
i = max_x;
|
||||||
|
} else {
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn add_to_atlas(
|
||||||
|
atlas: &mut guillotiere::SimpleAtlasAllocator,
|
||||||
|
todo_rects: &mut Vec<(
|
||||||
|
Vec3<i32>,
|
||||||
|
Vec2<Vec3<u16>>,
|
||||||
|
guillotiere::Rectangle,
|
||||||
|
Vec3<i32>,
|
||||||
|
)>,
|
||||||
|
pos: Vec3<usize>,
|
||||||
|
uv: Vec2<Vec3<u16>>,
|
||||||
|
dim: Vec2<usize>,
|
||||||
|
norm: Vec3<i16>,
|
||||||
|
faces_forward: bool,
|
||||||
|
max_size: guillotiere::Size,
|
||||||
|
cur_size: &mut Vec2<u16>,
|
||||||
|
) -> Option<guillotiere::Rectangle> {
|
||||||
|
// TODO: Check this conversion.
|
||||||
|
let atlas_rect;
|
||||||
|
loop {
|
||||||
|
// NOTE: Conversion to i32 is safe because he x, y, and z dimensions for any
|
||||||
|
// chunk index must fit in at least an i16 (lower for x and y, probably
|
||||||
|
// lower for z).
|
||||||
|
let res = atlas.allocate(guillotiere::Size::new(dim.x as i32 + 1, dim.y as i32 + 1));
|
||||||
|
if let Some(atlas_rect_) = res {
|
||||||
|
atlas_rect = atlas_rect_;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Allocation failure.
|
||||||
|
let current_size = atlas.size();
|
||||||
|
if current_size == max_size {
|
||||||
|
// NOTE: Currently, if we fail to allocate a terrain chunk in the atlas and we
|
||||||
|
// have already reached the maximum texture size, we choose to just skip the
|
||||||
|
// geometry and log a warning, rather than panicking or trying to use a fallback
|
||||||
|
// technique (e.g. a texture array).
|
||||||
|
//
|
||||||
|
// FIXME: Either make more robust, or explicitly document that limits on texture
|
||||||
|
// size need to be respected for terrain data (the OpenGL minimum requirement is
|
||||||
|
// 1024 × 1024, but in practice almost all computers support 4096 × 4096 or
|
||||||
|
// higher; see
|
||||||
|
// https://feedback.wildfiregames.com/report/opengl/feature/GL_MAX_TEXTURE_SIZE).
|
||||||
|
panic!(
|
||||||
|
"Could not add texture to atlas using simple allocator (pos={:?}, dim={:?});we \
|
||||||
|
could not fit the whole model into a single texture on this machine
|
||||||
|
(max texture size={:?}, so we are discarding this rectangle.",
|
||||||
|
pos, dim, max_size
|
||||||
|
);
|
||||||
|
// return None;
|
||||||
|
}
|
||||||
|
// Otherwise, we haven't reached max size yet, so double the size (or reach the
|
||||||
|
// max texture size) and try again.
|
||||||
|
let new_size = guillotiere::Size::new(
|
||||||
|
max_size.width.min(current_size.width.saturating_mul(2)),
|
||||||
|
max_size.height.min(current_size.height.saturating_mul(2)),
|
||||||
|
);
|
||||||
|
atlas.grow(new_size);
|
||||||
|
// atlas.grow((current_size * 2).min(max_size));
|
||||||
|
}
|
||||||
|
// NOTE: Conversion is correct because our initial max size for the atlas was
|
||||||
|
// a u16 and we never grew the atlas, meaning all valid coordinates within the
|
||||||
|
// atlas also fit into a u16.
|
||||||
|
*cur_size = Vec2::new(
|
||||||
|
cur_size.x.max(atlas_rect.max.x as u16),
|
||||||
|
cur_size.y.max(atlas_rect.max.y as u16),
|
||||||
|
);
|
||||||
|
|
||||||
|
/* let (dim, uv, norm) = if faces_forward {
|
||||||
|
// NOTE: Conversion to u16 safe by function precondition.
|
||||||
|
(dim.map(|e| e as u16), uv, norm)
|
||||||
|
} else {
|
||||||
|
// NOTE: Conversion to u16 safe by function precondition.
|
||||||
|
(Vec2::new(dim.y as u16, dim.x as u16), Vec2::new(uv.y, uv.x), -norm)
|
||||||
|
}; */
|
||||||
|
|
||||||
|
// NOTE: pos can be converted safely from usize to i32 because all legal block
|
||||||
|
// coordinates in this chunk must fit in an i32 (actually we have the much
|
||||||
|
// stronger property that this holds across the whole map).
|
||||||
|
let norm = norm.map(i32::from);
|
||||||
|
todo_rects.push((
|
||||||
|
pos.map(|e| e as i32) + if faces_forward { -norm } else { Vec3::zero() },
|
||||||
|
uv,
|
||||||
|
atlas_rect,
|
||||||
|
if faces_forward { norm } else { -norm },
|
||||||
|
));
|
||||||
|
Some(atlas_rect)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// We deferred actually recording the colors within the rectangles in order to
|
||||||
|
/// generate a texture of minimal size; we now proceed to create and populate
|
||||||
|
/// it.
|
||||||
|
///
|
||||||
|
/// TODO: Consider using the heavier interface (not the simple one) which seems
|
||||||
|
/// to provide builtin support for what we're doing here.
|
||||||
|
fn draw_col_lights<D>(
|
||||||
|
(col_lights, cur_size): &mut ColLightInfo,
|
||||||
|
data: &mut D,
|
||||||
|
todo_rects: Vec<(
|
||||||
|
Vec3<i32>,
|
||||||
|
Vec2<Vec3<u16>>,
|
||||||
|
guillotiere::Rectangle,
|
||||||
|
Vec3<i32>,
|
||||||
|
)>,
|
||||||
|
draw_delta: Vec3<i32>,
|
||||||
|
mut get_light: impl FnMut(&mut D, Vec3<i32>) -> f32,
|
||||||
|
mut get_color: impl FnMut(&mut D, Vec3<i32>) -> Rgb<u8>,
|
||||||
|
mut get_opacity: impl FnMut(&mut D, Vec3<i32>) -> bool,
|
||||||
|
mut make_col_light: impl FnMut(u8, Rgb<u8>) -> <<ColLightFmt as gfx::format::Formatted>::Surface as gfx::format::SurfaceTyped>::DataType,
|
||||||
|
) {
|
||||||
|
/* for i in 0..todo_rects.len() {
|
||||||
|
for j in 0..todo_rects.len() {
|
||||||
|
if i == j {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert!(!todo_rects[i].2.intersects(&todo_rects[j].2));
|
||||||
|
}
|
||||||
|
} */
|
||||||
|
todo_rects
|
||||||
|
.into_iter()
|
||||||
|
// .rev()
|
||||||
|
.for_each(|(pos, uv, rect, delta)| {
|
||||||
|
// NOTE: Conversions are safe because width, height, and offset must be
|
||||||
|
// non-negative, and because every allocated coordinate in the atlas must be in
|
||||||
|
// bounds for the original size, max_texture_size, which fit into a u16.
|
||||||
|
let width = (rect.max.x - rect.min.x) as u16;//rect.width() as u16;
|
||||||
|
let height = (rect.max.y - rect.min.y) as u16;//rect.height() as u16;
|
||||||
|
/* if width > 32 || height > 32 {
|
||||||
|
println!("Rect: {:?}", rect);
|
||||||
|
} */
|
||||||
|
let left = rect.min.x as u16;
|
||||||
|
let top = rect.min.y as u16;
|
||||||
|
let uv = uv.map(|e| e.map(i32::from));
|
||||||
|
let pos = pos + draw_delta;//Vec3::new(0, 0, z_start - 1);// + mesh_delta;// + draw_delta;
|
||||||
|
(0..height).for_each(|v| {
|
||||||
|
let start = usize::from(cur_size.x) * usize::from(top + v) + usize::from(left);
|
||||||
|
(0..width).zip(&mut col_lights[start..start + usize::from(width)]).for_each(|(u, col_light)| {
|
||||||
|
let pos = pos + uv.x * i32::from(u) + uv.y * i32::from(v);
|
||||||
|
// TODO: Consider optimizing to take advantage of the fact that this whole
|
||||||
|
// face should be facing nothing but air (this is not currently true, but
|
||||||
|
// could be if we used the right AO strategy).
|
||||||
|
// Each indirect light needs to come in through the direct light.
|
||||||
|
// Thus, we assign each light a score based on opacity (currently just 0 or
|
||||||
|
// 1, but it could support transluscent lights in the future).
|
||||||
|
// Thus, indirect_u_opacity and indirect_v_opacity are multiplied by
|
||||||
|
// direct_opacity, and indirect_uv_opacity is multiplied by
|
||||||
|
// the maximum of both of u and v's indirect opacities (since there are
|
||||||
|
// two choices for how to get to the direct surface).
|
||||||
|
let pos = pos +
|
||||||
|
if u + 1 == width { -uv.x } else { Vec3::zero() } +
|
||||||
|
if v + 1 == height { -uv.y } else { Vec3::zero() };
|
||||||
|
let uv = Vec2::new(
|
||||||
|
if u + 1 == width { -uv.x } else { uv.x },
|
||||||
|
if v + 1 == height { -uv.y } else { uv.y },
|
||||||
|
);
|
||||||
|
|
||||||
|
let light_pos = pos + /*range.min + */delta;
|
||||||
|
// let block = flat_get(pos);
|
||||||
|
|
||||||
|
// Currently, we assume that direct_opacity is 1 (if it's 0, you can't see
|
||||||
|
// the face anyway, since it's blocked by the block directly in front of it).
|
||||||
|
// TODO: If we add non-0/1 opacities, fix this.
|
||||||
|
// top-left block
|
||||||
|
// let direct_opacity = !flat_get(pos + delta).is_opaque();
|
||||||
|
// bottom-left block
|
||||||
|
let direct_u_opacity = get_opacity(data, light_pos - uv.x);
|
||||||
|
// top-right block
|
||||||
|
let direct_v_opacity = get_opacity(data, light_pos - uv.y);
|
||||||
|
// top-left block
|
||||||
|
// NOTE: Currently, since we only have 0 / 1 opacities, we don't worry
|
||||||
|
// about whether the uv block itself is opaque, because if it is its light
|
||||||
|
// value will be 0 anyway. But if we add translucent objects, we'll need
|
||||||
|
// to care about uv's opacity as well.
|
||||||
|
// let direct_uv_opacity = !flat_get(pos + delta - uv.x - uv.y).is_opaque();
|
||||||
|
// let indirect_opacity = direct_uv_opacity && (direct_u_opacity || direct_v_opacity) && direct_opacity;
|
||||||
|
|
||||||
|
// NOTE: Since we only support 0/1 opacities currently, we asssume
|
||||||
|
// direct_opacity is 1, and the light value will be zero anyway for objects
|
||||||
|
// with opacity 0, we only "multiply" by indirect_uv_opacity for now (since
|
||||||
|
// it's the only one that could be 0 even if its light value is not).
|
||||||
|
// However, "spiritually" these light values are all being multiplied by
|
||||||
|
// their opacities.
|
||||||
|
let darkness = (
|
||||||
|
// Light from the bottom-right-front block to this vertex always
|
||||||
|
// appears on this face, since it's the block this face is facing (so
|
||||||
|
// it can't be blocked by anything).
|
||||||
|
if /*direct_u_opacity || direct_v_opacity*/true/* || !flat_get(pos - uv.x - uv.y).is_opaque()*//* || !block.is_opaque()*/ { get_light(data, light_pos) } else { 0.0 } +
|
||||||
|
if /*direct_opacity || direct_uv_opacity*/true/* || !flat_get(pos - uv.y).is_opaque()*/ { get_light(data, light_pos - uv.x) } else { 0.0 } +
|
||||||
|
if /*direct_opacity || direct_uv_opacity*/true/* || !flat_get(pos - uv.x).is_opaque()*/ { get_light(data, light_pos - uv.y) } else { 0.0 } +
|
||||||
|
if direct_u_opacity || direct_v_opacity/* || !block.is_opaque()*/ { get_light(data, light_pos - uv.x - uv.y) } else { 0.0 }
|
||||||
|
) / 4.0;
|
||||||
|
let col = get_color(data, pos);//.map(Rgba::from_opaque).unwrap_or(Rgba::zero());
|
||||||
|
let light = (darkness * 255.0) as u8;
|
||||||
|
*col_light = make_col_light(light, col);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Precondition: when this function is called, atlas_pos should reflect an
|
||||||
|
/// actual valid position in a texture atlas (meaning it should fit into a u16).
|
||||||
|
fn create_quad_greedy</* S: render::Pipeline, *//*O: render::Pipeline, */ M>(
|
||||||
|
// shadow_mesh: &mut Mesh<S>,
|
||||||
|
// opaque_mesh: &mut Mesh<O>,
|
||||||
|
origin: Vec3<usize>,
|
||||||
|
dim: Vec2<usize>,
|
||||||
|
uv: Vec2<Vec3<u16>>,
|
||||||
|
norm: Vec3<i16>,
|
||||||
|
faces_forward: bool,
|
||||||
|
meta: &M,
|
||||||
|
atlas_pos: guillotiere::Rectangle,
|
||||||
|
// origin, norm, meta
|
||||||
|
// create_shadow: impl Fn(Vec3<f32>, Vec3<f32>, &M) -> S::Vertex,
|
||||||
|
// create_opaque: impl Fn(Vec2<u16>, Vec3<f32>, Vec3<f32>, &M) -> O::Vertex,
|
||||||
|
mut push_quad: impl FnMut(Vec2<u16>, Vec2<Vec2<u16>>, Vec3<f32>, Vec2<Vec3<f32>>, Vec3<f32>, &M),
|
||||||
|
) /* -> Quad<ShadowPipeline> */
|
||||||
|
{
|
||||||
|
let origin = origin.map(|e| e as f32);
|
||||||
|
/* // NOTE: Conversion to u16 safe by function precondition.
|
||||||
|
let dim = uv.map2(dim.map(|e| e as u16), |e, f| e * f); */
|
||||||
|
// NOTE: Conversion to f32 safe by function precondition (u16 can losslessly
|
||||||
|
// cast to f32, and dim fits in a u16).
|
||||||
|
let draw_dim = uv.map2(dim.map(|e| e as f32), |e, f| e.map(f32::from) * f);
|
||||||
|
let dim = Vec2::new(Vec2::new(dim.x as u16, 0), Vec2::new(0, dim.y as u16));
|
||||||
|
let (draw_dim, dim, /* uv, */ norm) = if faces_forward {
|
||||||
|
/* // NOTE: Conversion to u16 safe by function precondition.
|
||||||
|
(dim.map(|e| e as u16), uv, norm) */
|
||||||
|
(draw_dim, dim, norm)
|
||||||
|
} else {
|
||||||
|
/* // NOTE: Conversion to u16 safe by function precondition.
|
||||||
|
(Vec2::new(dim.y as u16, dim.x as u16), Vec2::new(uv.y, uv.x), -norm) */
|
||||||
|
(
|
||||||
|
Vec2::new(draw_dim.y, draw_dim.x),
|
||||||
|
Vec2::new(dim.y, dim.x),
|
||||||
|
-norm,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
let norm = norm.map(f32::from);
|
||||||
|
// let draw_dim = draw_dim.map(|e| e.map(f32::from));
|
||||||
|
// NOTE: Conversion to u16 safe by function precondition.
|
||||||
|
let atlas_pos = Vec2::new(atlas_pos.min.x as u16, atlas_pos.min.y as u16);
|
||||||
|
/* shadow_mesh.push_quad(Quad::new(
|
||||||
|
create_shadow(origin, norm, &meta/*, atlas_pos*/),
|
||||||
|
create_shadow(origin + draw_dim.x, norm, &meta/*, atlas_pos + dim.x*/),
|
||||||
|
create_shadow(origin + draw_dim.x + draw_dim.y, norm, &meta/*, atlas_pos + dim.x + dim.y*/),
|
||||||
|
create_shadow(origin + draw_dim.y, norm, &meta/*, atlas_pos + dim.y*/),
|
||||||
|
)); */
|
||||||
|
/* opaque_mesh.push_quad(Quad::new(
|
||||||
|
create_opaque(atlas_pos, origin, norm, &meta),
|
||||||
|
create_opaque(atlas_pos + dim.x, origin + draw_dim.x, norm, &meta),
|
||||||
|
create_opaque(atlas_pos + dim.x + dim.y, origin + draw_dim.x + draw_dim.y, norm, &meta),
|
||||||
|
create_opaque(atlas_pos + dim.y, origin + draw_dim.y, norm, &meta),
|
||||||
|
)); */
|
||||||
|
push_quad(atlas_pos, dim, origin, draw_dim, norm, meta);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_quad<O: render::Pipeline, M>(
|
||||||
|
atlas_pos: Vec2<u16>,
|
||||||
|
dim: Vec2<Vec2<u16>>,
|
||||||
|
origin: Vec3<f32>,
|
||||||
|
draw_dim: Vec2<Vec3<f32>>,
|
||||||
|
norm: Vec3<f32>,
|
||||||
|
meta: &M,
|
||||||
|
create_vertex: impl Fn(Vec2<u16>, Vec3<f32>, Vec3<f32>, &M) -> O::Vertex,
|
||||||
|
) -> Quad<O> {
|
||||||
|
Quad::new(
|
||||||
|
create_vertex(atlas_pos, origin, norm, meta),
|
||||||
|
create_vertex(atlas_pos + dim.x, origin + draw_dim.x, norm, meta),
|
||||||
|
create_vertex(
|
||||||
|
atlas_pos + dim.x + dim.y,
|
||||||
|
origin + draw_dim.x + draw_dim.y,
|
||||||
|
norm,
|
||||||
|
meta,
|
||||||
|
),
|
||||||
|
create_vertex(atlas_pos + dim.y, origin + draw_dim.y, norm, meta),
|
||||||
|
/* create_vertex(atlas_pos, origin, norm, meta),
|
||||||
|
create_vertex(atlas_pos + dim.y, origin + draw_dim.y, norm, meta),
|
||||||
|
create_vertex(atlas_pos + dim.x + dim.y, origin + draw_dim.x + draw_dim.y, norm, meta),
|
||||||
|
create_vertex(atlas_pos + dim.x, origin + draw_dim.x, norm, meta), */
|
||||||
|
)
|
||||||
|
}
|
@ -1,22 +1,24 @@
|
|||||||
|
pub mod greedy;
|
||||||
pub mod segment;
|
pub mod segment;
|
||||||
pub mod terrain;
|
pub mod terrain;
|
||||||
mod vol;
|
|
||||||
|
|
||||||
use crate::render::{self, Mesh};
|
use crate::render::{self, Mesh};
|
||||||
|
|
||||||
pub trait Meshable<'a, P: render::Pipeline, T: render::Pipeline> {
|
pub trait Meshable<P: render::Pipeline, T> {
|
||||||
type Pipeline: render::Pipeline;
|
type Pipeline: render::Pipeline;
|
||||||
type TranslucentPipeline: render::Pipeline;
|
type TranslucentPipeline: render::Pipeline;
|
||||||
type ShadowPipeline: render::Pipeline;
|
type ShadowPipeline: render::Pipeline;
|
||||||
type Supplement;
|
type Supplement;
|
||||||
|
type Result;
|
||||||
|
|
||||||
// Generate meshes - one opaque, one translucent, one shadow
|
// Generate meshes - one opaque, one translucent, one shadow
|
||||||
fn generate_mesh(
|
fn generate_mesh(
|
||||||
&'a self,
|
self,
|
||||||
supp: Self::Supplement,
|
supp: Self::Supplement,
|
||||||
) -> (
|
) -> (
|
||||||
Mesh<Self::Pipeline>,
|
Mesh<Self::Pipeline>,
|
||||||
Mesh<Self::TranslucentPipeline>,
|
Mesh<Self::TranslucentPipeline>,
|
||||||
Mesh<Self::ShadowPipeline>,
|
Mesh<Self::ShadowPipeline>,
|
||||||
|
Self::Result,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,91 +1,118 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
mesh::{vol, Meshable},
|
mesh::{
|
||||||
render::{self, FigurePipeline, Mesh, SpritePipeline},
|
greedy::{self, GreedyMesh},
|
||||||
|
Meshable,
|
||||||
|
},
|
||||||
|
render::{self, FigurePipeline, Mesh, ShadowPipeline, SpritePipeline, TerrainPipeline},
|
||||||
};
|
};
|
||||||
use common::{
|
use common::{
|
||||||
figure::Cell,
|
figure::Cell,
|
||||||
util::{linear_to_srgb, srgb_to_linear},
|
|
||||||
vol::{BaseVol, ReadVol, SizedVol, Vox},
|
vol::{BaseVol, ReadVol, SizedVol, Vox},
|
||||||
};
|
};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
type FigureVertex = <FigurePipeline as render::Pipeline>::Vertex;
|
|
||||||
type SpriteVertex = <SpritePipeline as render::Pipeline>::Vertex;
|
type SpriteVertex = <SpritePipeline as render::Pipeline>::Vertex;
|
||||||
|
type TerrainVertex = <TerrainPipeline as render::Pipeline>::Vertex;
|
||||||
|
|
||||||
impl<'a, V: 'a> Meshable<'a, FigurePipeline, FigurePipeline> for V
|
impl<'a: 'b, 'b, V: 'a> Meshable<FigurePipeline, &'b mut GreedyMesh<'a>> for V
|
||||||
where
|
where
|
||||||
V: BaseVol<Vox = Cell> + ReadVol + SizedVol,
|
V: BaseVol<Vox = Cell> + ReadVol + SizedVol,
|
||||||
/* TODO: Use VolIterator instead of manually iterating
|
/* TODO: Use VolIterator instead of manually iterating
|
||||||
* &'a V: IntoVolIterator<'a> + IntoFullVolIterator<'a>,
|
* &'a V: IntoVolIterator<'a> + IntoFullVolIterator<'a>,
|
||||||
* &'a V: BaseVol<Vox=Cell>, */
|
* &'a V: BaseVol<Vox=Cell>, */
|
||||||
{
|
{
|
||||||
type Pipeline = FigurePipeline;
|
type Pipeline = TerrainPipeline;
|
||||||
type ShadowPipeline = FigurePipeline;
|
type Result = Aabb<f32>;
|
||||||
type Supplement = (Vec3<f32>, Vec3<f32>);
|
type ShadowPipeline = ShadowPipeline;
|
||||||
|
type Supplement = (&'b mut GreedyMesh<'a>, Vec3<f32>, Vec3<f32>);
|
||||||
type TranslucentPipeline = FigurePipeline;
|
type TranslucentPipeline = FigurePipeline;
|
||||||
|
|
||||||
// TODO: Make sprites cast shadows?
|
|
||||||
|
|
||||||
fn generate_mesh(
|
fn generate_mesh(
|
||||||
&'a self,
|
self,
|
||||||
(offs, scale): Self::Supplement,
|
(greedy, offs, scale): Self::Supplement,
|
||||||
) -> (
|
) -> (
|
||||||
Mesh<Self::Pipeline>,
|
Mesh<Self::Pipeline>,
|
||||||
Mesh<Self::TranslucentPipeline>,
|
Mesh<Self::TranslucentPipeline>,
|
||||||
Mesh<Self::ShadowPipeline>,
|
Mesh<Self::ShadowPipeline>,
|
||||||
|
Self::Result,
|
||||||
) {
|
) {
|
||||||
let mut mesh = Mesh::new();
|
let max_size = greedy.max_size();
|
||||||
|
// NOTE: Required because we steal two bits from the normal in the shadow uint
|
||||||
|
// in order to store the bone index. The two bits are instead taken out
|
||||||
|
// of the atlas coordinates, which is why we "only" allow 1 << 15 per
|
||||||
|
// coordinate instead of 1 << 16.
|
||||||
|
assert!(max_size.width.max(max_size.height) < 1 << 15);
|
||||||
|
|
||||||
let vol_iter = (self.lower_bound().x..self.upper_bound().x)
|
let greedy_size = Vec3::new(
|
||||||
.map(|i| {
|
(self.upper_bound().x - self.lower_bound().x + 1) as usize,
|
||||||
(self.lower_bound().y..self.upper_bound().y).map(move |j| {
|
(self.upper_bound().y - self.lower_bound().y + 1) as usize,
|
||||||
(self.lower_bound().z..self.upper_bound().z).map(move |k| Vec3::new(i, j, k))
|
(self.upper_bound().z - self.lower_bound().z + 1) as usize,
|
||||||
})
|
);
|
||||||
})
|
let greedy_size_cross = greedy_size;
|
||||||
.flatten()
|
let draw_delta = Vec3::new(
|
||||||
.flatten()
|
self.lower_bound().x,
|
||||||
.map(|pos| (pos, self.get(pos).map(|x| *x).unwrap_or(Vox::empty())));
|
self.lower_bound().y,
|
||||||
|
self.lower_bound().z,
|
||||||
|
);
|
||||||
|
|
||||||
for (pos, vox) in vol_iter {
|
let get_light = |vol: &mut V, pos: Vec3<i32>| {
|
||||||
if let Some(col) = vox.get_color() {
|
if vol.get(pos).map(|vox| vox.is_empty()).unwrap_or(true) {
|
||||||
vol::push_vox_verts(
|
1.0
|
||||||
&mut mesh,
|
} else {
|
||||||
faces_to_make(self, pos, true, |vox| vox.is_empty()),
|
0.0
|
||||||
offs + pos.map(|e| e as f32),
|
|
||||||
&[[[Rgba::from_opaque(col); 3]; 3]; 3],
|
|
||||||
|origin, norm, col, light, ao, _meta| {
|
|
||||||
FigureVertex::new(
|
|
||||||
origin * scale,
|
|
||||||
norm,
|
|
||||||
linear_to_srgb(srgb_to_linear(col) * light),
|
|
||||||
ao,
|
|
||||||
0,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
&{
|
|
||||||
let mut ls = [[[None; 3]; 3]; 3];
|
|
||||||
for x in 0..3 {
|
|
||||||
for y in 0..3 {
|
|
||||||
for z in 0..3 {
|
|
||||||
ls[z][y][x] = self
|
|
||||||
.get(pos + Vec3::new(x as i32, y as i32, z as i32) - 1)
|
|
||||||
.map(|v| v.is_empty())
|
|
||||||
.unwrap_or(true)
|
|
||||||
.then_some(1.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ls
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
let get_color = |vol: &mut V, pos: Vec3<i32>| {
|
||||||
|
vol.get(pos)
|
||||||
|
.ok()
|
||||||
|
.and_then(|vox| vox.get_color())
|
||||||
|
.unwrap_or(Rgb::zero())
|
||||||
|
};
|
||||||
|
let get_opacity =
|
||||||
|
|vol: &mut V, pos: Vec3<i32>| vol.get(pos).map(|vox| vox.is_empty()).unwrap_or(true);
|
||||||
|
let should_draw = |vol: &mut V, pos: Vec3<i32>, delta: Vec3<i32>, uv| {
|
||||||
|
should_draw_greedy(pos, delta, uv, |vox| {
|
||||||
|
vol.get(vox).map(|vox| *vox).unwrap_or(Vox::empty())
|
||||||
|
})
|
||||||
|
};
|
||||||
|
let create_opaque = |atlas_pos, pos, norm, _meta| {
|
||||||
|
TerrainVertex::new_figure(atlas_pos, (pos + offs) * scale, norm, 0)
|
||||||
|
};
|
||||||
|
|
||||||
(mesh, Mesh::new(), Mesh::new())
|
let mut opaque_mesh = Mesh::new();
|
||||||
|
let bounds = greedy.push(
|
||||||
|
self,
|
||||||
|
draw_delta,
|
||||||
|
greedy_size,
|
||||||
|
greedy_size_cross,
|
||||||
|
get_light,
|
||||||
|
get_color,
|
||||||
|
get_opacity,
|
||||||
|
should_draw,
|
||||||
|
|atlas_origin, dim, origin, draw_dim, norm, meta| {
|
||||||
|
opaque_mesh.push_quad(greedy::create_quad(
|
||||||
|
atlas_origin,
|
||||||
|
dim,
|
||||||
|
origin,
|
||||||
|
draw_dim,
|
||||||
|
norm,
|
||||||
|
meta,
|
||||||
|
|atlas_pos, pos, norm, &meta| create_opaque(atlas_pos, pos, norm, meta),
|
||||||
|
));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
let bounds = bounds.map(f32::from);
|
||||||
|
let bounds = Aabb {
|
||||||
|
min: (bounds.min + offs) * scale,
|
||||||
|
max: (bounds.max + offs) * scale,
|
||||||
|
}
|
||||||
|
.made_valid();
|
||||||
|
|
||||||
|
(opaque_mesh, Mesh::new(), Mesh::new(), bounds)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, V: 'a> Meshable<'a, SpritePipeline, SpritePipeline> for V
|
impl<'a: 'b, 'b, V: 'a> Meshable<SpritePipeline, /* SpritePipeline */ &'b mut GreedyMesh<'a>> for V
|
||||||
where
|
where
|
||||||
V: BaseVol<Vox = Cell> + ReadVol + SizedVol,
|
V: BaseVol<Vox = Cell> + ReadVol + SizedVol,
|
||||||
/* TODO: Use VolIterator instead of manually iterating
|
/* TODO: Use VolIterator instead of manually iterating
|
||||||
@ -93,92 +120,172 @@ where
|
|||||||
* &'a V: BaseVol<Vox=Cell>, */
|
* &'a V: BaseVol<Vox=Cell>, */
|
||||||
{
|
{
|
||||||
type Pipeline = SpritePipeline;
|
type Pipeline = SpritePipeline;
|
||||||
type ShadowPipeline = SpritePipeline;
|
type Result = ();
|
||||||
type Supplement = (Vec3<f32>, Vec3<f32>);
|
type ShadowPipeline = ShadowPipeline;
|
||||||
|
type Supplement = (&'b mut GreedyMesh<'a>, bool);
|
||||||
type TranslucentPipeline = SpritePipeline;
|
type TranslucentPipeline = SpritePipeline;
|
||||||
|
|
||||||
// TODO: Make sprites cast shadows?
|
|
||||||
|
|
||||||
fn generate_mesh(
|
fn generate_mesh(
|
||||||
&'a self,
|
self,
|
||||||
(offs, scale): Self::Supplement,
|
(greedy, vertical_stripes): Self::Supplement,
|
||||||
) -> (
|
) -> (
|
||||||
Mesh<Self::Pipeline>,
|
Mesh<Self::Pipeline>,
|
||||||
Mesh<Self::TranslucentPipeline>,
|
Mesh<Self::TranslucentPipeline>,
|
||||||
Mesh<Self::ShadowPipeline>,
|
Mesh<Self::ShadowPipeline>,
|
||||||
|
(),
|
||||||
) {
|
) {
|
||||||
let mut mesh = Mesh::new();
|
let max_size = greedy.max_size();
|
||||||
|
// NOTE: Required because we steal two bits from the normal in the shadow uint
|
||||||
|
// in order to store the bone index. The two bits are instead taken out
|
||||||
|
// of the atlas coordinates, which is why we "only" allow 1 << 15 per
|
||||||
|
// coordinate instead of 1 << 16.
|
||||||
|
assert!(max_size.width.max(max_size.height) < 1 << 16);
|
||||||
|
|
||||||
let vol_iter = (self.lower_bound().x..self.upper_bound().x)
|
let greedy_size = Vec3::new(
|
||||||
.map(|i| {
|
(self.upper_bound().x - self.lower_bound().x + 1) as usize,
|
||||||
(self.lower_bound().y..self.upper_bound().y).map(move |j| {
|
(self.upper_bound().y - self.lower_bound().y + 1) as usize,
|
||||||
(self.lower_bound().z..self.upper_bound().z).map(move |k| Vec3::new(i, j, k))
|
(self.upper_bound().z - self.lower_bound().z + 1) as usize,
|
||||||
})
|
);
|
||||||
})
|
assert!(
|
||||||
.flatten()
|
greedy_size.x <= 16 && greedy_size.y <= 16 && greedy_size.z <= 64,
|
||||||
.flatten()
|
"Sprite size out of bounds: {:?} ≤ (15, 15, 63)",
|
||||||
.map(|pos| (pos, self.get(pos).map(|x| *x).unwrap_or(Vox::empty())));
|
greedy_size - 1
|
||||||
|
);
|
||||||
|
let greedy_size_cross = greedy_size;
|
||||||
|
let draw_delta = Vec3::new(
|
||||||
|
self.lower_bound().x,
|
||||||
|
self.lower_bound().y,
|
||||||
|
self.lower_bound().z,
|
||||||
|
);
|
||||||
|
|
||||||
for (pos, vox) in vol_iter {
|
let get_light = |vol: &mut V, pos: Vec3<i32>| {
|
||||||
if let Some(col) = vox.get_color() {
|
if vol.get(pos).map(|vox| vox.is_empty()).unwrap_or(true) {
|
||||||
vol::push_vox_verts(
|
1.0
|
||||||
&mut mesh,
|
} else {
|
||||||
faces_to_make(self, pos, true, |vox| vox.is_empty()),
|
0.0
|
||||||
offs + pos.map(|e| e as f32),
|
|
||||||
&[[[Rgba::from_opaque(col); 3]; 3]; 3],
|
|
||||||
|origin, norm, col, light, ao, _meta| {
|
|
||||||
SpriteVertex::new(
|
|
||||||
origin * scale,
|
|
||||||
norm,
|
|
||||||
linear_to_srgb(srgb_to_linear(col) * light),
|
|
||||||
ao,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
&{
|
|
||||||
let mut ls = [[[None; 3]; 3]; 3];
|
|
||||||
for x in 0..3 {
|
|
||||||
for y in 0..3 {
|
|
||||||
for z in 0..3 {
|
|
||||||
ls[z][y][x] = self
|
|
||||||
.get(pos + Vec3::new(x as i32, y as i32, z as i32) - 1)
|
|
||||||
.map(|v| v.is_empty())
|
|
||||||
.unwrap_or(true)
|
|
||||||
.then_some(1.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ls
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
let get_color = |vol: &mut V, pos: Vec3<i32>| {
|
||||||
|
vol.get(pos)
|
||||||
|
.ok()
|
||||||
|
.and_then(|vox| vox.get_color())
|
||||||
|
.unwrap_or(Rgb::zero())
|
||||||
|
};
|
||||||
|
let get_opacity =
|
||||||
|
|vol: &mut V, pos: Vec3<i32>| vol.get(pos).map(|vox| vox.is_empty()).unwrap_or(true);
|
||||||
|
let should_draw = |vol: &mut V, pos: Vec3<i32>, delta: Vec3<i32>, uv| {
|
||||||
|
should_draw_greedy_ao(vertical_stripes, pos, delta, uv, |vox| {
|
||||||
|
vol.get(vox).map(|vox| *vox).unwrap_or(Vox::empty())
|
||||||
|
})
|
||||||
|
};
|
||||||
|
// NOTE: Conversion to f32 is fine since this i32 is actually in bounds for u16.
|
||||||
|
// let create_shadow = |pos, norm, _meta| ShadowVertex::new_figure((pos + offs)
|
||||||
|
// * scale, norm, 0);
|
||||||
|
let create_opaque = |atlas_pos, pos: Vec3<f32>, norm, _meta| {
|
||||||
|
/* if pos.x >= 15.0 || pos.y >= 15.0 || pos.z >= 63.0 {
|
||||||
|
println!("{:?}", pos);
|
||||||
|
} */
|
||||||
|
SpriteVertex::new(atlas_pos, pos, norm /* , ao */)
|
||||||
|
};
|
||||||
|
|
||||||
(mesh, Mesh::new(), Mesh::new())
|
let mut opaque_mesh = Mesh::new();
|
||||||
|
let _bounds = greedy.push(
|
||||||
|
self,
|
||||||
|
draw_delta,
|
||||||
|
greedy_size,
|
||||||
|
greedy_size_cross,
|
||||||
|
get_light,
|
||||||
|
get_color,
|
||||||
|
get_opacity,
|
||||||
|
should_draw,
|
||||||
|
|atlas_origin, dim, origin, draw_dim, norm, meta| {
|
||||||
|
opaque_mesh.push_quad(greedy::create_quad(
|
||||||
|
atlas_origin,
|
||||||
|
dim,
|
||||||
|
origin,
|
||||||
|
draw_dim,
|
||||||
|
norm,
|
||||||
|
meta,
|
||||||
|
|atlas_pos, pos, norm, &meta| create_opaque(atlas_pos, pos, norm, meta),
|
||||||
|
));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
(opaque_mesh, Mesh::new(), Mesh::new(), ())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn should_draw_greedy(
|
||||||
|
pos: Vec3<i32>,
|
||||||
|
delta: Vec3<i32>,
|
||||||
|
_uv: Vec2<Vec3<i32>>,
|
||||||
|
flat_get: impl Fn(Vec3<i32>) -> Cell,
|
||||||
|
) -> Option<(bool, /* u8 */ ())> {
|
||||||
|
// TODO: Verify conversion.
|
||||||
|
// let pos = pos.map(|e| e as i32) + draw_delta; // - delta;
|
||||||
|
let from = flat_get(pos - delta); // map(|v| v.is_opaque()).unwrap_or(false);
|
||||||
|
let to = flat_get(pos); //map(|v| v.is_opaque()).unwrap_or(false);
|
||||||
|
let from_opaque = !from.is_empty();
|
||||||
|
if from_opaque == !to.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
// If going from transparent to opaque, backward facing; otherwise, forward
|
||||||
|
// facing.
|
||||||
|
Some((from_opaque, ()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Use the 6 voxels/blocks surrounding the one at the specified position
|
fn should_draw_greedy_ao(
|
||||||
/// to detemine which faces should be drawn
|
vertical_stripes: bool,
|
||||||
fn faces_to_make<V: ReadVol>(
|
|
||||||
seg: &V,
|
|
||||||
pos: Vec3<i32>,
|
pos: Vec3<i32>,
|
||||||
error_makes_face: bool,
|
delta: Vec3<i32>,
|
||||||
should_add: impl Fn(&V::Vox) -> bool,
|
_uv: Vec2<Vec3<i32>>,
|
||||||
) -> [Option<()>; 6] {
|
flat_get: impl Fn(Vec3<i32>) -> Cell,
|
||||||
let (x, y, z) = (Vec3::unit_x(), Vec3::unit_y(), Vec3::unit_z());
|
) -> Option<(bool, /* u8 */ bool)> {
|
||||||
let make_face = |offset| {
|
// TODO: Verify conversion.
|
||||||
let res = seg
|
// let pos = pos.map(|e| e as i32) + draw_delta; // - delta;
|
||||||
.get(pos + offset)
|
let from = flat_get(pos - delta); // map(|v| v.is_opaque()).unwrap_or(false);
|
||||||
.map(|v| should_add(v))
|
let to = flat_get(pos); //map(|v| v.is_opaque()).unwrap_or(false);
|
||||||
.unwrap_or(error_makes_face);
|
let from_opaque = !from.is_empty();
|
||||||
if res { Some(()) } else { None }
|
if from_opaque == !to.is_empty() {
|
||||||
};
|
None
|
||||||
[
|
} else {
|
||||||
make_face(-x),
|
let faces_forward = from_opaque;
|
||||||
make_face(x),
|
let ao = /* if delta.z != 0 {
|
||||||
make_face(-y),
|
0u8
|
||||||
make_face(y),
|
} else {
|
||||||
make_face(-z),
|
(pos.z & 1) as u8
|
||||||
make_face(z),
|
// (((pos.x & 1) as u8) << 1) | (pos.y & 1) as u8
|
||||||
]
|
}*/!vertical_stripes || /*((pos.x & 1) ^ (pos.y & 1))*/(pos.z & 1) != 0/* as u8*/;
|
||||||
|
/* let (from, delta, uv) = if faces_forward {
|
||||||
|
(pos - delta - uv.x - uv.y, delta, uv)
|
||||||
|
} else {
|
||||||
|
(pos, -delta, Vec2::new(-uv.y, -uv.x))
|
||||||
|
};
|
||||||
|
let ao_vertex = |from: Vec3<i32>, delta: Vec3<i32>, uv: Vec2<Vec3<i32>>| {
|
||||||
|
let corner = !flat_get(from + delta - uv.x - uv.y).is_empty();
|
||||||
|
let s1 = !flat_get(from + delta - uv.x).is_empty();
|
||||||
|
let s2 = !flat_get(from + delta - uv.y).is_empty();
|
||||||
|
if s1 && s2 {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
3 - (if corner { 1 } else { 0 } + if s1 { 1 } else { 0 } + if s2 { 1 } else { 0 })
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// We only care about the vertices we are *not* merging, since the shared vertices
|
||||||
|
// by definition have the same AO values. But snce we go both down and right we end up
|
||||||
|
// needing all but the bottom right vertex.
|
||||||
|
let ao_corner = ao_vertex(from, delta, uv);
|
||||||
|
let ao1 = ao_vertex(from + uv.x, delta, uv);
|
||||||
|
let ao2 = ao_vertex(from + uv.y, delta, uv);
|
||||||
|
let ao3 = ao_vertex(from + uv.x + uv.y, delta, uv);
|
||||||
|
// NOTE: ao's 4 values correspond (from 0 to 3) to 0.25, 0.5, 0.75, 1.0.
|
||||||
|
//
|
||||||
|
// 0.0 is the None case.
|
||||||
|
let ao = (ao_corner << 6) | (ao1 << 4) | (ao2 << 2) | ao3; */
|
||||||
|
// let ao = ao_vertex(from, delta, uv);
|
||||||
|
// If going from transparent to opaque, backward facing; otherwise, forward
|
||||||
|
// facing.
|
||||||
|
Some((faces_forward, ao))
|
||||||
|
// Some((faces_forward, ()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
mesh::{vol, Meshable},
|
mesh::{
|
||||||
render::{self, mesh::Quad, FluidPipeline, Mesh, ShadowPipeline, TerrainPipeline},
|
greedy::{self, GreedyMesh},
|
||||||
|
Meshable,
|
||||||
|
},
|
||||||
|
render::{self, ColLightInfo, FluidPipeline, Mesh, ShadowPipeline, TerrainPipeline},
|
||||||
};
|
};
|
||||||
use common::{
|
use common::{
|
||||||
terrain::{Block, BlockKind},
|
terrain::{Block, BlockKind},
|
||||||
@ -12,7 +15,16 @@ use vek::*;
|
|||||||
|
|
||||||
type TerrainVertex = <TerrainPipeline as render::Pipeline>::Vertex;
|
type TerrainVertex = <TerrainPipeline as render::Pipeline>::Vertex;
|
||||||
type FluidVertex = <FluidPipeline as render::Pipeline>::Vertex;
|
type FluidVertex = <FluidPipeline as render::Pipeline>::Vertex;
|
||||||
type ShadowVertex = <ShadowPipeline as render::Pipeline>::Vertex;
|
|
||||||
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
|
enum FaceKind {
|
||||||
|
/// Opaque face that is facing something non-opaque; either
|
||||||
|
/// water (Opaque(true)) or something else (Opaque(false)).
|
||||||
|
Opaque(bool),
|
||||||
|
/// Fluid face that is facing something non-opaque, non-tangible,
|
||||||
|
/// and non-fluid (most likely air).
|
||||||
|
Fluid,
|
||||||
|
}
|
||||||
|
|
||||||
trait Blendable {
|
trait Blendable {
|
||||||
fn is_blended(&self) -> bool;
|
fn is_blended(&self) -> bool;
|
||||||
@ -200,20 +212,22 @@ fn calc_light<V: RectRasterableVol<Vox = Block> + ReadVol + Debug>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug>
|
impl<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug>
|
||||||
Meshable<'a, TerrainPipeline, FluidPipeline> for VolGrid2d<V>
|
Meshable<TerrainPipeline, FluidPipeline> for &'a VolGrid2d<V>
|
||||||
{
|
{
|
||||||
type Pipeline = TerrainPipeline;
|
type Pipeline = TerrainPipeline;
|
||||||
|
type Result = (Aabb<f32>, ColLightInfo);
|
||||||
type ShadowPipeline = ShadowPipeline;
|
type ShadowPipeline = ShadowPipeline;
|
||||||
type Supplement = Aabb<i32>;
|
type Supplement = (Aabb<i32>, Vec2<u16>);
|
||||||
type TranslucentPipeline = FluidPipeline;
|
type TranslucentPipeline = FluidPipeline;
|
||||||
|
|
||||||
fn generate_mesh(
|
fn generate_mesh(
|
||||||
&'a self,
|
self,
|
||||||
range: Self::Supplement,
|
(range, max_texture_size): Self::Supplement,
|
||||||
) -> (
|
) -> (
|
||||||
Mesh<Self::Pipeline>,
|
Mesh<Self::Pipeline>,
|
||||||
Mesh<Self::TranslucentPipeline>,
|
Mesh<Self::TranslucentPipeline>,
|
||||||
Mesh<Self::ShadowPipeline>,
|
Mesh<Self::ShadowPipeline>,
|
||||||
|
Self::Result,
|
||||||
) {
|
) {
|
||||||
let mut light = calc_light(range, self);
|
let mut light = calc_light(range, self);
|
||||||
|
|
||||||
@ -262,7 +276,7 @@ impl<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug>
|
|||||||
let z = z + 1;
|
let z = z + 1;
|
||||||
match flat.get((x * h * d + y * d + z) as usize).copied() {
|
match flat.get((x * h * d + y * d + z) as usize).copied() {
|
||||||
Some(b) => b,
|
Some(b) => b,
|
||||||
None => panic!("x {} y {} z {} d {} h {}"),
|
None => panic!("x {} y {} z {} d {} h {}", x, y, z, d, h),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -298,10 +312,10 @@ impl<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug>
|
|||||||
// similar z // levels together (better rendering performance)
|
// similar z // levels together (better rendering performance)
|
||||||
// let mut opaque_meshes = vec![Mesh::new(); ((z_end + 1 - z_start).clamped(1,
|
// let mut opaque_meshes = vec![Mesh::new(); ((z_end + 1 - z_start).clamped(1,
|
||||||
// 60) as usize / 10).max(1)];
|
// 60) as usize / 10).max(1)];
|
||||||
let mut opaque_mesh = Mesh::new();
|
// let mut opaque_mesh = Mesh::new();
|
||||||
let mut fluid_mesh = Mesh::new();
|
// let mut fluid_mesh = Mesh::new();
|
||||||
|
|
||||||
for x in 1..range.size().w - 1 {
|
/* for x in 1..range.size().w - 1 {
|
||||||
for y in 1..range.size().w - 1 {
|
for y in 1..range.size().w - 1 {
|
||||||
let mut blocks = [[[None; 3]; 3]; 3];
|
let mut blocks = [[[None; 3]; 3]; 3];
|
||||||
for i in 0..3 {
|
for i in 0..3 {
|
||||||
@ -398,7 +412,7 @@ impl<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug>
|
|||||||
// + 1 - z_start).max(1)) as usize; let selected_opaque_mesh
|
// + 1 - z_start).max(1)) as usize; let selected_opaque_mesh
|
||||||
// = &mut opaque_meshes[opaque_mesh_index]; Create mesh
|
// = &mut opaque_meshes[opaque_mesh_index]; Create mesh
|
||||||
// polygons
|
// polygons
|
||||||
if block.map_or(false, |vox| vox.is_opaque()) {
|
/* if block.map_or(false, |vox| vox.is_opaque()) {
|
||||||
vol::push_vox_verts(
|
vol::push_vox_verts(
|
||||||
&mut opaque_mesh, //selected_opaque_mesh,
|
&mut opaque_mesh, //selected_opaque_mesh,
|
||||||
faces_to_make(&blocks, None, |vox| {
|
faces_to_make(&blocks, None, |vox| {
|
||||||
@ -425,7 +439,7 @@ impl<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug>
|
|||||||
},
|
},
|
||||||
&lights,
|
&lights,
|
||||||
);
|
);
|
||||||
} else if block.map_or(false, |vox| vox.is_fluid()) {
|
} else */if block.map_or(false, |vox| vox.is_fluid()) {
|
||||||
vol::push_vox_verts(
|
vol::push_vox_verts(
|
||||||
&mut fluid_mesh,
|
&mut fluid_mesh,
|
||||||
// NOTE: want to skip blocks that aren't either next to air, or next to
|
// NOTE: want to skip blocks that aren't either next to air, or next to
|
||||||
@ -455,7 +469,7 @@ impl<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// let opaque_mesh = opaque_meshes
|
// let opaque_mesh = opaque_meshes
|
||||||
// .into_iter()
|
// .into_iter()
|
||||||
@ -468,286 +482,121 @@ impl<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug>
|
|||||||
// });
|
// });
|
||||||
// opaque_mesh
|
// opaque_mesh
|
||||||
// });
|
// });
|
||||||
|
let max_size =
|
||||||
let mut shadow_mesh = Mesh::new();
|
guillotiere::Size::new(i32::from(max_texture_size.x), i32::from(max_texture_size.y));
|
||||||
|
let greedy_size = Vec3::new(
|
||||||
let x_size = (range.size().w - 2) as usize;
|
(range.size().w - 2) as usize,
|
||||||
let y_size = (range.size().h - 2) as usize;
|
(range.size().h - 2) as usize,
|
||||||
let z_size = (z_end - z_start + 1) as usize;
|
(z_end - z_start + 1) as usize,
|
||||||
|
);
|
||||||
|
let greedy_size_cross = Vec3::new(greedy_size.x - 1, greedy_size.y - 1, greedy_size.z);
|
||||||
let draw_delta = Vec3::new(1, 1, z_start);
|
let draw_delta = Vec3::new(1, 1, z_start);
|
||||||
let mesh_delta = Vec3::new(0, 0, z_start + range.min.z);
|
|
||||||
|
|
||||||
// x (u = y, v = z)
|
let get_light = |_: &mut (), pos: Vec3<i32>| light(pos + range.min);
|
||||||
greedy_mesh_cross_section(
|
let get_color =
|
||||||
Vec3::new(y_size, z_size, x_size - 1),
|
|_: &mut (), pos: Vec3<i32>| flat_get(pos).get_color().unwrap_or(Rgb::zero());
|
||||||
|pos| {
|
let get_opacity = |_: &mut (), pos: Vec3<i32>| !flat_get(pos).is_opaque();
|
||||||
should_draw_greedy(
|
let should_draw = |_: &mut (), pos: Vec3<i32>, delta: Vec3<i32>, _uv| {
|
||||||
Vec3::new(pos.z, pos.x, pos.y),
|
should_draw_greedy(pos, delta, |pos| flat_get(pos))
|
||||||
draw_delta,
|
};
|
||||||
Vec3::unit_x(), /* , pos.z, 0, x_size */
|
// NOTE: Conversion to f32 is fine since this i32 is actually in bounds for u16.
|
||||||
|pos| flat_get(pos),
|
// let create_shadow = |pos, norm, meta| ShadowVertex::new(pos + Vec3::new(0.0,
|
||||||
)
|
// 0.0, (z_start + range.min.z) as f32), norm, meta);
|
||||||
},
|
let mesh_delta = Vec3::new(0.0, 0.0, (z_start + range.min.z) as f32);
|
||||||
|pos, dim, faces_forward| {
|
let create_opaque = |atlas_pos, pos, norm, meta| {
|
||||||
shadow_mesh.push_quad(create_quad_greedy(
|
TerrainVertex::new(atlas_pos, pos + mesh_delta, norm, meta)
|
||||||
Vec3::new(pos.z, pos.x, pos.y),
|
};
|
||||||
mesh_delta,
|
let create_transparent =
|
||||||
dim,
|
|_atlas_pos, pos, norm, _meta| FluidVertex::new(pos + mesh_delta, norm);
|
||||||
Vec2::new(Vec3::unit_y(), Vec3::unit_z()),
|
|
||||||
Vec3::unit_x(),
|
let mut greedy = GreedyMesh::new(max_size);
|
||||||
faces_forward,
|
let mut opaque_mesh = Mesh::new();
|
||||||
));
|
let mut fluid_mesh = Mesh::new();
|
||||||
|
let bounds = greedy.push(
|
||||||
|
(),
|
||||||
|
draw_delta,
|
||||||
|
greedy_size,
|
||||||
|
greedy_size_cross,
|
||||||
|
get_light,
|
||||||
|
get_color,
|
||||||
|
get_opacity,
|
||||||
|
should_draw,
|
||||||
|
|atlas_origin, dim, origin, draw_dim, norm, meta| match meta {
|
||||||
|
FaceKind::Opaque(meta) => {
|
||||||
|
opaque_mesh.push_quad(greedy::create_quad(
|
||||||
|
atlas_origin,
|
||||||
|
dim,
|
||||||
|
origin,
|
||||||
|
draw_dim,
|
||||||
|
norm,
|
||||||
|
meta,
|
||||||
|
|atlas_pos, pos, norm, &meta| create_opaque(atlas_pos, pos, norm, meta),
|
||||||
|
));
|
||||||
|
},
|
||||||
|
FaceKind::Fluid => {
|
||||||
|
fluid_mesh.push_quad(greedy::create_quad(
|
||||||
|
atlas_origin,
|
||||||
|
dim,
|
||||||
|
origin,
|
||||||
|
draw_dim,
|
||||||
|
norm,
|
||||||
|
&(),
|
||||||
|
|atlas_pos, pos, norm, &meta| {
|
||||||
|
create_transparent(atlas_pos, pos, norm, meta)
|
||||||
|
},
|
||||||
|
));
|
||||||
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
// y (u = z, v = x)
|
let bounds = bounds.map(f32::from);
|
||||||
greedy_mesh_cross_section(
|
let bounds = Aabb {
|
||||||
Vec3::new(z_size, x_size, y_size - 1),
|
min: bounds.min + mesh_delta,
|
||||||
|pos| {
|
max: bounds.max + mesh_delta,
|
||||||
should_draw_greedy(
|
};
|
||||||
Vec3::new(pos.y, pos.z, pos.x),
|
let (col_lights, col_lights_size) = greedy.finalize();
|
||||||
draw_delta,
|
// println!("z_bounds{:?}, bounds: {:?}", (mesh_delta.z, mesh_delta.z +
|
||||||
Vec3::unit_y(),
|
|
||||||
|pos| flat_get(pos),
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|pos, dim, faces_forward| {
|
|
||||||
shadow_mesh.push_quad(create_quad_greedy(
|
|
||||||
Vec3::new(pos.y, pos.z, pos.x),
|
|
||||||
mesh_delta,
|
|
||||||
dim,
|
|
||||||
Vec2::new(Vec3::unit_z(), Vec3::unit_x()),
|
|
||||||
Vec3::unit_y(),
|
|
||||||
faces_forward,
|
|
||||||
));
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
// z (u = x, v = y)
|
(
|
||||||
greedy_mesh_cross_section(
|
opaque_mesh,
|
||||||
Vec3::new(x_size, y_size, z_size),
|
fluid_mesh,
|
||||||
|pos| {
|
Mesh::new(),
|
||||||
if pos.z == 0 {
|
(bounds, (col_lights, col_lights_size)),
|
||||||
let pos = pos.map(|e| e as i32) + draw_delta; // - delta;
|
)
|
||||||
let to = flat_get(pos).is_opaque(); //map(|v| v.is_opaque()).unwrap_or(false);
|
|
||||||
if to { Some(false) } else { None }
|
|
||||||
} else {
|
|
||||||
should_draw_greedy(
|
|
||||||
Vec3::new(pos.x, pos.y, pos.z),
|
|
||||||
draw_delta,
|
|
||||||
Vec3::unit_z(),
|
|
||||||
|pos| flat_get(pos),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|pos, dim, faces_forward| {
|
|
||||||
shadow_mesh.push_quad(create_quad_greedy(
|
|
||||||
Vec3::new(pos.x, pos.y, pos.z),
|
|
||||||
mesh_delta,
|
|
||||||
dim,
|
|
||||||
Vec2::new(Vec3::unit_x(), Vec3::unit_y()),
|
|
||||||
Vec3::unit_z(),
|
|
||||||
faces_forward,
|
|
||||||
));
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
(opaque_mesh, fluid_mesh, shadow_mesh)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Use the 6 voxels/blocks surrounding the center
|
|
||||||
/// to detemine which faces should be drawn
|
|
||||||
/// Unlike the one in segments.rs this uses a provided array of blocks instead
|
|
||||||
/// of retrieving from a volume
|
|
||||||
/// blocks[z][y][x]
|
|
||||||
fn faces_to_make<M: Clone>(
|
|
||||||
blocks: &[[[Option<Block>; 3]; 3]; 3],
|
|
||||||
error_makes_face: Option<M>,
|
|
||||||
should_add: impl Fn(Block) -> Option<M>,
|
|
||||||
) -> [Option<M>; 6] {
|
|
||||||
// Faces to draw
|
|
||||||
let make_face = |opt_v: Option<Block>| {
|
|
||||||
opt_v
|
|
||||||
.map(|v| should_add(v))
|
|
||||||
.unwrap_or(error_makes_face.clone())
|
|
||||||
};
|
|
||||||
[
|
|
||||||
make_face(blocks[1][1][0]),
|
|
||||||
make_face(blocks[1][1][2]),
|
|
||||||
make_face(blocks[1][0][1]),
|
|
||||||
make_face(blocks[1][2][1]),
|
|
||||||
make_face(blocks[0][1][1]),
|
|
||||||
make_face(blocks[2][1][1]),
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
// Greedy meshing.
|
|
||||||
fn greedy_mesh_cross_section(
|
|
||||||
/* mask: &mut [bool], */
|
|
||||||
dims: Vec3<usize>,
|
|
||||||
// Should we draw a face here (below this vertex)? If so, is it front or back facing?
|
|
||||||
draw_face: impl Fn(Vec3<usize>) -> Option<bool>,
|
|
||||||
// Vertex, width and height, and whether it's front facing (face is implicit from the cross
|
|
||||||
// section).
|
|
||||||
mut push_quads: impl FnMut(Vec3<usize>, Vec2<usize>, bool),
|
|
||||||
) {
|
|
||||||
// mask represents which faces are either set while the other is unset, or unset
|
|
||||||
// while the other is set.
|
|
||||||
let mut mask = vec![None; dims.y * dims.x];
|
|
||||||
(0..dims.z + 1).for_each(|d| {
|
|
||||||
// Compute mask
|
|
||||||
mask.iter_mut().enumerate().for_each(|(posi, mask)| {
|
|
||||||
let i = posi % dims.x;
|
|
||||||
let j = posi / dims.x;
|
|
||||||
*mask = draw_face(Vec3::new(i, j, d));
|
|
||||||
});
|
|
||||||
|
|
||||||
(0..dims.y).for_each(|j| {
|
|
||||||
let mut i = 0;
|
|
||||||
while i < dims.x {
|
|
||||||
// Compute width (number of set x bits for this row and layer, starting at the
|
|
||||||
// current minimum column).
|
|
||||||
if let Some(ori) = mask[j * dims.x + i] {
|
|
||||||
let width = 1 + mask[j * dims.x + i + 1..j * dims.x + dims.x]
|
|
||||||
.iter()
|
|
||||||
.take_while(move |&&mask| mask == Some(ori))
|
|
||||||
.count();
|
|
||||||
let max_x = i + width;
|
|
||||||
// Compute height (number of rows having w set x bits for this layer, starting
|
|
||||||
// at the current minimum column and row).
|
|
||||||
let height = 1
|
|
||||||
+ (j + 1..dims.y)
|
|
||||||
.take_while(|h| {
|
|
||||||
mask[h * dims.x + i..h * dims.x + max_x]
|
|
||||||
.iter()
|
|
||||||
.all(|&mask| mask == Some(ori))
|
|
||||||
})
|
|
||||||
.count();
|
|
||||||
let max_y = j + height;
|
|
||||||
// Add quad.
|
|
||||||
push_quads(Vec3::new(i, j, d /* + 1 */), Vec2::new(width, height), ori);
|
|
||||||
// Unset mask bits in drawn region, so we don't try to re-draw them.
|
|
||||||
(j..max_y).for_each(|l| {
|
|
||||||
mask[l * dims.x + i..l * dims.x + max_x]
|
|
||||||
.iter_mut()
|
|
||||||
.for_each(|mask| {
|
|
||||||
*mask = None;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
// Update x value.
|
|
||||||
i = max_x;
|
|
||||||
} else {
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn create_quad_greedy(
|
|
||||||
origin: Vec3<usize>,
|
|
||||||
mesh_delta: Vec3<i32>,
|
|
||||||
dim: Vec2<usize>,
|
|
||||||
uv: Vec2<Vec3<f32>>,
|
|
||||||
norm: Vec3<f32>,
|
|
||||||
faces_forward: bool,
|
|
||||||
) -> Quad<ShadowPipeline> {
|
|
||||||
let origin = (origin.map(|e| e as i32) + mesh_delta).map(|e| e as f32);
|
|
||||||
let dim = uv.map2(dim.map(|e| e as f32), |e, f| e * f);
|
|
||||||
let (dim, norm) = if faces_forward {
|
|
||||||
(dim, norm)
|
|
||||||
} else {
|
|
||||||
(Vec2::new(dim.y, dim.x), -norm)
|
|
||||||
};
|
|
||||||
Quad::new(
|
|
||||||
ShadowVertex::new(origin, norm),
|
|
||||||
ShadowVertex::new(origin + dim.x, norm),
|
|
||||||
ShadowVertex::new(origin + dim.x + dim.y, norm),
|
|
||||||
ShadowVertex::new(origin + dim.y, norm),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn should_draw_greedy(
|
fn should_draw_greedy(
|
||||||
pos: Vec3<usize>,
|
pos: Vec3<i32>,
|
||||||
draw_delta: Vec3<i32>,
|
|
||||||
delta: Vec3<i32>,
|
delta: Vec3<i32>,
|
||||||
flat_get: impl Fn(Vec3<i32>) -> Block,
|
flat_get: impl Fn(Vec3<i32>) -> Block,
|
||||||
) -> Option<bool> {
|
) -> Option<(bool, FaceKind)> {
|
||||||
let pos = pos.map(|e| e as i32) + draw_delta; // - delta;
|
// TODO: Verify conversion.
|
||||||
let from = flat_get(pos - delta).is_opaque(); // map(|v| v.is_opaque()).unwrap_or(false);
|
// let pos = pos.map(|e| e as i32) + draw_delta; // - delta;
|
||||||
let to = flat_get(pos).is_opaque(); //map(|v| v.is_opaque()).unwrap_or(false);
|
let from = flat_get(pos - delta); // map(|v| v.is_opaque()).unwrap_or(false);
|
||||||
if from == to {
|
let to = flat_get(pos); //map(|v| v.is_opaque()).unwrap_or(false);
|
||||||
None
|
let from_opaque = from.is_opaque();
|
||||||
} else {
|
if from_opaque == to.is_opaque() {
|
||||||
// If going from transparent to opaque, forward facing; otherwise, backward
|
// Check the interface of fluid and non-tangible non-fluids (e.g. air).
|
||||||
// facing.
|
let from_fluid = from.is_fluid();
|
||||||
Some(from)
|
if from_fluid == to.is_fluid() || from.is_tangible() || to.is_tangible() {
|
||||||
}
|
None
|
||||||
}
|
} else {
|
||||||
|
// While fluid is not culled, we still try to keep a consistent orientation as
|
||||||
/*
|
// we do for land; if going from fluid to non-fluid,
|
||||||
impl<V: BaseVol<Vox = Block> + ReadVol + Debug> Meshable for VolGrid3d<V> {
|
// forwards-facing; otherwise, backwards-facing.
|
||||||
type Pipeline = TerrainPipeline;
|
Some((from_fluid, FaceKind::Fluid))
|
||||||
type Supplement = Aabb<i32>;
|
|
||||||
|
|
||||||
fn generate_mesh(&self, range: Self::Supplement) -> Mesh<Self::Pipeline> {
|
|
||||||
let mut mesh = Mesh::new();
|
|
||||||
|
|
||||||
let mut last_chunk_pos = self.pos_key(range.min);
|
|
||||||
let mut last_chunk = self.get_key(last_chunk_pos);
|
|
||||||
|
|
||||||
let size = range.max - range.min;
|
|
||||||
for x in 1..size.x - 1 {
|
|
||||||
for y in 1..size.y - 1 {
|
|
||||||
for z in 1..size.z - 1 {
|
|
||||||
let pos = Vec3::new(x, y, z);
|
|
||||||
|
|
||||||
let new_chunk_pos = self.pos_key(range.min + pos);
|
|
||||||
if last_chunk_pos != new_chunk_pos {
|
|
||||||
last_chunk = self.get_key(new_chunk_pos);
|
|
||||||
last_chunk_pos = new_chunk_pos;
|
|
||||||
}
|
|
||||||
let offs = pos.map(|e| e as f32 - 1.0);
|
|
||||||
if let Some(chunk) = last_chunk {
|
|
||||||
let chunk_pos = Self::chunk_offs(range.min + pos);
|
|
||||||
if let Some(col) = chunk.get(chunk_pos).ok().and_then(|vox| vox.get_color())
|
|
||||||
{
|
|
||||||
let col = col.map(|e| e as f32 / 255.0);
|
|
||||||
|
|
||||||
vol::push_vox_verts(
|
|
||||||
&mut mesh,
|
|
||||||
self,
|
|
||||||
range.min + pos,
|
|
||||||
offs,
|
|
||||||
col,
|
|
||||||
TerrainVertex::new,
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if let Some(col) = self
|
|
||||||
.get(range.min + pos)
|
|
||||||
.ok()
|
|
||||||
.and_then(|vox| vox.get_color())
|
|
||||||
{
|
|
||||||
let col = col.map(|e| e as f32 / 255.0);
|
|
||||||
|
|
||||||
vol::push_vox_verts(
|
|
||||||
&mut mesh,
|
|
||||||
self,
|
|
||||||
range.min + pos,
|
|
||||||
offs,
|
|
||||||
col,
|
|
||||||
TerrainVertex::new,
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
mesh
|
} else {
|
||||||
|
// If going from transparent to opaque, backward facing; otherwise, forward
|
||||||
|
// facing. Also, if either from or to is fluid, set the meta accordingly.
|
||||||
|
Some((
|
||||||
|
from_opaque,
|
||||||
|
FaceKind::Opaque(if from_opaque {
|
||||||
|
to.is_fluid()
|
||||||
|
} else {
|
||||||
|
from.is_fluid()
|
||||||
|
}),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
@ -1,233 +0,0 @@
|
|||||||
use vek::*;
|
|
||||||
|
|
||||||
use crate::render::{
|
|
||||||
mesh::{Mesh, Quad},
|
|
||||||
Pipeline,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Given volume, position, and cardinal directions, compute each vertex's AO
|
|
||||||
/// value. `dirs` should be a slice of length 5 so that the sliding window of
|
|
||||||
/// size 2 over the slice yields each vertex' adjacent positions.
|
|
||||||
#[allow(unsafe_code)]
|
|
||||||
fn get_ao_quad(
|
|
||||||
shift: Vec3<i32>,
|
|
||||||
dirs: &[Vec3<i32>],
|
|
||||||
darknesses: &[[[Option<f32>; 3]; 3]; 3],
|
|
||||||
) -> Vec4<(f32, f32)> {
|
|
||||||
dirs.windows(2)
|
|
||||||
.map(|offs| {
|
|
||||||
let vox_opaque = |pos: Vec3<i32>| {
|
|
||||||
let pos = (pos + 1).map(|e| e as usize);
|
|
||||||
darknesses[pos.z][pos.y][pos.x].is_none()
|
|
||||||
};
|
|
||||||
|
|
||||||
let (s1, s2) = (
|
|
||||||
vox_opaque(shift + offs[0]),
|
|
||||||
vox_opaque(shift + offs[1]),
|
|
||||||
/*
|
|
||||||
vol.get(pos + shift + offs[0])
|
|
||||||
.map(&is_opaque)
|
|
||||||
.unwrap_or(false),
|
|
||||||
vol.get(pos + shift + offs[1])
|
|
||||||
.map(&is_opaque)
|
|
||||||
.unwrap_or(false),
|
|
||||||
*/
|
|
||||||
);
|
|
||||||
|
|
||||||
let mut darkness = 0.0;
|
|
||||||
let mut total = 0.0f32;
|
|
||||||
for x in 0..2 {
|
|
||||||
for y in 0..2 {
|
|
||||||
let dark_pos = shift + offs[0] * x + offs[1] * y + 1;
|
|
||||||
if let Some(dark) =
|
|
||||||
darknesses[dark_pos.z as usize][dark_pos.y as usize][dark_pos.x as usize]
|
|
||||||
{
|
|
||||||
darkness += dark;
|
|
||||||
total += 1.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let darkness = darkness / total.max(1.0);
|
|
||||||
|
|
||||||
(
|
|
||||||
darkness,
|
|
||||||
if s1 && s2 {
|
|
||||||
0.0
|
|
||||||
} else {
|
|
||||||
let corner = vox_opaque(shift + offs[0] + offs[1]);
|
|
||||||
// Map both 1 and 2 neighbors to 0.5 occlusion.
|
|
||||||
if s1 || s2 || corner { 0.4 } else { 1.0 }
|
|
||||||
},
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.collect::<Vec4<(f32, f32)>>()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(unsafe_code)]
|
|
||||||
fn get_col_quad(dirs: &[Vec3<i32>], cols: &[[[Rgba<u8>; 3]; 3]; 3]) -> Vec4<Rgb<f32>> {
|
|
||||||
dirs.windows(2)
|
|
||||||
.map(|offs| {
|
|
||||||
let primary_col = Rgb::from(cols[1][1][1]).map(|e: u8| e as f32);
|
|
||||||
let mut color = Rgb::zero();
|
|
||||||
let mut total = 0.0;
|
|
||||||
for x in 0..2 {
|
|
||||||
for y in 0..2 {
|
|
||||||
let col_pos = offs[0] * x + offs[1] * y + 1;
|
|
||||||
let col = unsafe {
|
|
||||||
cols.get_unchecked(col_pos.z as usize)
|
|
||||||
.get_unchecked(col_pos.y as usize)
|
|
||||||
.get_unchecked(col_pos.x as usize)
|
|
||||||
};
|
|
||||||
if col.a > 0 {
|
|
||||||
let col = Rgb::new(col.r, col.g, col.b).map(|e| e as f32);
|
|
||||||
if Vec3::<f32>::from(primary_col).distance_squared(Vec3::from(col))
|
|
||||||
< (0.025f32 * 256.0).powf(2.0)
|
|
||||||
{
|
|
||||||
color += col;
|
|
||||||
total += 256.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
color / total
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Utility function
|
|
||||||
fn create_quad<P: Pipeline, M, F: Fn(Vec3<f32>, Vec3<f32>, Rgb<f32>, f32, f32, &M) -> P::Vertex>(
|
|
||||||
origin: Vec3<f32>,
|
|
||||||
unit_x: Vec3<f32>,
|
|
||||||
unit_y: Vec3<f32>,
|
|
||||||
norm: Vec3<f32>,
|
|
||||||
cols: Vec4<Rgb<f32>>,
|
|
||||||
darkness_ao: Vec4<(f32, f32)>,
|
|
||||||
meta: &M,
|
|
||||||
vcons: &F,
|
|
||||||
) -> Quad<P> {
|
|
||||||
let darkness = darkness_ao.map(|e| e.0);
|
|
||||||
let ao = darkness_ao.map(|e| e.1);
|
|
||||||
|
|
||||||
let ao_map = ao;
|
|
||||||
|
|
||||||
if ao[0].min(ao[2]) < ao[1].min(ao[3]) {
|
|
||||||
Quad::new(
|
|
||||||
vcons(origin + unit_y, norm, cols[3], darkness[3], ao_map[3], meta),
|
|
||||||
vcons(origin, norm, cols[0], darkness[0], ao_map[0], meta),
|
|
||||||
vcons(origin + unit_x, norm, cols[1], darkness[1], ao_map[1], meta),
|
|
||||||
vcons(
|
|
||||||
origin + unit_x + unit_y,
|
|
||||||
norm,
|
|
||||||
cols[2],
|
|
||||||
darkness[2],
|
|
||||||
ao_map[2],
|
|
||||||
meta,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
Quad::new(
|
|
||||||
vcons(origin, norm, cols[0], darkness[0], ao_map[0], meta),
|
|
||||||
vcons(origin + unit_x, norm, cols[1], darkness[1], ao_map[1], meta),
|
|
||||||
vcons(
|
|
||||||
origin + unit_x + unit_y,
|
|
||||||
norm,
|
|
||||||
cols[2],
|
|
||||||
darkness[2],
|
|
||||||
ao_map[2],
|
|
||||||
meta,
|
|
||||||
),
|
|
||||||
vcons(origin + unit_y, norm, cols[3], darkness[3], ao_map[3], meta),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn push_vox_verts<P: Pipeline, M>(
|
|
||||||
mesh: &mut Mesh<P>,
|
|
||||||
faces: [Option<M>; 6],
|
|
||||||
offs: Vec3<f32>,
|
|
||||||
cols: &[[[Rgba<u8>; 3]; 3]; 3],
|
|
||||||
vcons: impl Fn(Vec3<f32>, Vec3<f32>, Rgb<f32>, f32, f32, &M) -> P::Vertex,
|
|
||||||
darknesses: &[[[Option<f32>; 3]; 3]; 3],
|
|
||||||
) {
|
|
||||||
let (x, y, z) = (Vec3::unit_x(), Vec3::unit_y(), Vec3::unit_z());
|
|
||||||
|
|
||||||
// -x
|
|
||||||
if let Some(meta) = &faces[0] {
|
|
||||||
mesh.push_quad(create_quad(
|
|
||||||
offs,
|
|
||||||
Vec3::unit_z(),
|
|
||||||
Vec3::unit_y(),
|
|
||||||
-Vec3::unit_x(),
|
|
||||||
get_col_quad(&[-z, -y, z, y, -z], cols),
|
|
||||||
get_ao_quad(-Vec3::unit_x(), &[-z, -y, z, y, -z], darknesses),
|
|
||||||
meta,
|
|
||||||
&vcons,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
// +x
|
|
||||||
if let Some(meta) = &faces[1] {
|
|
||||||
mesh.push_quad(create_quad(
|
|
||||||
offs + Vec3::unit_x(),
|
|
||||||
Vec3::unit_y(),
|
|
||||||
Vec3::unit_z(),
|
|
||||||
Vec3::unit_x(),
|
|
||||||
get_col_quad(&[-y, -z, y, z, -y], cols),
|
|
||||||
get_ao_quad(Vec3::unit_x(), &[-y, -z, y, z, -y], darknesses),
|
|
||||||
meta,
|
|
||||||
&vcons,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
// -y
|
|
||||||
if let Some(meta) = &faces[2] {
|
|
||||||
mesh.push_quad(create_quad(
|
|
||||||
offs,
|
|
||||||
Vec3::unit_x(),
|
|
||||||
Vec3::unit_z(),
|
|
||||||
-Vec3::unit_y(),
|
|
||||||
get_col_quad(&[-x, -z, x, z, -x], cols),
|
|
||||||
get_ao_quad(-Vec3::unit_y(), &[-x, -z, x, z, -x], darknesses),
|
|
||||||
meta,
|
|
||||||
&vcons,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
// +y
|
|
||||||
if let Some(meta) = &faces[3] {
|
|
||||||
mesh.push_quad(create_quad(
|
|
||||||
offs + Vec3::unit_y(),
|
|
||||||
Vec3::unit_z(),
|
|
||||||
Vec3::unit_x(),
|
|
||||||
Vec3::unit_y(),
|
|
||||||
get_col_quad(&[-z, -x, z, x, -z], cols),
|
|
||||||
get_ao_quad(Vec3::unit_y(), &[-z, -x, z, x, -z], darknesses),
|
|
||||||
meta,
|
|
||||||
&vcons,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
// -z
|
|
||||||
if let Some(meta) = &faces[4] {
|
|
||||||
mesh.push_quad(create_quad(
|
|
||||||
offs,
|
|
||||||
Vec3::unit_y(),
|
|
||||||
Vec3::unit_x(),
|
|
||||||
-Vec3::unit_z(),
|
|
||||||
get_col_quad(&[-y, -x, y, x, -y], cols),
|
|
||||||
get_ao_quad(-Vec3::unit_z(), &[-y, -x, y, x, -y], darknesses),
|
|
||||||
meta,
|
|
||||||
&vcons,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
// +z
|
|
||||||
if let Some(meta) = &faces[5] {
|
|
||||||
mesh.push_quad(create_quad(
|
|
||||||
offs + Vec3::unit_z(),
|
|
||||||
Vec3::unit_x(),
|
|
||||||
Vec3::unit_y(),
|
|
||||||
Vec3::unit_z(),
|
|
||||||
get_col_quad(&[-x, -y, x, y, -x], cols),
|
|
||||||
get_ao_quad(Vec3::unit_z(), &[-x, -y, x, y, -x], darknesses),
|
|
||||||
meta,
|
|
||||||
&vcons,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
@ -17,14 +17,24 @@ impl<T: Copy + gfx::traits::Pod> Consts<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* /// Create a new immutable `Const<T>`.
|
||||||
|
pub fn new_immutable(factory: &mut gfx_backend::Factory, data: &[T]) -> Result<gfx::handle::RawBuffer<T>, RenderError> {
|
||||||
|
Ok(Self {
|
||||||
|
ibuf: factory
|
||||||
|
.create_buffer_immutable_raw(gfx::memory::cast_slice(data), core::mem::size_of::<T>(), gfx::buffer::Role::Constant, gfx::memory::Bind::empty())
|
||||||
|
.map_err(|err| RenderError::BufferCreationError(err))?,
|
||||||
|
})
|
||||||
|
} */
|
||||||
|
|
||||||
/// Update the GPU-side value represented by this constant handle.
|
/// Update the GPU-side value represented by this constant handle.
|
||||||
pub fn update(
|
pub fn update(
|
||||||
&mut self,
|
&mut self,
|
||||||
encoder: &mut gfx::Encoder<gfx_backend::Resources, gfx_backend::CommandBuffer>,
|
encoder: &mut gfx::Encoder<gfx_backend::Resources, gfx_backend::CommandBuffer>,
|
||||||
vals: &[T],
|
vals: &[T],
|
||||||
|
offset: usize,
|
||||||
) -> Result<(), RenderError> {
|
) -> Result<(), RenderError> {
|
||||||
encoder
|
encoder
|
||||||
.update_buffer(&self.buf, vals, 0)
|
.update_buffer(&self.buf, vals, offset)
|
||||||
.map_err(|err| RenderError::UpdateError(err))
|
.map_err(|err| RenderError::UpdateError(err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ use std::iter::FromIterator;
|
|||||||
/// A `Vec`-based mesh structure used to store mesh data on the CPU.
|
/// A `Vec`-based mesh structure used to store mesh data on the CPU.
|
||||||
pub struct Mesh<P: Pipeline> {
|
pub struct Mesh<P: Pipeline> {
|
||||||
verts: Vec<P::Vertex>,
|
verts: Vec<P::Vertex>,
|
||||||
|
// textures: Vec<>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P: Pipeline> Clone for Mesh<P>
|
impl<P: Pipeline> Clone for Mesh<P>
|
||||||
|
@ -16,7 +16,10 @@ pub use self::{
|
|||||||
mesh::{Mesh, Quad, Tri},
|
mesh::{Mesh, Quad, Tri},
|
||||||
model::{DynamicModel, Model},
|
model::{DynamicModel, Model},
|
||||||
pipelines::{
|
pipelines::{
|
||||||
figure::{BoneData as FigureBoneData, FigurePipeline, Locals as FigureLocals},
|
figure::{
|
||||||
|
BoneData as FigureBoneData, BoneMeshes, FigureModel, FigurePipeline,
|
||||||
|
Locals as FigureLocals,
|
||||||
|
},
|
||||||
fluid::FluidPipeline,
|
fluid::FluidPipeline,
|
||||||
lod_terrain::{Locals as LodTerrainLocals, LodTerrainPipeline},
|
lod_terrain::{Locals as LodTerrainLocals, LodTerrainPipeline},
|
||||||
postprocess::{
|
postprocess::{
|
||||||
@ -24,7 +27,7 @@ pub use self::{
|
|||||||
},
|
},
|
||||||
shadow::{Locals as ShadowLocals, ShadowPipeline},
|
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, Locals as SpriteLocals, SpritePipeline},
|
||||||
terrain::{Locals as TerrainLocals, TerrainPipeline},
|
terrain::{Locals as TerrainLocals, TerrainPipeline},
|
||||||
ui::{
|
ui::{
|
||||||
create_quad as create_ui_quad, create_tri as create_ui_tri, Locals as UiLocals,
|
create_quad as create_ui_quad, create_tri as create_ui_tri, Locals as UiLocals,
|
||||||
@ -33,8 +36,8 @@ pub use self::{
|
|||||||
Globals, Light, Shadow,
|
Globals, Light, Shadow,
|
||||||
},
|
},
|
||||||
renderer::{
|
renderer::{
|
||||||
LodColorFmt, LodTextureFmt, Renderer, ShadowDepthStencilFmt, TgtColorFmt,
|
ColLightFmt, ColLightInfo, LodColorFmt, LodTextureFmt, Renderer, ShadowDepthStencilFmt,
|
||||||
TgtDepthStencilFmt, WinColorFmt, WinDepthFmt,
|
TgtColorFmt, TgtDepthStencilFmt, WinColorFmt, WinDepthFmt,
|
||||||
},
|
},
|
||||||
texture::Texture,
|
texture::Texture,
|
||||||
};
|
};
|
||||||
@ -72,6 +75,10 @@ pub enum AaMode {
|
|||||||
SsaaX4,
|
SsaaX4,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for AaMode {
|
||||||
|
fn default() -> Self { AaMode::Fxaa }
|
||||||
|
}
|
||||||
|
|
||||||
/// Cloud modes
|
/// Cloud modes
|
||||||
#[derive(PartialEq, Eq, Clone, Copy, Debug, Serialize, Deserialize)]
|
#[derive(PartialEq, Eq, Clone, Copy, Debug, Serialize, Deserialize)]
|
||||||
pub enum CloudMode {
|
pub enum CloudMode {
|
||||||
@ -79,6 +86,10 @@ pub enum CloudMode {
|
|||||||
Regular,
|
Regular,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for CloudMode {
|
||||||
|
fn default() -> Self { CloudMode::Regular }
|
||||||
|
}
|
||||||
|
|
||||||
/// Fluid modes
|
/// Fluid modes
|
||||||
#[derive(PartialEq, Eq, Clone, Copy, Debug, Serialize, Deserialize)]
|
#[derive(PartialEq, Eq, Clone, Copy, Debug, Serialize, Deserialize)]
|
||||||
pub enum FluidMode {
|
pub enum FluidMode {
|
||||||
@ -86,6 +97,10 @@ pub enum FluidMode {
|
|||||||
Shiny,
|
Shiny,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for FluidMode {
|
||||||
|
fn default() -> Self { FluidMode::Shiny }
|
||||||
|
}
|
||||||
|
|
||||||
/// Lighting modes
|
/// Lighting modes
|
||||||
#[derive(PartialEq, Eq, Clone, Copy, Debug, Serialize, Deserialize)]
|
#[derive(PartialEq, Eq, Clone, Copy, Debug, Serialize, Deserialize)]
|
||||||
pub enum LightingMode {
|
pub enum LightingMode {
|
||||||
@ -93,3 +108,30 @@ pub enum LightingMode {
|
|||||||
BlinnPhong,
|
BlinnPhong,
|
||||||
Lambertian,
|
Lambertian,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for LightingMode {
|
||||||
|
fn default() -> Self { LightingMode::BlinnPhong }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Shadow modes
|
||||||
|
#[derive(PartialEq, Eq, Clone, Copy, Debug, Serialize, Deserialize)]
|
||||||
|
pub enum ShadowMode {
|
||||||
|
None,
|
||||||
|
Cheap,
|
||||||
|
/// Multiple of resolution.
|
||||||
|
Map, /* (f32) */
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ShadowMode {
|
||||||
|
fn default() -> Self { ShadowMode::Cheap }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Render modes
|
||||||
|
#[derive(PartialEq, Eq, Clone, Copy, Debug, Default, Serialize, Deserialize)]
|
||||||
|
pub struct RenderMode {
|
||||||
|
pub aa: AaMode,
|
||||||
|
pub cloud: CloudMode,
|
||||||
|
pub fluid: FluidMode,
|
||||||
|
pub lighting: LightingMode,
|
||||||
|
pub shadow: ShadowMode,
|
||||||
|
}
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
use super::{
|
use super::{
|
||||||
super::{util::arr_to_mat, Pipeline, TgtColorFmt, TgtDepthStencilFmt},
|
super::{
|
||||||
Globals, Light, Shadow,
|
util::arr_to_mat, ColLightFmt, Mesh, Model, Pipeline, TerrainPipeline, Texture,
|
||||||
|
TgtColorFmt, TgtDepthStencilFmt,
|
||||||
|
},
|
||||||
|
shadow, Globals, Light, Shadow,
|
||||||
};
|
};
|
||||||
|
use crate::mesh::greedy::GreedyMesh;
|
||||||
use gfx::{
|
use gfx::{
|
||||||
self, gfx_constant_struct_meta, gfx_defines, gfx_impl_struct_meta, gfx_pipeline,
|
self, gfx_constant_struct_meta, gfx_defines, gfx_impl_struct_meta, gfx_pipeline,
|
||||||
gfx_pipeline_inner, gfx_vertex_struct_meta,
|
gfx_pipeline_inner, gfx_vertex_struct_meta, state::ColorMask,
|
||||||
state::{ColorMask, Comparison, Stencil, StencilOp},
|
|
||||||
};
|
};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
@ -22,15 +25,21 @@ gfx_defines! {
|
|||||||
constant Locals {
|
constant Locals {
|
||||||
model_mat: [[f32; 4]; 4] = "model_mat",
|
model_mat: [[f32; 4]; 4] = "model_mat",
|
||||||
model_col: [f32; 4] = "model_col",
|
model_col: [f32; 4] = "model_col",
|
||||||
|
atlas_offs: [i32; 4] = "atlas_offs",
|
||||||
|
model_pos: [f32; 3] = "model_pos",
|
||||||
flags: u32 = "flags",
|
flags: u32 = "flags",
|
||||||
}
|
}
|
||||||
|
|
||||||
constant BoneData {
|
constant BoneData {
|
||||||
bone_mat: [[f32; 4]; 4] = "bone_mat",
|
bone_mat: [[f32; 4]; 4] = "bone_mat",
|
||||||
|
normals_mat: [[f32; 4]; 4] = "normals_mat",
|
||||||
}
|
}
|
||||||
|
|
||||||
pipeline pipe {
|
pipeline pipe {
|
||||||
vbuf: gfx::VertexBuffer<Vertex> = (),
|
// vbuf: gfx::VertexBuffer<Vertex> = (),
|
||||||
|
vbuf: gfx::VertexBuffer<<TerrainPipeline as Pipeline>::Vertex> = (),
|
||||||
|
// abuf: gfx::VertexBuffer<<TerrainPipeline as Pipeline>::Vertex> = (),
|
||||||
|
col_lights: gfx::TextureSampler<[f32; 4]> = "t_col_light",
|
||||||
|
|
||||||
locals: gfx::ConstantBuffer<Locals> = "u_locals",
|
locals: gfx::ConstantBuffer<Locals> = "u_locals",
|
||||||
globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
||||||
@ -38,15 +47,20 @@ 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",
|
point_shadow_maps: gfx::TextureSampler<f32> = "t_point_shadow_maps",
|
||||||
|
directed_shadow_maps: gfx::TextureSampler<f32> = "t_directed_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",
|
||||||
|
|
||||||
noise: gfx::TextureSampler<f32> = "t_noise",
|
noise: gfx::TextureSampler<f32> = "t_noise",
|
||||||
|
|
||||||
|
// Shadow stuff
|
||||||
|
light_shadows: gfx::ConstantBuffer<shadow::Locals> = "u_light_shadows",
|
||||||
|
|
||||||
tgt_color: gfx::BlendTarget<TgtColorFmt> = ("tgt_color", ColorMask::all(), gfx::preset::blend::ALPHA),
|
tgt_color: gfx::BlendTarget<TgtColorFmt> = ("tgt_color", ColorMask::all(), gfx::preset::blend::ALPHA),
|
||||||
tgt_depth_stencil: gfx::DepthStencilTarget<TgtDepthStencilFmt> = (gfx::preset::depth::LESS_EQUAL_WRITE,Stencil::new(Comparison::Always,0xff,(StencilOp::Keep,StencilOp::Keep,StencilOp::Replace))),
|
tgt_depth_stencil: gfx::DepthTarget<TgtDepthStencilFmt> = gfx::preset::depth::LESS_EQUAL_WRITE,
|
||||||
|
// tgt_depth_stencil: gfx::DepthStencilTarget<TgtDepthStencilFmt> = (gfx::preset::depth::LESS_EQUAL_WRITE,Stencil::new(Comparison::Always,0xff,(StencilOp::Keep,StencilOp::Keep,StencilOp::Replace))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,30 +94,49 @@ impl Vertex {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Locals {
|
impl Locals {
|
||||||
pub fn new(model_mat: Mat4<f32>, col: Rgba<f32>, is_player: bool) -> Self {
|
pub fn new(
|
||||||
|
model_mat: Mat4<f32>,
|
||||||
|
col: Rgba<f32>,
|
||||||
|
pos: Vec3<f32>,
|
||||||
|
atlas_offs: Vec2<i32>,
|
||||||
|
is_player: bool,
|
||||||
|
) -> Self {
|
||||||
let mut flags = 0;
|
let mut flags = 0;
|
||||||
flags |= is_player as u32;
|
flags |= is_player as u32;
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
model_mat: arr_to_mat(model_mat.into_col_array()),
|
model_mat: arr_to_mat(model_mat.into_col_array()),
|
||||||
model_col: col.into_array(),
|
model_col: col.into_array(),
|
||||||
|
model_pos: pos.into_array(),
|
||||||
|
atlas_offs: Vec4::from(atlas_offs).into_array(),
|
||||||
flags,
|
flags,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Locals {
|
impl Default for Locals {
|
||||||
fn default() -> Self { Self::new(Mat4::identity(), Rgba::broadcast(1.0), false) }
|
fn default() -> Self {
|
||||||
|
Self::new(
|
||||||
|
Mat4::identity(),
|
||||||
|
Rgba::broadcast(1.0),
|
||||||
|
Vec3::default(),
|
||||||
|
Vec2::default(),
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BoneData {
|
impl BoneData {
|
||||||
pub fn new(bone_mat: Mat4<f32>) -> Self {
|
pub fn new(bone_mat: Mat4<f32>, normals_mat: Mat4<f32>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
bone_mat: arr_to_mat(bone_mat.into_col_array()),
|
bone_mat: arr_to_mat(bone_mat.into_col_array()),
|
||||||
|
normals_mat: arr_to_mat(normals_mat.into_col_array()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn default() -> Self { Self::new(Mat4::identity()) }
|
impl Default for BoneData {
|
||||||
|
fn default() -> Self { Self::new(Mat4::identity(), Mat4::identity()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FigurePipeline;
|
pub struct FigurePipeline;
|
||||||
@ -111,3 +144,30 @@ pub struct FigurePipeline;
|
|||||||
impl Pipeline for FigurePipeline {
|
impl Pipeline for FigurePipeline {
|
||||||
type Vertex = Vertex;
|
type Vertex = Vertex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct FigureModel {
|
||||||
|
pub bounds: Aabb<f32>,
|
||||||
|
pub opaque: Model<TerrainPipeline>,
|
||||||
|
// pub shadow: Model<ShadowPipeline>,
|
||||||
|
// TODO: Consider using mipmaps instead of storing multiple texture atlases for different LOD
|
||||||
|
// levels.
|
||||||
|
pub col_lights: Texture<ColLightFmt>,
|
||||||
|
pub allocation: guillotiere::Allocation,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FigureModel {
|
||||||
|
/// Start a greedy mesh designed for figure bones.
|
||||||
|
pub fn make_greedy<'a>() -> GreedyMesh<'a> {
|
||||||
|
// NOTE: Required because we steal two bits from the normal in the shadow uint
|
||||||
|
// in order to store the bone index. The two bits are instead taken out
|
||||||
|
// of the atlas coordinates, which is why we "only" allow 1 << 15 per
|
||||||
|
// coordinate instead of 1 << 16.
|
||||||
|
let max_size = guillotiere::Size::new(1 << 15 - 1, 1 << 15 - 1);
|
||||||
|
GreedyMesh::new(max_size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type BoneMeshes = (
|
||||||
|
Mesh</* FigurePipeline */ TerrainPipeline>, /* , Mesh<ShadowPipeline> */
|
||||||
|
Aabb<f32>,
|
||||||
|
);
|
||||||
|
@ -1,19 +1,17 @@
|
|||||||
use super::{
|
use super::{
|
||||||
super::{Pipeline, TerrainLocals, TgtColorFmt, TgtDepthStencilFmt},
|
super::{Pipeline, TerrainLocals, TgtColorFmt, TgtDepthStencilFmt},
|
||||||
Globals, Light, Shadow,
|
shadow, Globals, Light, Shadow,
|
||||||
};
|
};
|
||||||
use gfx::{
|
use gfx::{
|
||||||
self, gfx_defines, gfx_impl_struct_meta, gfx_pipeline, gfx_pipeline_inner,
|
self, gfx_defines, gfx_impl_struct_meta, gfx_pipeline, gfx_pipeline_inner,
|
||||||
gfx_vertex_struct_meta,
|
gfx_vertex_struct_meta, state::ColorMask,
|
||||||
state::{ColorMask, Comparison, Stencil, StencilOp},
|
|
||||||
};
|
};
|
||||||
use std::ops::Mul;
|
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
gfx_defines! {
|
gfx_defines! {
|
||||||
vertex Vertex {
|
vertex Vertex {
|
||||||
pos_norm: u32 = "v_pos_norm",
|
pos_norm: u32 = "v_pos_norm",
|
||||||
col_light: u32 = "v_col_light",
|
// col_light: u32 = "v_col_light",
|
||||||
}
|
}
|
||||||
|
|
||||||
pipeline pipe {
|
pipeline pipe {
|
||||||
@ -24,7 +22,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",
|
point_shadow_maps: gfx::TextureSampler<f32> = "t_point_shadow_maps",
|
||||||
|
directed_shadow_maps: gfx::TextureSampler<f32> = "t_directed_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",
|
||||||
@ -32,13 +31,17 @@ gfx_defines! {
|
|||||||
noise: gfx::TextureSampler<f32> = "t_noise",
|
noise: gfx::TextureSampler<f32> = "t_noise",
|
||||||
waves: gfx::TextureSampler<[f32; 4]> = "t_waves",
|
waves: gfx::TextureSampler<[f32; 4]> = "t_waves",
|
||||||
|
|
||||||
|
// Shadow stuff
|
||||||
|
light_shadows: gfx::ConstantBuffer<shadow::Locals> = "u_light_shadows",
|
||||||
|
|
||||||
tgt_color: gfx::BlendTarget<TgtColorFmt> = ("tgt_color", ColorMask::all(), gfx::preset::blend::ALPHA),
|
tgt_color: gfx::BlendTarget<TgtColorFmt> = ("tgt_color", ColorMask::all(), gfx::preset::blend::ALPHA),
|
||||||
tgt_depth_stencil: gfx::DepthStencilTarget<TgtDepthStencilFmt> = (gfx::preset::depth::LESS_EQUAL_TEST,Stencil::new(Comparison::Always,0xff,(StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))),
|
tgt_depth_stencil: gfx::DepthTarget<TgtDepthStencilFmt> = gfx::preset::depth::LESS_EQUAL_TEST,
|
||||||
|
// tgt_depth_stencil: gfx::DepthStencilTarget<TgtDepthStencilFmt> = (gfx::preset::depth::LESS_EQUAL_TEST,Stencil::new(Comparison::Always,0xff,(StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Vertex {
|
impl Vertex {
|
||||||
pub fn new(pos: Vec3<f32>, norm: Vec3<f32>, col: Rgb<f32>, light: f32, _opac: f32) -> Self {
|
/* pub fn new(pos: Vec3<f32>, norm: Vec3<f32>, col: Rgb<f32>, light: f32, _opac: f32) -> Self {
|
||||||
let (norm_axis, norm_dir) = norm
|
let (norm_axis, norm_dir) = norm
|
||||||
.as_slice()
|
.as_slice()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@ -62,6 +65,31 @@ impl Vertex {
|
|||||||
| ((light.mul(255.0) as u32) & 0xFF) << 0,
|
| ((light.mul(255.0) as u32) & 0xFF) << 0,
|
||||||
//| ((opac.mul(0.4) as u32) & 0xFF) << 0,
|
//| ((opac.mul(0.4) as u32) & 0xFF) << 0,
|
||||||
}
|
}
|
||||||
|
} */
|
||||||
|
pub fn new(pos: Vec3<f32>, norm: Vec3<f32>) -> Self {
|
||||||
|
let (norm_axis, norm_dir) = norm
|
||||||
|
.as_slice()
|
||||||
|
.into_iter()
|
||||||
|
.enumerate()
|
||||||
|
.find(|(_i, e)| **e != 0.0)
|
||||||
|
.unwrap_or((0, &1.0));
|
||||||
|
let norm_bits = ((norm_axis << 1) | if *norm_dir > 0.0 { 1 } else { 0 }) as u32;
|
||||||
|
|
||||||
|
const EXTRA_NEG_Z: f32 = 65536.0;
|
||||||
|
|
||||||
|
Self {
|
||||||
|
pos_norm: 0
|
||||||
|
| ((pos.x as u32) & 0x003F) << 0
|
||||||
|
| ((pos.y as u32) & 0x003F) << 6
|
||||||
|
| (((pos.z + EXTRA_NEG_Z).max(0.0).min((1 << 17) as f32) as u32) & 0x1FFFF) << 12
|
||||||
|
| (norm_bits & 0x7) << 29,
|
||||||
|
/* col_light: 0
|
||||||
|
| ((col.r.mul(200.0) as u32) & 0xFF) << 8
|
||||||
|
| ((col.g.mul(200.0) as u32) & 0xFF) << 16
|
||||||
|
| ((col.b.mul(200.0) as u32) & 0xFF) << 24
|
||||||
|
| ((light.mul(255.0) as u32) & 0xFF) << 0,
|
||||||
|
//| ((opac.mul(0.4) as u32) & 0xFF) << 0, */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@ use super::{
|
|||||||
use gfx::{
|
use gfx::{
|
||||||
self, gfx_constant_struct_meta, gfx_defines, gfx_impl_struct_meta, gfx_pipeline,
|
self, gfx_constant_struct_meta, gfx_defines, gfx_impl_struct_meta, gfx_pipeline,
|
||||||
gfx_pipeline_inner, gfx_vertex_struct_meta,
|
gfx_pipeline_inner, gfx_vertex_struct_meta,
|
||||||
state::{Comparison, Stencil, StencilOp},
|
|
||||||
};
|
};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
@ -29,7 +28,8 @@ gfx_defines! {
|
|||||||
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",
|
||||||
tgt_depth_stencil: gfx::DepthStencilTarget<TgtDepthStencilFmt> = (gfx::preset::depth::LESS_EQUAL_WRITE,Stencil::new(Comparison::Always,0xff,(StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))),
|
tgt_depth_stencil: gfx::DepthTarget<TgtDepthStencilFmt> = gfx::preset::depth::LESS_EQUAL_WRITE,
|
||||||
|
// tgt_depth_stencil: gfx::DepthStencilTarget<TgtDepthStencilFmt> = (gfx::preset::depth::LESS_EQUAL_WRITE,Stencil::new(Comparison::Always,0xff,(StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ use common::terrain::BlockKind;
|
|||||||
use gfx::{self, gfx_constant_struct_meta, gfx_defines, gfx_impl_struct_meta};
|
use gfx::{self, gfx_constant_struct_meta, gfx_defines, gfx_impl_struct_meta};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
pub const MAX_POINT_LIGHT_COUNT: usize = 32;
|
pub const MAX_POINT_LIGHT_COUNT: usize = 31;
|
||||||
pub const MAX_FIGURE_SHADOW_COUNT: usize = 24;
|
pub const MAX_FIGURE_SHADOW_COUNT: usize = 24;
|
||||||
pub const MAX_DIRECTED_LIGHT_COUNT: usize = 6;
|
pub const MAX_DIRECTED_LIGHT_COUNT: usize = 6;
|
||||||
|
|
||||||
@ -24,6 +24,7 @@ gfx_defines! {
|
|||||||
proj_mat: [[f32; 4]; 4] = "proj_mat",
|
proj_mat: [[f32; 4]; 4] = "proj_mat",
|
||||||
all_mat: [[f32; 4]; 4] = "all_mat",
|
all_mat: [[f32; 4]; 4] = "all_mat",
|
||||||
cam_pos: [f32; 4] = "cam_pos",
|
cam_pos: [f32; 4] = "cam_pos",
|
||||||
|
focus_off: [f32; 4] = "focus_off",
|
||||||
focus_pos: [f32; 4] = "focus_pos",
|
focus_pos: [f32; 4] = "focus_pos",
|
||||||
/// NOTE: max_intensity is computed as the ratio between the brightest and least bright
|
/// NOTE: max_intensity is computed as the ratio between the brightest and least bright
|
||||||
/// intensities among all lights in the scene.
|
/// intensities among all lights in the scene.
|
||||||
@ -36,6 +37,8 @@ gfx_defines! {
|
|||||||
/// TODO: Fix whatever alignment issue requires these uniforms to be aligned.
|
/// TODO: Fix whatever alignment issue requires these uniforms to be aligned.
|
||||||
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.
|
||||||
|
sun_dir: [f32; 4] = "sun_dir",
|
||||||
|
moon_dir: [f32; 4] = "moon_dir",
|
||||||
tick: [f32; 4] = "tick",
|
tick: [f32; 4] = "tick",
|
||||||
/// x, y represent the resolution of the screen;
|
/// x, y represent the resolution of the screen;
|
||||||
/// w, z represent the near and far planes of the shadow map.
|
/// w, z represent the near and far planes of the shadow map.
|
||||||
@ -83,14 +86,24 @@ impl Globals {
|
|||||||
cam_mode: CameraMode,
|
cam_mode: CameraMode,
|
||||||
sprite_render_distance: f32,
|
sprite_render_distance: f32,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
// Transform to left-handed homogeneous coordinates.
|
||||||
|
let proj_mat_lh = proj_mat;
|
||||||
|
// proj_mat_lh[(2, 2)] = -proj_mat[(2, 2)];
|
||||||
|
// proj_mat_lh[(3, 2)] = -proj_mat[(3, 2)];
|
||||||
Self {
|
Self {
|
||||||
view_mat: arr_to_mat(view_mat.into_col_array()),
|
view_mat: arr_to_mat(view_mat.into_col_array()),
|
||||||
proj_mat: arr_to_mat(proj_mat.into_col_array()),
|
proj_mat: arr_to_mat(proj_mat.into_col_array()),
|
||||||
all_mat: arr_to_mat((proj_mat * view_mat).into_col_array()),
|
all_mat: arr_to_mat(
|
||||||
|
((proj_mat_lh * view_mat)/* .scaled_3d(Vec3::new(0.0, 0.0, -1.0)) */)
|
||||||
|
.into_col_array(),
|
||||||
|
),
|
||||||
cam_pos: Vec4::from(cam_pos).into_array(),
|
cam_pos: Vec4::from(cam_pos).into_array(),
|
||||||
focus_pos: Vec4::from(focus_pos).into_array(),
|
focus_off: Vec4::from(focus_pos).map(|e: f32| e.trunc()).into_array(),
|
||||||
|
focus_pos: Vec4::from(focus_pos).map(|e: f32| e.fract()).into_array(),
|
||||||
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],
|
||||||
|
sun_dir: Vec4::from_direction(Self::get_sun_dir(time_of_day)).into_array(),
|
||||||
|
moon_dir: Vec4::from_direction(Self::get_moon_dir(time_of_day)).into_array(),
|
||||||
tick: [tick as f32; 4],
|
tick: [tick as f32; 4],
|
||||||
// Provide the shadow map far plane as well.
|
// Provide the shadow map far plane as well.
|
||||||
screen_res: [
|
screen_res: [
|
||||||
@ -100,9 +113,9 @@ impl Globals {
|
|||||||
shadow_planes.y,
|
shadow_planes.y,
|
||||||
],
|
],
|
||||||
light_shadow_count: [
|
light_shadow_count: [
|
||||||
(light_count % MAX_POINT_LIGHT_COUNT) as u32,
|
(light_count % (MAX_POINT_LIGHT_COUNT + 1)) as u32,
|
||||||
(shadow_count % MAX_FIGURE_SHADOW_COUNT) as u32,
|
(shadow_count % (MAX_FIGURE_SHADOW_COUNT + 1)) as u32,
|
||||||
(directed_light_count % MAX_DIRECTED_LIGHT_COUNT) as u32,
|
(directed_light_count % (MAX_DIRECTED_LIGHT_COUNT + 1)) as u32,
|
||||||
0,
|
0,
|
||||||
],
|
],
|
||||||
shadow_proj_factors: [
|
shadow_proj_factors: [
|
||||||
@ -121,6 +134,21 @@ impl Globals {
|
|||||||
sprite_render_distance,
|
sprite_render_distance,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_angle_rad(time_of_day: f64) -> f32 {
|
||||||
|
const TIME_FACTOR: f32 = (std::f32::consts::PI * 2.0) / (3600.0 * 24.0);
|
||||||
|
time_of_day as f32 * TIME_FACTOR
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_sun_dir(time_of_day: f64) -> Vec3<f32> {
|
||||||
|
let angle_rad = Self::get_angle_rad(time_of_day);
|
||||||
|
Vec3::new(angle_rad.sin(), 0.0, angle_rad.cos())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_moon_dir(time_of_day: f64) -> Vec3<f32> {
|
||||||
|
let angle_rad = Self::get_angle_rad(time_of_day);
|
||||||
|
-Vec3::new(angle_rad.sin(), 0.0, angle_rad.cos() - 0.5)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Globals {
|
impl Default for Globals {
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
use super::{
|
use super::{
|
||||||
super::{util::arr_to_mat, Pipeline, ShadowDepthStencilFmt, TerrainLocals},
|
super::{
|
||||||
Globals, Light, Shadow,
|
util::arr_to_mat, ColLightFmt, ColLightInfo, Pipeline, RenderError, Renderer,
|
||||||
|
ShadowDepthStencilFmt, TerrainLocals, Texture,
|
||||||
|
},
|
||||||
|
figure, terrain, Globals,
|
||||||
};
|
};
|
||||||
use gfx::{
|
use gfx::{
|
||||||
self, gfx_constant_struct_meta, gfx_defines, gfx_impl_struct_meta, gfx_pipeline,
|
self, gfx_constant_struct_meta, gfx_defines, gfx_impl_struct_meta, gfx_pipeline,
|
||||||
@ -13,35 +16,70 @@ gfx_defines! {
|
|||||||
// pos: [f32; 4] = "v_pos",
|
// pos: [f32; 4] = "v_pos",
|
||||||
pos_norm: u32 = "v_pos_norm",
|
pos_norm: u32 = "v_pos_norm",
|
||||||
// col_light: u32 = "v_col_light",
|
// col_light: u32 = "v_col_light",
|
||||||
|
// atlas_pos: u32 = "v_atlas_pos",
|
||||||
}
|
}
|
||||||
|
|
||||||
constant Locals {
|
constant Locals {
|
||||||
shadow_matrices: [[f32; 4]; 4] = "shadowMatrices",
|
shadow_matrices: [[f32; 4]; 4] = "shadowMatrices",
|
||||||
|
texture_mats: [[f32; 4]; 4] = "texture_mat",
|
||||||
}
|
}
|
||||||
|
|
||||||
pipeline pipe {
|
pipeline pipe {
|
||||||
// Terrain vertex stuff
|
// Terrain vertex stuff
|
||||||
vbuf: gfx::VertexBuffer<Vertex> = (),
|
vbuf: gfx::VertexBuffer</*Vertex*/terrain::Vertex> = (),
|
||||||
|
|
||||||
locals: gfx::ConstantBuffer<TerrainLocals> = "u_locals",
|
locals: gfx::ConstantBuffer<TerrainLocals> = "u_locals",
|
||||||
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",
|
||||||
|
|
||||||
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",
|
||||||
|
|
||||||
noise: gfx::TextureSampler<f32> = "t_noise",
|
// noise: gfx::TextureSampler<f32> = "t_noise",
|
||||||
|
|
||||||
// Shadow stuff
|
// Shadow stuff
|
||||||
light_shadows: gfx::ConstantBuffer<Locals> = "u_light_shadows",
|
light_shadows: gfx::ConstantBuffer<Locals> = "u_light_shadows",
|
||||||
|
|
||||||
tgt_depth_stencil: gfx::DepthTarget<ShadowDepthStencilFmt> = gfx::preset::depth::LESS_EQUAL_WRITE,//,Stencil::new(Comparison::Always,0xff,(StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))),
|
tgt_depth_stencil: gfx::DepthTarget<ShadowDepthStencilFmt> = gfx::state::Depth {
|
||||||
|
fun: gfx::state::Comparison::Less,
|
||||||
|
write: true,
|
||||||
|
},
|
||||||
|
// tgt_depth_stencil: gfx::DepthTarget<ShadowDepthStencilFmt> = gfx::preset::depth::LESS_EQUAL_WRITE,//,Stencil::new(Comparison::Always,0xff,(StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))),
|
||||||
|
}
|
||||||
|
|
||||||
|
pipeline figure_pipe {
|
||||||
|
// Terrain vertex stuff
|
||||||
|
vbuf: gfx::VertexBuffer</*Vertex*/terrain::Vertex> = (),
|
||||||
|
|
||||||
|
locals: gfx::ConstantBuffer<figure::Locals> = "u_locals",
|
||||||
|
bones: gfx::ConstantBuffer<figure::BoneData> = "u_bones",
|
||||||
|
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::state::Depth {
|
||||||
|
fun: gfx::state::Comparison::Less,
|
||||||
|
write: true,
|
||||||
|
},
|
||||||
|
// tgt_depth_stencil: gfx::DepthTarget<ShadowDepthStencilFmt> = gfx::preset::depth::LESS_WRITE,//,Stencil::new(Comparison::Always,0xff,(StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Vertex {
|
impl Vertex {
|
||||||
pub fn new(pos: Vec3<f32>, norm: Vec3<f32>) -> Self {
|
pub fn new(
|
||||||
|
pos: Vec3<f32>,
|
||||||
|
norm: Vec3<f32>,
|
||||||
|
meta: bool, /* , atlas_pos: Vec2<u16> */
|
||||||
|
) -> Self {
|
||||||
let norm_bits = if norm.x != 0.0 {
|
let norm_bits = if norm.x != 0.0 {
|
||||||
if norm.x < 0.0 { 0 } else { 1 }
|
if norm.x < 0.0 { 0 } else { 1 }
|
||||||
} else if norm.y != 0.0 {
|
} else if norm.y != 0.0 {
|
||||||
@ -52,7 +90,7 @@ impl Vertex {
|
|||||||
// let ao = 0xFFu32;
|
// let ao = 0xFFu32;
|
||||||
// let light = 0xFFu32;
|
// let light = 0xFFu32;
|
||||||
// let col = Rgb::new(1.0f32, 0.0, 0.0);
|
// let col = Rgb::new(1.0f32, 0.0, 0.0);
|
||||||
let meta = true;
|
// let meta = true;
|
||||||
|
|
||||||
const EXTRA_NEG_Z: f32 = 32768.0;
|
const EXTRA_NEG_Z: f32 = 32768.0;
|
||||||
|
|
||||||
@ -63,6 +101,9 @@ impl Vertex {
|
|||||||
| (((pos + EXTRA_NEG_Z).z.max(0.0).min((1 << 16) as f32) as u32) & 0xFFFF) << 12
|
| (((pos + EXTRA_NEG_Z).z.max(0.0).min((1 << 16) as f32) as u32) & 0xFFFF) << 12
|
||||||
| if meta { 1 } else { 0 } << 28
|
| if meta { 1 } else { 0 } << 28
|
||||||
| (norm_bits & 0x7) << 29,
|
| (norm_bits & 0x7) << 29,
|
||||||
|
/* atlas_pos: 0
|
||||||
|
| ((atlas_pos.x as u32) & 0xFFFF) << 0
|
||||||
|
| ((atlas_pos.y as u32) & 0xFFFF) << 16, */
|
||||||
/* col_light: 0
|
/* col_light: 0
|
||||||
| (((col.r * 255.0) as u32) & 0xFF) << 8
|
| (((col.r * 255.0) as u32) & 0xFF) << 8
|
||||||
| (((col.g * 255.0) as u32) & 0xFF) << 16
|
| (((col.g * 255.0) as u32) & 0xFF) << 16
|
||||||
@ -71,20 +112,73 @@ impl Vertex {
|
|||||||
| ((light >> 2) & 0x3F) << 0, */
|
| ((light >> 2) & 0x3F) << 0, */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl Locals {
|
pub fn new_figure(
|
||||||
pub fn new(shadow_mat: Mat4<f32>) -> Self {
|
pos: Vec3<f32>,
|
||||||
|
norm: Vec3<f32>,
|
||||||
|
/* col: Rgb<f32>, ao: f32, */ bone_idx: u8,
|
||||||
|
) -> Self {
|
||||||
|
let norm_bits = if norm.x.min(norm.y).min(norm.z) < 0.0 {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
1
|
||||||
|
};
|
||||||
Self {
|
Self {
|
||||||
shadow_matrices: arr_to_mat(shadow_mat.into_col_array()),
|
pos_norm: pos
|
||||||
|
.map2(Vec3::new(0, 9, 18), |e, shift| {
|
||||||
|
(((e * 2.0 + 256.0) as u32) & 0x1FF) << shift
|
||||||
|
})
|
||||||
|
.reduce_bitor()
|
||||||
|
| (((bone_idx & 0xF) as u32) << 27)
|
||||||
|
| (norm_bits << 31),
|
||||||
|
// col: col
|
||||||
|
// .map2(Rgb::new(0, 8, 16), |e, shift| ((e * 255.0) as u32) << shift)
|
||||||
|
// .reduce_bitor(),
|
||||||
|
// ao_bone: (bone_idx << 2) | ((ao * 3.9999) as u8),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn default() -> Self { Self::new(Mat4::identity()) }
|
pub fn with_bone_idx(self, bone_idx: u8) -> Self {
|
||||||
|
Self {
|
||||||
|
pos_norm: (self.pos_norm & !(0xF << 27)) | ((bone_idx as u32 & 0xF) << 27),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Locals {
|
||||||
|
pub fn new(shadow_mat: Mat4<f32>, texture_mat: Mat4<f32>) -> Self {
|
||||||
|
Self {
|
||||||
|
shadow_matrices: arr_to_mat(shadow_mat.into_col_array()),
|
||||||
|
texture_mats: arr_to_mat(texture_mat.into_col_array()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn default() -> Self { Self::new(Mat4::identity(), Mat4::identity()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ShadowPipeline;
|
pub struct ShadowPipeline;
|
||||||
|
|
||||||
|
impl ShadowPipeline {
|
||||||
|
pub fn create_col_lights(
|
||||||
|
renderer: &mut Renderer,
|
||||||
|
(col_lights, col_lights_size): ColLightInfo,
|
||||||
|
) -> Result<Texture<ColLightFmt>, RenderError> {
|
||||||
|
renderer.create_texture_immutable_raw(
|
||||||
|
gfx::texture::Kind::D2(
|
||||||
|
col_lights_size.x,
|
||||||
|
col_lights_size.y,
|
||||||
|
gfx::texture::AaMode::Single,
|
||||||
|
),
|
||||||
|
gfx::texture::Mipmap::Provided,
|
||||||
|
&[&col_lights /* .raw_pixels() */],
|
||||||
|
gfx::texture::SamplerInfo::new(
|
||||||
|
gfx::texture::FilterMethod::Bilinear,
|
||||||
|
gfx::texture::WrapMode::Clamp,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Pipeline for ShadowPipeline {
|
impl Pipeline for ShadowPipeline {
|
||||||
type Vertex = Vertex;
|
type Vertex = Vertex;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ use super::{
|
|||||||
use gfx::{
|
use gfx::{
|
||||||
self, gfx_constant_struct_meta, gfx_defines, gfx_impl_struct_meta, gfx_pipeline,
|
self, gfx_constant_struct_meta, gfx_defines, gfx_impl_struct_meta, gfx_pipeline,
|
||||||
gfx_pipeline_inner, gfx_vertex_struct_meta,
|
gfx_pipeline_inner, gfx_vertex_struct_meta,
|
||||||
state::{Comparison, Stencil, StencilOp},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
gfx_defines! {
|
gfx_defines! {
|
||||||
@ -29,7 +28,9 @@ gfx_defines! {
|
|||||||
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",
|
||||||
tgt_depth_stencil: gfx::DepthStencilTarget<TgtDepthStencilFmt> = (gfx::preset::depth::LESS_EQUAL_WRITE,Stencil::new(Comparison::Always,0xff,(StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))),
|
tgt_depth_stencil: gfx::DepthTarget<TgtDepthStencilFmt> = gfx::preset::depth::LESS_EQUAL_TEST,
|
||||||
|
// tgt_depth_stencil: gfx::DepthTarget<TgtDepthStencilFmt> = gfx::preset::depth::LESS_EQUAL_WRITE,
|
||||||
|
// tgt_depth_stencil: gfx::DepthStencilTarget<TgtDepthStencilFmt> = (gfx::preset::depth::LESS_EQUAL_WRITE,Stencil::new(Comparison::Always,0xff,(StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,56 +1,104 @@
|
|||||||
use super::{
|
use super::{
|
||||||
super::{util::arr_to_mat, Pipeline, TgtColorFmt, TgtDepthStencilFmt},
|
super::{util::arr_to_mat, Pipeline, TgtColorFmt, TgtDepthStencilFmt},
|
||||||
Globals, Light, Shadow,
|
shadow, terrain, Globals, Light, Shadow,
|
||||||
};
|
};
|
||||||
|
use core::fmt;
|
||||||
use gfx::{
|
use gfx::{
|
||||||
self, gfx_defines, gfx_impl_struct_meta, gfx_pipeline, gfx_pipeline_inner,
|
self, gfx_constant_struct_meta, gfx_defines, gfx_impl_struct_meta, gfx_pipeline,
|
||||||
gfx_vertex_struct_meta,
|
gfx_pipeline_inner, gfx_vertex_struct_meta, state::ColorMask,
|
||||||
state::{ColorMask, Comparison, Stencil, StencilOp},
|
|
||||||
};
|
};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
gfx_defines! {
|
gfx_defines! {
|
||||||
vertex Vertex {
|
vertex Vertex {
|
||||||
pos: [f32; 3] = "v_pos",
|
pos: [f32; 3] = "v_pos",
|
||||||
|
// pos_norm: u32 = "v_pos_norm",
|
||||||
|
// Because we try to restrict terrain sprite data to a 128×128 block
|
||||||
|
// we need an offset into the texture atlas.
|
||||||
|
atlas_pos: u32 = "v_atlas_pos",
|
||||||
// ____BBBBBBBBGGGGGGGGRRRRRRRR
|
// ____BBBBBBBBGGGGGGGGRRRRRRRR
|
||||||
col: u32 = "v_col",
|
// col: u32 = "v_col",
|
||||||
// ...AANNN
|
// ...AANNN
|
||||||
// A = AO
|
// A = AO
|
||||||
// N = Normal
|
// N = Normal
|
||||||
norm_ao: u32 = "v_norm_ao",
|
norm_ao: u32 = "v_norm_ao",
|
||||||
}
|
}
|
||||||
|
|
||||||
vertex Instance {
|
constant Locals {
|
||||||
|
// Each matrix performs rotatation, translation, and scaling, relative to the sprite
|
||||||
|
// origin, for all sprite instances. The matrix will be in an array indexed by the
|
||||||
|
// sprite instance's orientation (0 through 7).
|
||||||
|
mat: [[f32; 4]; 4] = "mat",
|
||||||
|
wind_sway: [f32; 4] = "wind_sway",
|
||||||
|
offs: [f32; 4] = "offs",
|
||||||
|
}
|
||||||
|
|
||||||
|
vertex/*constant*/ Instance {
|
||||||
|
// Terrain block position and orientation
|
||||||
|
pos_ori: u32 = "inst_pos_ori",
|
||||||
inst_mat0: [f32; 4] = "inst_mat0",
|
inst_mat0: [f32; 4] = "inst_mat0",
|
||||||
inst_mat1: [f32; 4] = "inst_mat1",
|
inst_mat1: [f32; 4] = "inst_mat1",
|
||||||
inst_mat2: [f32; 4] = "inst_mat2",
|
inst_mat2: [f32; 4] = "inst_mat2",
|
||||||
inst_mat3: [f32; 4] = "inst_mat3",
|
inst_mat3: [f32; 4] = "inst_mat3",
|
||||||
inst_col: [f32; 3] = "inst_col",
|
// inst_mat: [[f32; 4]; 4] = "inst_mat",
|
||||||
|
// inst_col: [f32; 3] = "inst_col",
|
||||||
inst_wind_sway: f32 = "inst_wind_sway",
|
inst_wind_sway: f32 = "inst_wind_sway",
|
||||||
}
|
}
|
||||||
|
|
||||||
pipeline pipe {
|
pipeline pipe {
|
||||||
vbuf: gfx::VertexBuffer<Vertex> = (),
|
vbuf: gfx::VertexBuffer<Vertex> = (),
|
||||||
ibuf: gfx::InstanceBuffer<Instance> = (),
|
ibuf: gfx::InstanceBuffer<Instance> = (),
|
||||||
|
// ibuf: gfx::/*handle::RawBuffer*/ConstantBuffer<Instance> = "u_ibuf",
|
||||||
|
col_lights: gfx::TextureSampler<[f32; 4]> = "t_col_light",
|
||||||
|
|
||||||
|
locals: gfx::ConstantBuffer<Locals> = "u_locals",
|
||||||
|
// A sprite instance is a cross between a sprite and a terrain chunk.
|
||||||
|
terrain_locals: gfx::ConstantBuffer<terrain::Locals> = "u_terrain_locals",
|
||||||
|
// locals: gfx::ConstantBuffer<terrain::Locals> = "u_locals",
|
||||||
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",
|
point_shadow_maps: gfx::TextureSampler<f32> = "t_point_shadow_maps",
|
||||||
|
directed_shadow_maps: gfx::TextureSampler<f32> = "t_directed_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",
|
||||||
|
|
||||||
noise: gfx::TextureSampler<f32> = "t_noise",
|
noise: gfx::TextureSampler<f32> = "t_noise",
|
||||||
|
|
||||||
|
// Shadow stuff
|
||||||
|
light_shadows: gfx::ConstantBuffer<shadow::Locals> = "u_light_shadows",
|
||||||
|
|
||||||
tgt_color: gfx::BlendTarget<TgtColorFmt> = ("tgt_color", ColorMask::all(), gfx::preset::blend::ALPHA),
|
tgt_color: gfx::BlendTarget<TgtColorFmt> = ("tgt_color", ColorMask::all(), gfx::preset::blend::ALPHA),
|
||||||
tgt_depth_stencil: gfx::DepthStencilTarget<TgtDepthStencilFmt> = (gfx::preset::depth::LESS_EQUAL_WRITE,Stencil::new(Comparison::Always,0xff,(StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))),
|
tgt_depth_stencil: gfx::DepthTarget<TgtDepthStencilFmt> = gfx::preset::depth::LESS_EQUAL_WRITE,
|
||||||
|
// tgt_depth_stencil: gfx::DepthStencilTarget<TgtDepthStencilFmt> = (gfx::preset::depth::LESS_EQUAL_WRITE,Stencil::new(Comparison::Always,0xff,(StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Vertex {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
f.debug_struct("Vertex")
|
||||||
|
.field("pos", &Vec3::<f32>::from(self.pos))
|
||||||
|
.field(
|
||||||
|
"atlas_pos",
|
||||||
|
&Vec2::new(
|
||||||
|
(self.atlas_pos >> 0) & 0xFFFF,
|
||||||
|
(self.atlas_pos >> 16) & 0xFFFF,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.field("norm_ao", &self.norm_ao)
|
||||||
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Vertex {
|
impl Vertex {
|
||||||
pub fn new(pos: Vec3<f32>, norm: Vec3<f32>, col: Rgb<f32>, ao: f32) -> Self {
|
// NOTE: Limit to 16 (x) × 16 (y) × 32 (z).
|
||||||
|
pub fn new(
|
||||||
|
atlas_pos: Vec2<u16>,
|
||||||
|
pos: Vec3<f32>,
|
||||||
|
norm: Vec3<f32>, /* , col: Rgb<f32>, ao: f32 */
|
||||||
|
) -> Self {
|
||||||
let norm_bits = if norm.x != 0.0 {
|
let norm_bits = if norm.x != 0.0 {
|
||||||
if norm.x < 0.0 { 0 } else { 1 }
|
if norm.x < 0.0 { 0 } else { 1 }
|
||||||
} else if norm.y != 0.0 {
|
} else if norm.y != 0.0 {
|
||||||
@ -60,31 +108,75 @@ impl Vertex {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
// pos_norm: 0
|
||||||
|
// | ((pos.x as u32) & 0x003F) << 0
|
||||||
|
// | ((pos.y as u32) & 0x003F) << 6
|
||||||
|
// | (((pos + EXTRA_NEG_Z).z.max(0.0).min((1 << 16) as f32) as u32) & 0xFFFF) << 12
|
||||||
|
// | if meta { 1 } else { 0 } << 28
|
||||||
|
// | (norm_bits & 0x7) << 29,
|
||||||
pos: pos.into_array(),
|
pos: pos.into_array(),
|
||||||
col: col
|
/* col: col
|
||||||
.map2(Rgb::new(0, 8, 16), |e, shift| ((e * 255.0) as u32) << shift)
|
.map2(Rgb::new(0, 8, 16), |e, shift| ((e * 255.0) as u32) << shift)
|
||||||
.reduce_bitor(),
|
.reduce_bitor(), */
|
||||||
norm_ao: norm_bits | (((ao * 3.9999) as u32) << 3),
|
atlas_pos: 0
|
||||||
|
| ((atlas_pos.x as u32) & 0xFFFF) << 0
|
||||||
|
| ((atlas_pos.y as u32) & 0xFFFF) << 16, /* | axis_bits & 3 */
|
||||||
|
norm_ao: norm_bits, /* | (((ao * 3.9999) as u32) << 3) */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Instance {
|
impl Instance {
|
||||||
pub fn new(mat: Mat4<f32>, col: Rgb<f32>, wind_sway: f32) -> Self {
|
pub fn new(
|
||||||
|
mat: Mat4<f32>,
|
||||||
|
/* col: Rgb<f32>, */ wind_sway: f32,
|
||||||
|
pos: Vec3<i32>,
|
||||||
|
ori_bits: u8,
|
||||||
|
) -> Self {
|
||||||
|
const EXTRA_NEG_Z: i32 = 32768;
|
||||||
|
|
||||||
let mat_arr = arr_to_mat(mat.into_col_array());
|
let mat_arr = arr_to_mat(mat.into_col_array());
|
||||||
Self {
|
Self {
|
||||||
|
pos_ori: 0
|
||||||
|
| ((pos.x as u32) & 0x003F) << 0
|
||||||
|
| ((pos.y as u32) & 0x003F) << 6
|
||||||
|
| (((pos + EXTRA_NEG_Z).z.max(0).min(1 << 16/* as f32*/) as u32) & 0xFFFF) << 12
|
||||||
|
// | if meta { 1 } else { 0 } << 28
|
||||||
|
| (u32::from(ori_bits) & 0x7) << 29,
|
||||||
inst_mat0: mat_arr[0],
|
inst_mat0: mat_arr[0],
|
||||||
inst_mat1: mat_arr[1],
|
inst_mat1: mat_arr[1],
|
||||||
inst_mat2: mat_arr[2],
|
inst_mat2: mat_arr[2],
|
||||||
inst_mat3: mat_arr[3],
|
inst_mat3: mat_arr[3],
|
||||||
inst_col: col.into_array(),
|
// inst_mat: mat_arr,
|
||||||
|
// inst_col: col.into_array(),
|
||||||
inst_wind_sway: wind_sway,
|
inst_wind_sway: wind_sway,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Instance {
|
impl Default for Instance {
|
||||||
fn default() -> Self { Self::new(Mat4::identity(), Rgb::broadcast(1.0), 0.0) }
|
fn default() -> Self {
|
||||||
|
Self::new(
|
||||||
|
Mat4::identity(),
|
||||||
|
/* Rgb::broadcast(1.0), */ 0.0,
|
||||||
|
Vec3::zero(),
|
||||||
|
0,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Locals {
|
||||||
|
fn default() -> Self { Self::new(Mat4::identity(), Vec3::one(), Vec3::zero(), 0.0) }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Locals {
|
||||||
|
pub fn new(mat: Mat4<f32>, scale: Vec3<f32>, offs: Vec3<f32>, wind_sway: f32) -> Self {
|
||||||
|
Self {
|
||||||
|
mat: arr_to_mat(mat.into_col_array()),
|
||||||
|
wind_sway: [scale.x, scale.y, scale.z, wind_sway],
|
||||||
|
offs: [offs.x, offs.y, offs.z, 0.0],
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SpritePipeline;
|
pub struct SpritePipeline;
|
||||||
|
@ -1,48 +1,125 @@
|
|||||||
use super::{
|
use super::{
|
||||||
super::{Pipeline, TgtColorFmt, TgtDepthStencilFmt},
|
super::{ColLightFmt, Pipeline, TgtColorFmt, TgtDepthStencilFmt},
|
||||||
Globals, Light, Shadow,
|
shadow, Globals, Light, Shadow,
|
||||||
};
|
};
|
||||||
use gfx::{
|
use gfx::{
|
||||||
self, gfx_constant_struct_meta, gfx_defines, gfx_impl_struct_meta, gfx_pipeline,
|
self, gfx_constant_struct_meta, gfx_defines, gfx_impl_struct_meta, gfx_pipeline,
|
||||||
gfx_pipeline_inner, gfx_vertex_struct_meta,
|
gfx_pipeline_inner, gfx_vertex_struct_meta,
|
||||||
state::{Comparison, Stencil, StencilOp},
|
|
||||||
};
|
};
|
||||||
use std::ops::Mul;
|
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
gfx_defines! {
|
gfx_defines! {
|
||||||
vertex Vertex {
|
vertex Vertex {
|
||||||
|
// pos_norm: u32 = "v_pos_norm",
|
||||||
|
// col_light: u32 = "v_col_light",
|
||||||
pos_norm: u32 = "v_pos_norm",
|
pos_norm: u32 = "v_pos_norm",
|
||||||
col_light: u32 = "v_col_light",
|
atlas_pos: u32 = "v_atlas_pos",
|
||||||
}
|
}
|
||||||
|
|
||||||
constant Locals {
|
constant Locals {
|
||||||
model_offs: [f32; 3] = "model_offs",
|
model_offs: [f32; 3] = "model_offs",
|
||||||
load_time: f32 = "load_time",
|
load_time: f32 = "load_time",
|
||||||
|
atlas_offs: [i32; 4] = "atlas_offs",
|
||||||
}
|
}
|
||||||
|
|
||||||
pipeline pipe {
|
pipeline pipe {
|
||||||
vbuf: gfx::VertexBuffer<Vertex> = (),
|
vbuf: gfx::VertexBuffer</*shadow::Vertex*/Vertex> = (),
|
||||||
|
// abuf: gfx::VertexBuffer<Vertex> = (),
|
||||||
|
col_lights: gfx::TextureSampler<[f32; 4]> = "t_col_light",
|
||||||
|
|
||||||
locals: gfx::ConstantBuffer<Locals> = "u_locals",
|
locals: gfx::ConstantBuffer<Locals> = "u_locals",
|
||||||
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",
|
point_shadow_maps: gfx::TextureSampler<f32> = "t_point_shadow_maps",
|
||||||
|
directed_shadow_maps: gfx::TextureSampler<f32> = "t_directed_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",
|
||||||
|
|
||||||
noise: gfx::TextureSampler<f32> = "t_noise",
|
noise: gfx::TextureSampler<f32> = "t_noise",
|
||||||
|
|
||||||
|
// Shadow stuff
|
||||||
|
light_shadows: gfx::ConstantBuffer<shadow::Locals> = "u_light_shadows",
|
||||||
|
|
||||||
tgt_color: gfx::RenderTarget<TgtColorFmt> = "tgt_color",
|
tgt_color: gfx::RenderTarget<TgtColorFmt> = "tgt_color",
|
||||||
tgt_depth_stencil: gfx::DepthStencilTarget<TgtDepthStencilFmt> = (gfx::preset::depth::LESS_EQUAL_WRITE,Stencil::new(Comparison::Always,0xff,(StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))),
|
tgt_depth_stencil: gfx::DepthTarget<TgtDepthStencilFmt> = gfx::preset::depth::LESS_EQUAL_WRITE,
|
||||||
|
// tgt_depth_stencil: gfx::DepthStencilTarget<TgtDepthStencilFmt> = (gfx::preset::depth::LESS_EQUAL_WRITE,Stencil::new(Comparison::Always,0xff,(StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Vertex {
|
impl Vertex {
|
||||||
pub fn new(
|
pub fn new(atlas_pos: Vec2<u16>, pos: Vec3<f32>, norm: Vec3<f32>, meta: bool) -> Self {
|
||||||
|
const EXTRA_NEG_Z: f32 = 32768.0;
|
||||||
|
|
||||||
|
let norm_bits = if norm.x != 0.0 {
|
||||||
|
if norm.x < 0.0 { 0 } else { 1 }
|
||||||
|
} else if norm.y != 0.0 {
|
||||||
|
if norm.y < 0.0 { 2 } else { 3 }
|
||||||
|
} else {
|
||||||
|
if norm.z < 0.0 { 4 } else { 5 }
|
||||||
|
};
|
||||||
|
Self {
|
||||||
|
pos_norm: 0
|
||||||
|
| ((pos.x as u32) & 0x003F) << 0
|
||||||
|
| ((pos.y as u32) & 0x003F) << 6
|
||||||
|
| (((pos + EXTRA_NEG_Z).z.max(0.0).min((1 << 16) as f32) as u32) & 0xFFFF) << 12
|
||||||
|
| if meta { 1 } else { 0 } << 28
|
||||||
|
| (norm_bits & 0x7) << 29,
|
||||||
|
atlas_pos: 0
|
||||||
|
| ((atlas_pos.x as u32) & 0xFFFF) << 0
|
||||||
|
| ((atlas_pos.y as u32) & 0xFFFF) << 16,
|
||||||
|
/* col_light: 0
|
||||||
|
| (((col.r * 255.0) as u32) & 0xFF) << 8
|
||||||
|
| (((col.g * 255.0) as u32) & 0xFF) << 16
|
||||||
|
| (((col.b * 255.0) as u32) & 0xFF) << 24
|
||||||
|
| (ao >> 6) << 6
|
||||||
|
| ((light >> 2) & 0x3F) << 0, */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_figure(
|
||||||
|
// norm: Vec3<f32>,
|
||||||
|
atlas_pos: Vec2<u16>,
|
||||||
|
pos: Vec3<f32>,
|
||||||
|
norm: Vec3<f32>,
|
||||||
|
bone_idx: u8,
|
||||||
|
) -> Self {
|
||||||
|
let norm_bits = if norm.x.min(norm.y).min(norm.z) < 0.0 {
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
1
|
||||||
|
};
|
||||||
|
let axis_bits = if norm.x != 0.0 {
|
||||||
|
0
|
||||||
|
} else if norm.y != 0.0 {
|
||||||
|
1
|
||||||
|
} else {
|
||||||
|
2
|
||||||
|
};
|
||||||
|
Self {
|
||||||
|
pos_norm: pos
|
||||||
|
.map2(Vec3::new(0, 9, 18), |e, shift| {
|
||||||
|
(((e * 2.0 + 256.0) as u32) & 0x1FF) << shift
|
||||||
|
})
|
||||||
|
.reduce_bitor()
|
||||||
|
| (((bone_idx & 0xF) as u32) << 27)
|
||||||
|
| (norm_bits << 31),
|
||||||
|
atlas_pos: 0
|
||||||
|
| ((atlas_pos.x as u32) & 0x7FFF) << 2
|
||||||
|
| ((atlas_pos.y as u32) & 0x7FFF) << 17
|
||||||
|
| axis_bits & 3,
|
||||||
|
/* col_light: 0
|
||||||
|
| (((col.r * 255.0) as u32) & 0xFF) << 8
|
||||||
|
| (((col.g * 255.0) as u32) & 0xFF) << 16
|
||||||
|
| (((col.b * 255.0) as u32) & 0xFF) << 24
|
||||||
|
| (ao >> 6) << 6
|
||||||
|
| ((light >> 2) & 0x3F) << 0, */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* pub fn new(
|
||||||
norm_bits: u32,
|
norm_bits: u32,
|
||||||
light: u32,
|
light: u32,
|
||||||
ao: u32,
|
ao: u32,
|
||||||
@ -66,6 +143,31 @@ impl Vertex {
|
|||||||
| (ao >> 6) << 6
|
| (ao >> 6) << 6
|
||||||
| ((light >> 2) & 0x3F) << 0,
|
| ((light >> 2) & 0x3F) << 0,
|
||||||
}
|
}
|
||||||
|
} */
|
||||||
|
|
||||||
|
pub fn make_col_light(
|
||||||
|
light: /* u32 */ u8,
|
||||||
|
// ao: u32,
|
||||||
|
// col: Rgb<f32>,
|
||||||
|
col: Rgb<u8>,
|
||||||
|
) -> <<ColLightFmt as gfx::format::Formatted>::Surface as gfx::format::SurfaceTyped>::DataType
|
||||||
|
{
|
||||||
|
[
|
||||||
|
col.r, //.mul(255.0) as u8,
|
||||||
|
col.g, //.mul(255.0) as u8,
|
||||||
|
col.b, //.mul(255.0) as u8,
|
||||||
|
light,
|
||||||
|
/* | (ao as u8 >> 6) << 6
|
||||||
|
* | //((light as u8 >> 2) & 0x3F) << 0,
|
||||||
|
* | light */
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_bone_idx(self, bone_idx: u8) -> Self {
|
||||||
|
Self {
|
||||||
|
pos_norm: (self.pos_norm & !(0xF << 27)) | ((bone_idx as u32 & 0xF) << 27),
|
||||||
|
..self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,6 +176,7 @@ impl Locals {
|
|||||||
Self {
|
Self {
|
||||||
model_offs: [0.0; 3],
|
model_offs: [0.0; 3],
|
||||||
load_time: 0.0,
|
load_time: 0.0,
|
||||||
|
atlas_offs: [0; 4],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -81,5 +184,5 @@ impl Locals {
|
|||||||
pub struct TerrainPipeline;
|
pub struct TerrainPipeline;
|
||||||
|
|
||||||
impl Pipeline for TerrainPipeline {
|
impl Pipeline for TerrainPipeline {
|
||||||
type Vertex = Vertex;
|
type Vertex = Vertex; //<<ColLightFmt as gfx::format::Formatted>::Surface as gfx::format::SurfaceTyped>::DataType;
|
||||||
}
|
}
|
||||||
|
@ -130,6 +130,18 @@ pub fn create_quad(
|
|||||||
v([l, b], [uv_l, uv_b]),
|
v([l, b], [uv_l, uv_b]),
|
||||||
v([r, b], [uv_r, uv_b]),
|
v([r, b], [uv_r, uv_b]),
|
||||||
),
|
),
|
||||||
|
/* (true, true) | (false, false) => Quad::new(
|
||||||
|
v([l, t], [uv_l, uv_t]),
|
||||||
|
v([r, t], [uv_l, uv_b]),
|
||||||
|
v([r, b], [uv_r, uv_b]),
|
||||||
|
v([l, b], [uv_r, uv_t]),
|
||||||
|
),
|
||||||
|
_ => Quad::new(
|
||||||
|
v([l, t], [uv_l, uv_t]),
|
||||||
|
v([l, b], [uv_l, uv_b]),
|
||||||
|
v([r, b], [uv_r, uv_b]),
|
||||||
|
v([r, t], [uv_r, uv_t]),
|
||||||
|
) */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -89,6 +89,58 @@ where
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_immutable_raw(
|
||||||
|
factory: &mut gfx_backend::Factory,
|
||||||
|
kind: gfx::texture::Kind,
|
||||||
|
mipmap: gfx::texture::Mipmap,
|
||||||
|
data: &[&[<F::Surface as gfx::format::SurfaceTyped>::DataType]],
|
||||||
|
sampler_info: gfx::texture::SamplerInfo,
|
||||||
|
) -> Result<Self, RenderError> {
|
||||||
|
let (tex, srv) = factory
|
||||||
|
.create_texture_immutable::<F>(kind, mipmap, data)
|
||||||
|
.map_err(|err| RenderError::CombinedError(err))?;
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
tex,
|
||||||
|
srv,
|
||||||
|
sampler: factory.create_sampler(sampler_info),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_raw(
|
||||||
|
_device: &mut gfx_backend::Device,
|
||||||
|
factory: &mut gfx_backend::Factory,
|
||||||
|
kind: gfx::texture::Kind,
|
||||||
|
max_levels: u8,
|
||||||
|
bind: gfx::memory::Bind,
|
||||||
|
usage: gfx::memory::Usage,
|
||||||
|
levels: (u8, u8),
|
||||||
|
swizzle: gfx::format::Swizzle,
|
||||||
|
sampler_info: gfx::texture::SamplerInfo,
|
||||||
|
) -> Result<Self, RenderError> {
|
||||||
|
let tex = factory
|
||||||
|
.create_texture(
|
||||||
|
kind,
|
||||||
|
max_levels as gfx::texture::Level,
|
||||||
|
bind | gfx::memory::Bind::SHADER_RESOURCE,
|
||||||
|
usage,
|
||||||
|
Some(<<F as gfx::format::Formatted>::Channel as gfx::format::ChannelTyped>::get_channel_type())
|
||||||
|
)
|
||||||
|
.map_err(|err| RenderError::CombinedError(gfx::CombinedError::Texture(err)))?;
|
||||||
|
|
||||||
|
// device.cleanup();
|
||||||
|
|
||||||
|
let srv = factory
|
||||||
|
.view_texture_as_shader_resource::<F>(&tex, levels, swizzle)
|
||||||
|
.map_err(|err| RenderError::CombinedError(gfx::CombinedError::Resource(err)))?;
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
tex,
|
||||||
|
srv,
|
||||||
|
sampler: factory.create_sampler(sampler_info),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Update a texture with the given data (used for updating the glyph cache
|
/// Update a texture with the given data (used for updating the glyph cache
|
||||||
/// texture).
|
/// texture).
|
||||||
pub fn update(
|
pub fn update(
|
||||||
|
@ -3,8 +3,8 @@ use std::f32::consts::PI;
|
|||||||
use treeculler::Frustum;
|
use treeculler::Frustum;
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
const NEAR_PLANE: f32 = 0.5;
|
pub const NEAR_PLANE: f32 = 0.5;
|
||||||
const FAR_PLANE: f32 = 100000.0;
|
pub const FAR_PLANE: f32 = 100000.0;
|
||||||
|
|
||||||
const FIRST_PERSON_INTERP_TIME: f32 = 0.1;
|
const FIRST_PERSON_INTERP_TIME: f32 = 0.1;
|
||||||
const THIRD_PERSON_INTERP_TIME: f32 = 0.1;
|
const THIRD_PERSON_INTERP_TIME: f32 = 0.1;
|
||||||
@ -43,6 +43,7 @@ pub struct Camera {
|
|||||||
last_time: Option<f64>,
|
last_time: Option<f64>,
|
||||||
|
|
||||||
dependents: Dependents,
|
dependents: Dependents,
|
||||||
|
frustum: Frustum<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Camera {
|
impl Camera {
|
||||||
@ -66,6 +67,7 @@ impl Camera {
|
|||||||
proj_mat: Mat4::identity(),
|
proj_mat: Mat4::identity(),
|
||||||
cam_pos: Vec3::zero(),
|
cam_pos: Vec3::zero(),
|
||||||
},
|
},
|
||||||
|
frustum: Frustum::from_modelview_projection(Mat4::identity().into_col_arrays()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,6 +97,7 @@ impl Camera {
|
|||||||
(_, Err(_)) => self.dist,
|
(_, Err(_)) => self.dist,
|
||||||
}
|
}
|
||||||
.max(0.0)
|
.max(0.0)
|
||||||
|
// .max(NEAR_PLANE)
|
||||||
// self.dist.max(0.0)
|
// self.dist.max(0.0)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -104,20 +107,22 @@ impl Camera {
|
|||||||
* Mat4::rotation_x(self.ori.y)
|
* Mat4::rotation_x(self.ori.y)
|
||||||
* Mat4::rotation_y(self.ori.x)
|
* Mat4::rotation_y(self.ori.x)
|
||||||
* Mat4::rotation_3d(PI / 2.0, -Vec4::unit_x())
|
* Mat4::rotation_3d(PI / 2.0, -Vec4::unit_x())
|
||||||
* Mat4::translation_3d(-self.focus);
|
* Mat4::translation_3d(-self.focus.map(|e| e.fract()));
|
||||||
|
|
||||||
self.dependents.proj_mat =
|
self.dependents.proj_mat =
|
||||||
Mat4::perspective_rh_no(self.fov, self.aspect, NEAR_PLANE, FAR_PLANE);
|
Mat4::perspective_rh_no(self.fov, self.aspect, NEAR_PLANE, FAR_PLANE);
|
||||||
|
|
||||||
// TODO: Make this more efficient.
|
// TODO: Make this more efficient.
|
||||||
self.dependents.cam_pos = Vec3::from(self.dependents.view_mat.inverted() * Vec4::unit_w());
|
self.dependents.cam_pos = Vec3::from(self.dependents.view_mat.inverted() * Vec4::unit_w());
|
||||||
|
self.frustum = Frustum::from_modelview_projection(
|
||||||
|
(self.dependents.proj_mat
|
||||||
|
* self.dependents.view_mat
|
||||||
|
* Mat4::translation_3d(-self.focus.map(|e| e.trunc())))
|
||||||
|
.into_col_arrays(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn frustum(&self) -> Frustum<f32> {
|
pub fn frustum(&self) -> &Frustum<f32> { &self.frustum }
|
||||||
Frustum::from_modelview_projection(
|
|
||||||
(self.dependents.proj_mat * self.dependents.view_mat).into_col_arrays(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn dependents(&self) -> Dependents { self.dependents.clone() }
|
pub fn dependents(&self) -> Dependents { self.dependents.clone() }
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use super::load::*;
|
use super::load::*;
|
||||||
use crate::{
|
use crate::{
|
||||||
anim::{self, Skeleton},
|
anim::{self, Skeleton},
|
||||||
mesh::Meshable,
|
mesh::{greedy::GreedyMesh, Meshable},
|
||||||
render::{FigurePipeline, Mesh, Model, Renderer},
|
render::{BoneMeshes, FigureModel, FigurePipeline, Mesh, Renderer},
|
||||||
scene::camera::CameraMode,
|
scene::camera::CameraMode,
|
||||||
};
|
};
|
||||||
use common::{
|
use common::{
|
||||||
@ -21,6 +21,8 @@ use std::{
|
|||||||
};
|
};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
|
pub type FigureModelEntry = [FigureModel; 3];
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Hash, Clone)]
|
#[derive(PartialEq, Eq, Hash, Clone)]
|
||||||
enum FigureKey {
|
enum FigureKey {
|
||||||
Simple(Body),
|
Simple(Body),
|
||||||
@ -68,7 +70,7 @@ pub struct FigureModelCache<Skel = anim::character::CharacterSkeleton>
|
|||||||
where
|
where
|
||||||
Skel: Skeleton,
|
Skel: Skeleton,
|
||||||
{
|
{
|
||||||
models: HashMap<FigureKey, (([Model<FigurePipeline>; 3], Skel::Attr), u64)>,
|
models: HashMap<FigureKey, ((FigureModelEntry, Skel::Attr), u64)>,
|
||||||
manifest_indicator: ReloadIndicator,
|
manifest_indicator: ReloadIndicator,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,8 +88,8 @@ impl<Skel: Skeleton> FigureModelCache<Skel> {
|
|||||||
character_state: Option<&CharacterState>,
|
character_state: Option<&CharacterState>,
|
||||||
camera_mode: CameraMode,
|
camera_mode: CameraMode,
|
||||||
manifest_indicator: &mut ReloadIndicator,
|
manifest_indicator: &mut ReloadIndicator,
|
||||||
generate_mesh: fn(&Segment, Vec3<f32>) -> Mesh<FigurePipeline>,
|
mut generate_mesh: impl FnMut(Segment, Vec3<f32>) -> BoneMeshes,
|
||||||
) -> [Option<Mesh<FigurePipeline>>; 16] {
|
) -> [Option<BoneMeshes>; 16] {
|
||||||
match body {
|
match body {
|
||||||
Body::Humanoid(body) => {
|
Body::Humanoid(body) => {
|
||||||
let humanoid_head_spec = HumHeadSpec::load_watched(manifest_indicator);
|
let humanoid_head_spec = HumHeadSpec::load_watched(manifest_indicator);
|
||||||
@ -119,7 +121,7 @@ impl<Skel: Skeleton> FigureModelCache<Skel> {
|
|||||||
body.skin,
|
body.skin,
|
||||||
body.eyebrows,
|
body.eyebrows,
|
||||||
body.accessory,
|
body.accessory,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
CameraMode::FirstPerson => None,
|
CameraMode::FirstPerson => None,
|
||||||
},
|
},
|
||||||
@ -127,27 +129,31 @@ impl<Skel: Skeleton> FigureModelCache<Skel> {
|
|||||||
CameraMode::ThirdPerson => Some(humanoid_armor_chest_spec.mesh_chest(
|
CameraMode::ThirdPerson => Some(humanoid_armor_chest_spec.mesh_chest(
|
||||||
&body,
|
&body,
|
||||||
loadout,
|
loadout,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
CameraMode::FirstPerson => None,
|
CameraMode::FirstPerson => None,
|
||||||
},
|
},
|
||||||
match camera_mode {
|
match camera_mode {
|
||||||
CameraMode::ThirdPerson => {
|
CameraMode::ThirdPerson => Some(humanoid_armor_belt_spec.mesh_belt(
|
||||||
Some(humanoid_armor_belt_spec.mesh_belt(&body, loadout, generate_mesh))
|
&body,
|
||||||
},
|
loadout,
|
||||||
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
|
)),
|
||||||
CameraMode::FirstPerson => None,
|
CameraMode::FirstPerson => None,
|
||||||
},
|
},
|
||||||
match camera_mode {
|
match camera_mode {
|
||||||
CameraMode::ThirdPerson => {
|
CameraMode::ThirdPerson => Some(humanoid_armor_back_spec.mesh_back(
|
||||||
Some(humanoid_armor_back_spec.mesh_back(&body, loadout, generate_mesh))
|
&body,
|
||||||
},
|
loadout,
|
||||||
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
|
)),
|
||||||
CameraMode::FirstPerson => None,
|
CameraMode::FirstPerson => None,
|
||||||
},
|
},
|
||||||
match camera_mode {
|
match camera_mode {
|
||||||
CameraMode::ThirdPerson => Some(humanoid_armor_pants_spec.mesh_pants(
|
CameraMode::ThirdPerson => Some(humanoid_armor_pants_spec.mesh_pants(
|
||||||
&body,
|
&body,
|
||||||
loadout,
|
loadout,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
CameraMode::FirstPerson => None,
|
CameraMode::FirstPerson => None,
|
||||||
},
|
},
|
||||||
@ -156,7 +162,11 @@ impl<Skel: Skeleton> FigureModelCache<Skel> {
|
|||||||
{
|
{
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(humanoid_armor_hand_spec.mesh_left_hand(&body, loadout, generate_mesh))
|
Some(humanoid_armor_hand_spec.mesh_left_hand(
|
||||||
|
&body,
|
||||||
|
loadout,
|
||||||
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
|
))
|
||||||
},
|
},
|
||||||
if character_state.map(|cs| cs.is_dodge()).unwrap_or_default() {
|
if character_state.map(|cs| cs.is_dodge()).unwrap_or_default() {
|
||||||
None
|
None
|
||||||
@ -164,14 +174,14 @@ impl<Skel: Skeleton> FigureModelCache<Skel> {
|
|||||||
Some(humanoid_armor_hand_spec.mesh_right_hand(
|
Some(humanoid_armor_hand_spec.mesh_right_hand(
|
||||||
&body,
|
&body,
|
||||||
loadout,
|
loadout,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
))
|
))
|
||||||
},
|
},
|
||||||
match camera_mode {
|
match camera_mode {
|
||||||
CameraMode::ThirdPerson => Some(humanoid_armor_foot_spec.mesh_left_foot(
|
CameraMode::ThirdPerson => Some(humanoid_armor_foot_spec.mesh_left_foot(
|
||||||
&body,
|
&body,
|
||||||
loadout,
|
loadout,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
CameraMode::FirstPerson => None,
|
CameraMode::FirstPerson => None,
|
||||||
},
|
},
|
||||||
@ -179,7 +189,7 @@ impl<Skel: Skeleton> FigureModelCache<Skel> {
|
|||||||
CameraMode::ThirdPerson => Some(humanoid_armor_foot_spec.mesh_right_foot(
|
CameraMode::ThirdPerson => Some(humanoid_armor_foot_spec.mesh_right_foot(
|
||||||
&body,
|
&body,
|
||||||
loadout,
|
loadout,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
CameraMode::FirstPerson => None,
|
CameraMode::FirstPerson => None,
|
||||||
},
|
},
|
||||||
@ -188,7 +198,7 @@ impl<Skel: Skeleton> FigureModelCache<Skel> {
|
|||||||
Some(humanoid_armor_shoulder_spec.mesh_left_shoulder(
|
Some(humanoid_armor_shoulder_spec.mesh_left_shoulder(
|
||||||
&body,
|
&body,
|
||||||
loadout,
|
loadout,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
))
|
))
|
||||||
},
|
},
|
||||||
CameraMode::FirstPerson => None,
|
CameraMode::FirstPerson => None,
|
||||||
@ -198,12 +208,14 @@ impl<Skel: Skeleton> FigureModelCache<Skel> {
|
|||||||
Some(humanoid_armor_shoulder_spec.mesh_right_shoulder(
|
Some(humanoid_armor_shoulder_spec.mesh_right_shoulder(
|
||||||
&body,
|
&body,
|
||||||
loadout,
|
loadout,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
))
|
))
|
||||||
},
|
},
|
||||||
CameraMode::FirstPerson => None,
|
CameraMode::FirstPerson => None,
|
||||||
},
|
},
|
||||||
Some(mesh_glider(generate_mesh)),
|
Some(mesh_glider(|segment, offset| {
|
||||||
|
generate_mesh(segment, offset)
|
||||||
|
})),
|
||||||
if camera_mode != CameraMode::FirstPerson
|
if camera_mode != CameraMode::FirstPerson
|
||||||
|| character_state
|
|| character_state
|
||||||
.map(|cs| cs.is_attack() || cs.is_block() || cs.is_wield())
|
.map(|cs| cs.is_attack() || cs.is_block() || cs.is_wield())
|
||||||
@ -211,7 +223,7 @@ impl<Skel: Skeleton> FigureModelCache<Skel> {
|
|||||||
{
|
{
|
||||||
Some(humanoid_main_weapon_spec.mesh_main_weapon(
|
Some(humanoid_main_weapon_spec.mesh_main_weapon(
|
||||||
loadout.active_item.as_ref().map(|i| &i.item.kind),
|
loadout.active_item.as_ref().map(|i| &i.item.kind),
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@ -231,32 +243,32 @@ impl<Skel: Skeleton> FigureModelCache<Skel> {
|
|||||||
Some(quadruped_small_central_spec.mesh_head(
|
Some(quadruped_small_central_spec.mesh_head(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(quadruped_small_central_spec.mesh_chest(
|
Some(quadruped_small_central_spec.mesh_chest(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(quadruped_small_lateral_spec.mesh_foot_lf(
|
Some(quadruped_small_lateral_spec.mesh_foot_lf(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(quadruped_small_lateral_spec.mesh_foot_rf(
|
Some(quadruped_small_lateral_spec.mesh_foot_rf(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(quadruped_small_lateral_spec.mesh_foot_lb(
|
Some(quadruped_small_lateral_spec.mesh_foot_lb(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(quadruped_small_lateral_spec.mesh_foot_rb(
|
Some(quadruped_small_lateral_spec.mesh_foot_rb(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
@ -280,57 +292,57 @@ impl<Skel: Skeleton> FigureModelCache<Skel> {
|
|||||||
Some(quadruped_medium_central_spec.mesh_head_upper(
|
Some(quadruped_medium_central_spec.mesh_head_upper(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(quadruped_medium_central_spec.mesh_head_lower(
|
Some(quadruped_medium_central_spec.mesh_head_lower(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(quadruped_medium_central_spec.mesh_jaw(
|
Some(quadruped_medium_central_spec.mesh_jaw(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(quadruped_medium_central_spec.mesh_tail(
|
Some(quadruped_medium_central_spec.mesh_tail(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(quadruped_medium_central_spec.mesh_torso_f(
|
Some(quadruped_medium_central_spec.mesh_torso_f(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(quadruped_medium_central_spec.mesh_torso_b(
|
Some(quadruped_medium_central_spec.mesh_torso_b(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(quadruped_medium_central_spec.mesh_ears(
|
Some(quadruped_medium_central_spec.mesh_ears(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(quadruped_medium_lateral_spec.mesh_foot_lf(
|
Some(quadruped_medium_lateral_spec.mesh_foot_lf(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(quadruped_medium_lateral_spec.mesh_foot_rf(
|
Some(quadruped_medium_lateral_spec.mesh_foot_rf(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(quadruped_medium_lateral_spec.mesh_foot_lb(
|
Some(quadruped_medium_lateral_spec.mesh_foot_lb(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(quadruped_medium_lateral_spec.mesh_foot_rb(
|
Some(quadruped_medium_lateral_spec.mesh_foot_rb(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
@ -349,37 +361,37 @@ impl<Skel: Skeleton> FigureModelCache<Skel> {
|
|||||||
Some(bird_medium_center_spec.mesh_head(
|
Some(bird_medium_center_spec.mesh_head(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(bird_medium_center_spec.mesh_torso(
|
Some(bird_medium_center_spec.mesh_torso(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(bird_medium_center_spec.mesh_tail(
|
Some(bird_medium_center_spec.mesh_tail(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(bird_medium_lateral_spec.mesh_wing_l(
|
Some(bird_medium_lateral_spec.mesh_wing_l(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(bird_medium_lateral_spec.mesh_wing_r(
|
Some(bird_medium_lateral_spec.mesh_wing_r(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(bird_medium_lateral_spec.mesh_foot_l(
|
Some(bird_medium_lateral_spec.mesh_foot_l(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(bird_medium_lateral_spec.mesh_foot_r(
|
Some(bird_medium_lateral_spec.mesh_foot_r(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
@ -393,12 +405,24 @@ impl<Skel: Skeleton> FigureModelCache<Skel> {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
Body::FishMedium(body) => [
|
Body::FishMedium(body) => [
|
||||||
Some(mesh_fish_medium_head(body.head, generate_mesh)),
|
Some(mesh_fish_medium_head(body.head, |segment, offset| {
|
||||||
Some(mesh_fish_medium_torso(body.torso, generate_mesh)),
|
generate_mesh(segment, offset)
|
||||||
Some(mesh_fish_medium_rear(body.rear, generate_mesh)),
|
})),
|
||||||
Some(mesh_fish_medium_tail(body.tail, generate_mesh)),
|
Some(mesh_fish_medium_torso(body.torso, |segment, offset| {
|
||||||
Some(mesh_fish_medium_fin_l(body.fin_l, generate_mesh)),
|
generate_mesh(segment, offset)
|
||||||
Some(mesh_fish_medium_fin_r(body.fin_r, generate_mesh)),
|
})),
|
||||||
|
Some(mesh_fish_medium_rear(body.rear, |segment, offset| {
|
||||||
|
generate_mesh(segment, offset)
|
||||||
|
})),
|
||||||
|
Some(mesh_fish_medium_tail(body.tail, |segment, offset| {
|
||||||
|
generate_mesh(segment, offset)
|
||||||
|
})),
|
||||||
|
Some(mesh_fish_medium_fin_l(body.fin_l, |segment, offset| {
|
||||||
|
generate_mesh(segment, offset)
|
||||||
|
})),
|
||||||
|
Some(mesh_fish_medium_fin_r(body.fin_r, |segment, offset| {
|
||||||
|
generate_mesh(segment, offset)
|
||||||
|
})),
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
@ -418,82 +442,94 @@ impl<Skel: Skeleton> FigureModelCache<Skel> {
|
|||||||
Some(dragon_center_spec.mesh_head_upper(
|
Some(dragon_center_spec.mesh_head_upper(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(dragon_center_spec.mesh_head_lower(
|
Some(dragon_center_spec.mesh_head_lower(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
|
)),
|
||||||
|
Some(dragon_center_spec.mesh_jaw(
|
||||||
|
body.species,
|
||||||
|
body.body_type,
|
||||||
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(dragon_center_spec.mesh_jaw(body.species, body.body_type, generate_mesh)),
|
|
||||||
Some(dragon_center_spec.mesh_chest_front(
|
Some(dragon_center_spec.mesh_chest_front(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(dragon_center_spec.mesh_chest_rear(
|
Some(dragon_center_spec.mesh_chest_rear(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(dragon_center_spec.mesh_tail_front(
|
Some(dragon_center_spec.mesh_tail_front(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(dragon_center_spec.mesh_tail_rear(
|
Some(dragon_center_spec.mesh_tail_rear(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(dragon_lateral_spec.mesh_wing_in_l(
|
Some(dragon_lateral_spec.mesh_wing_in_l(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(dragon_lateral_spec.mesh_wing_in_r(
|
Some(dragon_lateral_spec.mesh_wing_in_r(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(dragon_lateral_spec.mesh_wing_out_l(
|
Some(dragon_lateral_spec.mesh_wing_out_l(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(dragon_lateral_spec.mesh_wing_out_r(
|
Some(dragon_lateral_spec.mesh_wing_out_r(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(dragon_lateral_spec.mesh_foot_fl(
|
Some(dragon_lateral_spec.mesh_foot_fl(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(dragon_lateral_spec.mesh_foot_fr(
|
Some(dragon_lateral_spec.mesh_foot_fr(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(dragon_lateral_spec.mesh_foot_bl(
|
Some(dragon_lateral_spec.mesh_foot_bl(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(dragon_lateral_spec.mesh_foot_br(
|
Some(dragon_lateral_spec.mesh_foot_br(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
None,
|
None,
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
Body::BirdSmall(body) => [
|
Body::BirdSmall(body) => [
|
||||||
Some(mesh_bird_small_head(body.head, generate_mesh)),
|
Some(mesh_bird_small_head(body.head, |segment, offset| {
|
||||||
Some(mesh_bird_small_torso(body.torso, generate_mesh)),
|
generate_mesh(segment, offset)
|
||||||
Some(mesh_bird_small_wing_l(body.wing_l, generate_mesh)),
|
})),
|
||||||
Some(mesh_bird_small_wing_r(body.wing_r, generate_mesh)),
|
Some(mesh_bird_small_torso(body.torso, |segment, offset| {
|
||||||
|
generate_mesh(segment, offset)
|
||||||
|
})),
|
||||||
|
Some(mesh_bird_small_wing_l(body.wing_l, |segment, offset| {
|
||||||
|
generate_mesh(segment, offset)
|
||||||
|
})),
|
||||||
|
Some(mesh_bird_small_wing_r(body.wing_r, |segment, offset| {
|
||||||
|
generate_mesh(segment, offset)
|
||||||
|
})),
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
@ -508,8 +544,12 @@ impl<Skel: Skeleton> FigureModelCache<Skel> {
|
|||||||
None,
|
None,
|
||||||
],
|
],
|
||||||
Body::FishSmall(body) => [
|
Body::FishSmall(body) => [
|
||||||
Some(mesh_fish_small_torso(body.torso, generate_mesh)),
|
Some(mesh_fish_small_torso(body.torso, |segment, offset| {
|
||||||
Some(mesh_fish_small_tail(body.tail, generate_mesh)),
|
generate_mesh(segment, offset)
|
||||||
|
})),
|
||||||
|
Some(mesh_fish_small_tail(body.tail, |segment, offset| {
|
||||||
|
generate_mesh(segment, offset)
|
||||||
|
})),
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
@ -535,57 +575,57 @@ impl<Skel: Skeleton> FigureModelCache<Skel> {
|
|||||||
Some(biped_large_center_spec.mesh_head(
|
Some(biped_large_center_spec.mesh_head(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(biped_large_center_spec.mesh_torso_upper(
|
Some(biped_large_center_spec.mesh_torso_upper(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(biped_large_center_spec.mesh_torso_lower(
|
Some(biped_large_center_spec.mesh_torso_lower(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(biped_large_lateral_spec.mesh_shoulder_l(
|
Some(biped_large_lateral_spec.mesh_shoulder_l(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(biped_large_lateral_spec.mesh_shoulder_r(
|
Some(biped_large_lateral_spec.mesh_shoulder_r(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(biped_large_lateral_spec.mesh_hand_l(
|
Some(biped_large_lateral_spec.mesh_hand_l(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(biped_large_lateral_spec.mesh_hand_r(
|
Some(biped_large_lateral_spec.mesh_hand_r(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(biped_large_lateral_spec.mesh_leg_l(
|
Some(biped_large_lateral_spec.mesh_leg_l(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(biped_large_lateral_spec.mesh_leg_r(
|
Some(biped_large_lateral_spec.mesh_leg_r(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(biped_large_lateral_spec.mesh_foot_l(
|
Some(biped_large_lateral_spec.mesh_foot_l(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(biped_large_lateral_spec.mesh_foot_r(
|
Some(biped_large_lateral_spec.mesh_foot_r(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
@ -599,51 +639,55 @@ impl<Skel: Skeleton> FigureModelCache<Skel> {
|
|||||||
let golem_lateral_spec = GolemLateralSpec::load_watched(manifest_indicator);
|
let golem_lateral_spec = GolemLateralSpec::load_watched(manifest_indicator);
|
||||||
|
|
||||||
[
|
[
|
||||||
Some(golem_center_spec.mesh_head(body.species, body.body_type, generate_mesh)),
|
Some(golem_center_spec.mesh_head(
|
||||||
|
body.species,
|
||||||
|
body.body_type,
|
||||||
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
|
)),
|
||||||
Some(golem_center_spec.mesh_torso_upper(
|
Some(golem_center_spec.mesh_torso_upper(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(golem_lateral_spec.mesh_shoulder_l(
|
Some(golem_lateral_spec.mesh_shoulder_l(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(golem_lateral_spec.mesh_shoulder_r(
|
Some(golem_lateral_spec.mesh_shoulder_r(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(golem_lateral_spec.mesh_hand_l(
|
Some(golem_lateral_spec.mesh_hand_l(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(golem_lateral_spec.mesh_hand_r(
|
Some(golem_lateral_spec.mesh_hand_r(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(golem_lateral_spec.mesh_leg_l(
|
Some(golem_lateral_spec.mesh_leg_l(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(golem_lateral_spec.mesh_leg_r(
|
Some(golem_lateral_spec.mesh_leg_r(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(golem_lateral_spec.mesh_foot_l(
|
Some(golem_lateral_spec.mesh_foot_l(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(golem_lateral_spec.mesh_foot_r(
|
Some(golem_lateral_spec.mesh_foot_r(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
@ -660,27 +704,27 @@ impl<Skel: Skeleton> FigureModelCache<Skel> {
|
|||||||
Some(critter_center_spec.mesh_head(
|
Some(critter_center_spec.mesh_head(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(critter_center_spec.mesh_chest(
|
Some(critter_center_spec.mesh_chest(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(critter_center_spec.mesh_feet_f(
|
Some(critter_center_spec.mesh_feet_f(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(critter_center_spec.mesh_feet_b(
|
Some(critter_center_spec.mesh_feet_b(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
Some(critter_center_spec.mesh_tail(
|
Some(critter_center_spec.mesh_tail(
|
||||||
body.species,
|
body.species,
|
||||||
body.body_type,
|
body.body_type,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(segment, offset),
|
||||||
)),
|
)),
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
@ -719,12 +763,13 @@ impl<Skel: Skeleton> FigureModelCache<Skel> {
|
|||||||
pub fn get_or_create_model(
|
pub fn get_or_create_model(
|
||||||
&mut self,
|
&mut self,
|
||||||
renderer: &mut Renderer,
|
renderer: &mut Renderer,
|
||||||
|
col_lights: &mut super::FigureColLights,
|
||||||
body: Body,
|
body: Body,
|
||||||
loadout: Option<&Loadout>,
|
loadout: Option<&Loadout>,
|
||||||
tick: u64,
|
tick: u64,
|
||||||
camera_mode: CameraMode,
|
camera_mode: CameraMode,
|
||||||
character_state: Option<&CharacterState>,
|
character_state: Option<&CharacterState>,
|
||||||
) -> &([Model<FigurePipeline>; 3], Skel::Attr)
|
) -> &(FigureModelEntry, Skel::Attr)
|
||||||
where
|
where
|
||||||
for<'a> &'a common::comp::Body: std::convert::TryInto<Skel::Attr>,
|
for<'a> &'a common::comp::Body: std::convert::TryInto<Skel::Attr>,
|
||||||
Skel::Attr: Default,
|
Skel::Attr: Default,
|
||||||
@ -754,58 +799,72 @@ impl<Skel: Skeleton> FigureModelCache<Skel> {
|
|||||||
.unwrap_or_else(<Skel::Attr as Default>::default);
|
.unwrap_or_else(<Skel::Attr as Default>::default);
|
||||||
|
|
||||||
let manifest_indicator = &mut self.manifest_indicator;
|
let manifest_indicator = &mut self.manifest_indicator;
|
||||||
let mut make_model = |generate_mesh| {
|
let mut make_model = |generate_mesh: for<'a> fn(&mut GreedyMesh<'a>, _, _) -> _| {
|
||||||
let mut mesh = Mesh::new();
|
let mut greedy = FigureModel::make_greedy();
|
||||||
|
let mut opaque = Mesh::new();
|
||||||
|
let mut figure_bounds = Aabb {
|
||||||
|
min: Vec3::zero(),
|
||||||
|
max: Vec3::zero(),
|
||||||
|
};
|
||||||
|
// let mut shadow = Mesh::new();
|
||||||
Self::bone_meshes(
|
Self::bone_meshes(
|
||||||
body,
|
body,
|
||||||
loadout,
|
loadout,
|
||||||
character_state,
|
character_state,
|
||||||
camera_mode,
|
camera_mode,
|
||||||
manifest_indicator,
|
manifest_indicator,
|
||||||
generate_mesh,
|
|segment, offset| generate_mesh(&mut greedy, segment, offset),
|
||||||
)
|
)
|
||||||
.iter()
|
.iter()
|
||||||
|
// .zip(&mut figure_bounds)
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter_map(|(i, bm)| bm.as_ref().map(|bm| (i, bm)))
|
.filter_map(|(i, bm)| bm.as_ref().map(|bm| (i, bm)))
|
||||||
.for_each(|(i, bone_mesh)| {
|
.for_each(|(i, (opaque_mesh/*, shadow_mesh*/, bounds)/*, bone_bounds*/)| {
|
||||||
mesh.push_mesh_map(bone_mesh, |vert| vert.with_bone_idx(i as u8))
|
// opaque.push_mesh_map(opaque_mesh, |vert| vert.with_bone_idx(i as u8));
|
||||||
|
opaque.push_mesh_map(opaque_mesh, |vert| vert.with_bone_idx(i as u8));
|
||||||
|
figure_bounds.expand_to_contain(*bounds);
|
||||||
|
// shadow.push_mesh_map(shadow_mesh, |vert| vert.with_bone_idx(i as u8));
|
||||||
});
|
});
|
||||||
renderer.create_model(&mesh).unwrap()
|
col_lights.create_figure(renderer, greedy, (opaque/*, shadow*/, figure_bounds)).unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
fn generate_mesh(
|
fn generate_mesh<'a>(
|
||||||
segment: &Segment,
|
greedy: &mut GreedyMesh<'a>,
|
||||||
|
segment: Segment,
|
||||||
offset: Vec3<f32>,
|
offset: Vec3<f32>,
|
||||||
) -> Mesh<FigurePipeline> {
|
) -> BoneMeshes {
|
||||||
Meshable::<FigurePipeline, FigurePipeline>::generate_mesh(
|
let (opaque, _, /*shadow*/_, bounds) = Meshable::<FigurePipeline, &mut GreedyMesh>::generate_mesh(
|
||||||
segment,
|
segment,
|
||||||
(offset, Vec3::one()),
|
(greedy, offset, Vec3::one()),
|
||||||
)
|
);
|
||||||
.0
|
(opaque/*, shadow*/, bounds)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_mesh_lod_mid(
|
fn generate_mesh_lod_mid<'a>(
|
||||||
segment: &Segment,
|
greedy: &mut GreedyMesh<'a>,
|
||||||
|
segment: Segment,
|
||||||
offset: Vec3<f32>,
|
offset: Vec3<f32>,
|
||||||
) -> Mesh<FigurePipeline> {
|
) -> BoneMeshes {
|
||||||
let lod_scale = Vec3::broadcast(0.6);
|
let lod_scale = Vec3::broadcast(0.6);
|
||||||
Meshable::<FigurePipeline, FigurePipeline>::generate_mesh(
|
let (opaque, _, /*shadow*/_, bounds) = Meshable::<FigurePipeline, &mut GreedyMesh>::generate_mesh(
|
||||||
&segment.scaled_by(lod_scale),
|
segment.scaled_by(lod_scale),
|
||||||
(offset * lod_scale, Vec3::one() / lod_scale),
|
(greedy, offset * lod_scale, Vec3::one() / lod_scale),
|
||||||
)
|
);
|
||||||
.0
|
(opaque/*, shadow*/, bounds)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_mesh_lod_low(
|
fn generate_mesh_lod_low<'a>(
|
||||||
segment: &Segment,
|
greedy: &mut GreedyMesh<'a>,
|
||||||
|
segment: Segment,
|
||||||
offset: Vec3<f32>,
|
offset: Vec3<f32>,
|
||||||
) -> Mesh<FigurePipeline> {
|
) -> BoneMeshes {
|
||||||
let lod_scale = Vec3::broadcast(0.3);
|
let lod_scale = Vec3::broadcast(0.3);
|
||||||
Meshable::<FigurePipeline, FigurePipeline>::generate_mesh(
|
let segment = segment.scaled_by(lod_scale);
|
||||||
&segment.scaled_by(lod_scale),
|
let (opaque, _, /*shadow*/_, bounds) = Meshable::<FigurePipeline, &mut GreedyMesh>::generate_mesh(
|
||||||
(offset * lod_scale, Vec3::one() / lod_scale),
|
segment,
|
||||||
)
|
(greedy, offset * lod_scale, Vec3::one() / lod_scale),
|
||||||
.0
|
);
|
||||||
|
(opaque/*, shadow*/, bounds)
|
||||||
}
|
}
|
||||||
|
|
||||||
(
|
(
|
||||||
@ -824,14 +883,24 @@ impl<Skel: Skeleton> FigureModelCache<Skel> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clean(&mut self, tick: u64) {
|
pub fn clean(&mut self, col_lights: &mut super::FigureColLights, tick: u64) {
|
||||||
// Check for reloaded manifests
|
// Check for reloaded manifests
|
||||||
// TODO: maybe do this in a different function, maintain?
|
// TODO: maybe do this in a different function, maintain?
|
||||||
if self.manifest_indicator.reloaded() {
|
if self.manifest_indicator.reloaded() {
|
||||||
|
col_lights.atlas.clear();
|
||||||
self.models.clear();
|
self.models.clear();
|
||||||
}
|
}
|
||||||
// TODO: Don't hard-code this.
|
// TODO: Don't hard-code this.
|
||||||
self.models
|
if tick % 60 == 0 {
|
||||||
.retain(|_, (_, last_used)| *last_used + 60 > tick);
|
self.models.retain(|_, ((models, _), last_used)| {
|
||||||
|
let alive = *last_used + 60 > tick;
|
||||||
|
if !alive {
|
||||||
|
models.iter().for_each(|model| {
|
||||||
|
col_lights.atlas.deallocate(model.allocation.id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
alive
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -4,14 +4,15 @@ use crate::{
|
|||||||
fixture::FixtureSkeleton,
|
fixture::FixtureSkeleton,
|
||||||
Animation, Skeleton,
|
Animation, Skeleton,
|
||||||
},
|
},
|
||||||
mesh::Meshable,
|
mesh::{greedy::GreedyMesh, Meshable},
|
||||||
render::{
|
render::{
|
||||||
create_pp_mesh, create_skybox_mesh, Consts, FigurePipeline, Globals, Light, Mesh, Model,
|
create_pp_mesh, create_skybox_mesh, BoneMeshes, Consts, FigureModel, FigurePipeline,
|
||||||
PostProcessLocals, PostProcessPipeline, Renderer, Shadow, SkyboxLocals, SkyboxPipeline,
|
Globals, Light, Model, PostProcessLocals, PostProcessPipeline, Renderer, Shadow,
|
||||||
|
ShadowLocals, SkyboxLocals, SkyboxPipeline,
|
||||||
},
|
},
|
||||||
scene::{
|
scene::{
|
||||||
camera::{self, Camera, CameraMode},
|
camera::{self, Camera, CameraMode},
|
||||||
figure::{load_mesh, FigureModelCache, FigureState},
|
figure::{load_mesh, FigureColLights, FigureModelCache, FigureState},
|
||||||
LodData,
|
LodData,
|
||||||
},
|
},
|
||||||
window::{Event, PressState},
|
window::{Event, PressState},
|
||||||
@ -43,8 +44,17 @@ impl ReadVol for VoidVol {
|
|||||||
fn get<'a>(&'a self, _pos: Vec3<i32>) -> Result<&'a Self::Vox, Self::Error> { Ok(&VoidVox) }
|
fn get<'a>(&'a self, _pos: Vec3<i32>) -> Result<&'a Self::Vox, Self::Error> { Ok(&VoidVox) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_mesh(segment: &Segment, offset: Vec3<f32>) -> Mesh<FigurePipeline> {
|
fn generate_mesh<'a>(
|
||||||
Meshable::<FigurePipeline, FigurePipeline>::generate_mesh(segment, (offset, Vec3::one())).0
|
greedy: &mut GreedyMesh<'a>,
|
||||||
|
segment: Segment,
|
||||||
|
offset: Vec3<f32>,
|
||||||
|
) -> BoneMeshes {
|
||||||
|
let (opaque, _, /* shadow */ _, bounds) =
|
||||||
|
Meshable::<FigurePipeline, &mut GreedyMesh>::generate_mesh(
|
||||||
|
segment,
|
||||||
|
(greedy, offset, Vec3::one()),
|
||||||
|
);
|
||||||
|
(opaque /* , shadow */, bounds)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Skybox {
|
struct Skybox {
|
||||||
@ -61,14 +71,16 @@ pub struct Scene {
|
|||||||
globals: Consts<Globals>,
|
globals: Consts<Globals>,
|
||||||
lights: Consts<Light>,
|
lights: Consts<Light>,
|
||||||
shadows: Consts<Shadow>,
|
shadows: Consts<Shadow>,
|
||||||
|
shadow_mats: Consts<ShadowLocals>,
|
||||||
camera: Camera,
|
camera: Camera,
|
||||||
|
|
||||||
skybox: Skybox,
|
skybox: Skybox,
|
||||||
postprocess: PostProcess,
|
postprocess: PostProcess,
|
||||||
lod: LodData,
|
lod: LodData,
|
||||||
map_bounds: Vec2<f32>,
|
map_bounds: Vec2<f32>,
|
||||||
backdrop: Option<(Model<FigurePipeline>, FigureState<FixtureSkeleton>)>,
|
|
||||||
|
|
||||||
|
col_lights: FigureColLights,
|
||||||
|
backdrop: Option<(FigureModel, FigureState<FixtureSkeleton>)>,
|
||||||
figure_model_cache: FigureModelCache,
|
figure_model_cache: FigureModelCache,
|
||||||
figure_state: FigureState<CharacterSkeleton>,
|
figure_state: FigureState<CharacterSkeleton>,
|
||||||
|
|
||||||
@ -109,11 +121,13 @@ impl Scene {
|
|||||||
camera.set_distance(3.4);
|
camera.set_distance(3.4);
|
||||||
camera.set_orientation(Vec3::new(start_angle, 0.0, 0.0));
|
camera.set_orientation(Vec3::new(start_angle, 0.0, 0.0));
|
||||||
|
|
||||||
|
let mut col_lights = FigureColLights::new(renderer);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
globals: renderer.create_consts(&[Globals::default()]).unwrap(),
|
globals: renderer.create_consts(&[Globals::default()]).unwrap(),
|
||||||
lights: renderer.create_consts(&[Light::default(); 32]).unwrap(),
|
lights: renderer.create_consts(&[Light::default(); 32]).unwrap(),
|
||||||
shadows: renderer.create_consts(&[Shadow::default(); 32]).unwrap(),
|
shadows: renderer.create_consts(&[Shadow::default(); 32]).unwrap(),
|
||||||
camera,
|
shadow_mats: renderer.create_consts(&[ShadowLocals::default(); 6]).unwrap(),
|
||||||
|
|
||||||
skybox: Skybox {
|
skybox: Skybox {
|
||||||
model: renderer.create_model(&create_skybox_mesh()).unwrap(),
|
model: renderer.create_model(&create_skybox_mesh()).unwrap(),
|
||||||
@ -133,6 +147,13 @@ impl Scene {
|
|||||||
|
|
||||||
backdrop: backdrop.map(|specifier| {
|
backdrop: backdrop.map(|specifier| {
|
||||||
let mut state = FigureState::new(renderer, FixtureSkeleton::new());
|
let mut state = FigureState::new(renderer, FixtureSkeleton::new());
|
||||||
|
let mut greedy = FigureModel::make_greedy();
|
||||||
|
let mesh = load_mesh(
|
||||||
|
specifier,
|
||||||
|
Vec3::new(-55.0, -49.5, -2.0),
|
||||||
|
|segment, offset| generate_mesh(&mut greedy, segment, offset),
|
||||||
|
);
|
||||||
|
let model = col_lights.create_figure(renderer, greedy, mesh).unwrap();
|
||||||
state.update(
|
state.update(
|
||||||
renderer,
|
renderer,
|
||||||
Vec3::zero(),
|
Vec3::zero(),
|
||||||
@ -141,21 +162,20 @@ impl Scene {
|
|||||||
Rgba::broadcast(1.0),
|
Rgba::broadcast(1.0),
|
||||||
15.0, // Want to get there immediately.
|
15.0, // Want to get there immediately.
|
||||||
1.0,
|
1.0,
|
||||||
|
&model,
|
||||||
0,
|
0,
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
|
&camera,
|
||||||
);
|
);
|
||||||
(
|
(
|
||||||
renderer
|
model,
|
||||||
.create_model(&load_mesh(
|
state,
|
||||||
specifier,
|
|
||||||
Vec3::new(-55.0, -49.5, -2.0),
|
|
||||||
generate_mesh,
|
|
||||||
))
|
|
||||||
.unwrap(),
|
|
||||||
state
|
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
|
col_lights,
|
||||||
|
|
||||||
|
camera,
|
||||||
|
|
||||||
turning: false,
|
turning: false,
|
||||||
char_ori: /*0.0*/-start_angle,
|
char_ori: /*0.0*/-start_angle,
|
||||||
@ -190,7 +210,12 @@ impl Scene {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn maintain(&mut self, renderer: &mut Renderer, scene_data: SceneData) {
|
pub fn maintain(
|
||||||
|
&mut self,
|
||||||
|
renderer: &mut Renderer,
|
||||||
|
scene_data: SceneData,
|
||||||
|
loadout: Option<&Loadout>,
|
||||||
|
) {
|
||||||
self.camera.update(
|
self.camera.update(
|
||||||
scene_data.time,
|
scene_data.time,
|
||||||
/* 1.0 / 60.0 */ scene_data.delta_time,
|
/* 1.0 / 60.0 */ scene_data.delta_time,
|
||||||
@ -233,7 +258,8 @@ impl Scene {
|
|||||||
error!("Renderer failed to update: {:?}", err);
|
error!("Renderer failed to update: {:?}", err);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.figure_model_cache.clean(scene_data.tick);
|
self.figure_model_cache
|
||||||
|
.clean(&mut self.col_lights, scene_data.tick);
|
||||||
|
|
||||||
if let Some(body) = scene_data.body {
|
if let Some(body) = scene_data.body {
|
||||||
let tgt_skeleton = IdleAnimation::update_skeleton(
|
let tgt_skeleton = IdleAnimation::update_skeleton(
|
||||||
@ -246,20 +272,34 @@ impl Scene {
|
|||||||
self.figure_state
|
self.figure_state
|
||||||
.skeleton_mut()
|
.skeleton_mut()
|
||||||
.interpolate(&tgt_skeleton, scene_data.delta_time);
|
.interpolate(&tgt_skeleton, scene_data.delta_time);
|
||||||
}
|
|
||||||
|
|
||||||
self.figure_state.update(
|
let model = &self
|
||||||
renderer,
|
.figure_model_cache
|
||||||
Vec3::zero(),
|
.get_or_create_model(
|
||||||
Vec3::new(self.char_ori.sin(), -self.char_ori.cos(), 0.0),
|
renderer,
|
||||||
1.0,
|
&mut self.col_lights,
|
||||||
Rgba::broadcast(1.0),
|
Body::Humanoid(body),
|
||||||
scene_data.delta_time,
|
loadout,
|
||||||
1.0,
|
scene_data.tick,
|
||||||
0,
|
CameraMode::default(),
|
||||||
true,
|
None,
|
||||||
false,
|
)
|
||||||
);
|
.0;
|
||||||
|
self.figure_state.update(
|
||||||
|
renderer,
|
||||||
|
Vec3::zero(),
|
||||||
|
Vec3::new(self.char_ori.sin(), -self.char_ori.cos(), 0.0),
|
||||||
|
1.0,
|
||||||
|
Rgba::broadcast(1.0),
|
||||||
|
scene_data.delta_time,
|
||||||
|
1.0,
|
||||||
|
&model[0],
|
||||||
|
0,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
&self.camera,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(
|
pub fn render(
|
||||||
@ -282,6 +322,7 @@ impl Scene {
|
|||||||
.figure_model_cache
|
.figure_model_cache
|
||||||
.get_or_create_model(
|
.get_or_create_model(
|
||||||
renderer,
|
renderer,
|
||||||
|
&mut self.col_lights,
|
||||||
Body::Humanoid(body),
|
Body::Humanoid(body),
|
||||||
loadout,
|
loadout,
|
||||||
tick,
|
tick,
|
||||||
@ -292,11 +333,13 @@ impl Scene {
|
|||||||
|
|
||||||
renderer.render_figure(
|
renderer.render_figure(
|
||||||
&model[0],
|
&model[0],
|
||||||
|
&self.col_lights.texture(),
|
||||||
&self.globals,
|
&self.globals,
|
||||||
self.figure_state.locals(),
|
self.figure_state.locals(),
|
||||||
self.figure_state.bone_consts(),
|
self.figure_state.bone_consts(),
|
||||||
&self.lights,
|
&self.lights,
|
||||||
&self.shadows,
|
&self.shadows,
|
||||||
|
&self.shadow_mats,
|
||||||
&self.lod.map,
|
&self.lod.map,
|
||||||
&self.lod.horizon,
|
&self.lod.horizon,
|
||||||
);
|
);
|
||||||
@ -305,11 +348,13 @@ impl Scene {
|
|||||||
if let Some((model, state)) = &self.backdrop {
|
if let Some((model, state)) = &self.backdrop {
|
||||||
renderer.render_figure(
|
renderer.render_figure(
|
||||||
model,
|
model,
|
||||||
|
&self.col_lights.texture(),
|
||||||
&self.globals,
|
&self.globals,
|
||||||
state.locals(),
|
state.locals(),
|
||||||
state.bone_consts(),
|
state.bone_consts(),
|
||||||
&self.lights,
|
&self.lights,
|
||||||
&self.shadows,
|
&self.shadows,
|
||||||
|
&self.shadow_mats,
|
||||||
&self.lod.map,
|
&self.lod.map,
|
||||||
&self.lod.horizon,
|
&self.lod.horizon,
|
||||||
);
|
);
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -157,6 +157,9 @@ impl PlayState for SessionState {
|
|||||||
let camera::Dependents {
|
let camera::Dependents {
|
||||||
view_mat, cam_pos, ..
|
view_mat, cam_pos, ..
|
||||||
} = self.scene.camera().dependents();
|
} = self.scene.camera().dependents();
|
||||||
|
let focus_pos = self.scene.camera().get_focus_pos();
|
||||||
|
let focus_off = focus_pos.map(|e| e.trunc());
|
||||||
|
let cam_pos = cam_pos + focus_off;
|
||||||
|
|
||||||
// Choose a spot above the player's head for item distance checks
|
// Choose a spot above the player's head for item distance checks
|
||||||
let player_pos = match self
|
let player_pos = match self
|
||||||
@ -189,7 +192,9 @@ impl PlayState for SessionState {
|
|||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
let cam_dir: Vec3<f32> = Vec3::from(view_mat.inverted() * -Vec4::unit_z());
|
let cam_dir: Vec3<f32> = Vec3::from(
|
||||||
|
(view_mat/* * Mat4::translation_3d(-focus_off */).inverted() * -Vec4::unit_z(),
|
||||||
|
);
|
||||||
|
|
||||||
// Check to see whether we're aiming at anything
|
// Check to see whether we're aiming at anything
|
||||||
let (build_pos, select_pos) = {
|
let (build_pos, select_pos) = {
|
||||||
@ -695,34 +700,15 @@ impl PlayState for SessionState {
|
|||||||
global_state.settings.graphics.gamma = new_gamma;
|
global_state.settings.graphics.gamma = new_gamma;
|
||||||
global_state.settings.save_to_file_warn();
|
global_state.settings.save_to_file_warn();
|
||||||
},
|
},
|
||||||
HudEvent::ChangeAaMode(new_aa_mode) => {
|
HudEvent::ChangeRenderMode(new_render_mode) => {
|
||||||
// Do this first so if it crashes the setting isn't saved :)
|
// Do this first so if it crashes the setting isn't saved :)
|
||||||
|
println!("Changing render mode: {:?}", new_render_mode);
|
||||||
global_state
|
global_state
|
||||||
.window
|
.window
|
||||||
.renderer_mut()
|
.renderer_mut()
|
||||||
.set_aa_mode(new_aa_mode)
|
.set_render_mode(new_render_mode)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
global_state.settings.graphics.aa_mode = new_aa_mode;
|
global_state.settings.graphics.render_mode = new_render_mode;
|
||||||
global_state.settings.save_to_file_warn();
|
|
||||||
},
|
|
||||||
HudEvent::ChangeCloudMode(new_cloud_mode) => {
|
|
||||||
// Do this first so if it crashes the setting isn't saved :)
|
|
||||||
global_state
|
|
||||||
.window
|
|
||||||
.renderer_mut()
|
|
||||||
.set_cloud_mode(new_cloud_mode)
|
|
||||||
.unwrap();
|
|
||||||
global_state.settings.graphics.cloud_mode = new_cloud_mode;
|
|
||||||
global_state.settings.save_to_file_warn();
|
|
||||||
},
|
|
||||||
HudEvent::ChangeFluidMode(new_fluid_mode) => {
|
|
||||||
// Do this first so if it crashes the setting isn't saved :)
|
|
||||||
global_state
|
|
||||||
.window
|
|
||||||
.renderer_mut()
|
|
||||||
.set_fluid_mode(new_fluid_mode)
|
|
||||||
.unwrap();
|
|
||||||
global_state.settings.graphics.fluid_mode = new_fluid_mode;
|
|
||||||
global_state.settings.save_to_file_warn();
|
global_state.settings.save_to_file_warn();
|
||||||
},
|
},
|
||||||
HudEvent::ChangeLanguage(new_language) => {
|
HudEvent::ChangeLanguage(new_language) => {
|
||||||
@ -736,16 +722,6 @@ 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
|
||||||
@ -799,9 +775,8 @@ 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
|
// Clear the shadow maps.
|
||||||
// start of the shadow encoder.
|
renderer.clear_shadows();
|
||||||
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
|
||||||
@ -824,6 +799,12 @@ impl PlayState for SessionState {
|
|||||||
.swap_buffers()
|
.swap_buffers()
|
||||||
.expect("Failed to swap window buffers!");
|
.expect("Failed to swap window buffers!");
|
||||||
|
|
||||||
|
/* let renderer = global_state.window.renderer_mut();
|
||||||
|
// Clear the shadow maps.
|
||||||
|
renderer.clear_shadows();
|
||||||
|
// Clear the screen
|
||||||
|
renderer.clear(); */
|
||||||
|
|
||||||
// Wait for the next tick.
|
// Wait for the next tick.
|
||||||
clock.tick(Duration::from_millis(
|
clock.tick(Duration::from_millis(
|
||||||
1000 / global_state.settings.graphics.max_fps as u64,
|
1000 / global_state.settings.graphics.max_fps as u64,
|
||||||
|
@ -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, LightingMode},
|
render::RenderMode,
|
||||||
ui::ScaleMode,
|
ui::ScaleMode,
|
||||||
window::{GameInput, KeyMouse},
|
window::{GameInput, KeyMouse},
|
||||||
};
|
};
|
||||||
@ -548,7 +548,7 @@ impl Default for Log {
|
|||||||
|
|
||||||
/// `GraphicsSettings` contains settings related to framerate and in-game
|
/// `GraphicsSettings` contains settings related to framerate and in-game
|
||||||
/// visuals.
|
/// visuals.
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub struct GraphicsSettings {
|
pub struct GraphicsSettings {
|
||||||
pub view_distance: u32,
|
pub view_distance: u32,
|
||||||
@ -557,34 +557,12 @@ pub struct GraphicsSettings {
|
|||||||
pub max_fps: u32,
|
pub max_fps: u32,
|
||||||
pub fov: u16,
|
pub fov: u16,
|
||||||
pub gamma: f32,
|
pub gamma: f32,
|
||||||
pub aa_mode: AaMode,
|
pub render_mode: RenderMode,
|
||||||
pub cloud_mode: CloudMode,
|
|
||||||
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,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for GraphicsSettings {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
view_distance: 10,
|
|
||||||
sprite_render_distance: 250,
|
|
||||||
figure_lod_render_distance: 250,
|
|
||||||
max_fps: 60,
|
|
||||||
fov: 50,
|
|
||||||
gamma: 1.0,
|
|
||||||
aa_mode: AaMode::Fxaa,
|
|
||||||
cloud_mode: CloudMode::Regular,
|
|
||||||
fluid_mode: FluidMode::Shiny,
|
|
||||||
lighting_mode: LightingMode::Ashikmin,
|
|
||||||
window_size: [1920, 1080],
|
|
||||||
fullscreen: false,
|
|
||||||
lod_detail: 500,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
pub enum AudioOutput {
|
pub enum AudioOutput {
|
||||||
/// Veloren's audio system wont work on some systems,
|
/// Veloren's audio system wont work on some systems,
|
||||||
|
@ -26,7 +26,7 @@ impl Cache {
|
|||||||
let max_texture_size = renderer.max_texture_size();
|
let max_texture_size = renderer.max_texture_size();
|
||||||
|
|
||||||
let glyph_cache_dims =
|
let glyph_cache_dims =
|
||||||
Vec2::new(w, h).map(|e| (e * GLYPH_CACHE_SIZE).min(max_texture_size as u16).max(512));
|
Vec2::new(w, h).map(|e| (e * GLYPH_CACHE_SIZE).min(max_texture_size).max(512));
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
glyph_cache: GlyphCache::builder()
|
glyph_cache: GlyphCache::builder()
|
||||||
@ -67,7 +67,7 @@ impl Cache {
|
|||||||
let max_texture_size = renderer.max_texture_size();
|
let max_texture_size = renderer.max_texture_size();
|
||||||
let cache_dims = renderer
|
let cache_dims = renderer
|
||||||
.get_resolution()
|
.get_resolution()
|
||||||
.map(|e| (e * GLYPH_CACHE_SIZE).min(max_texture_size as u16).max(512));
|
.map(|e| (e * GLYPH_CACHE_SIZE).min(max_texture_size).max(512));
|
||||||
self.glyph_cache = GlyphCache::builder()
|
self.glyph_cache = GlyphCache::builder()
|
||||||
.dimensions(cache_dims.x as u32, cache_dims.y as u32)
|
.dimensions(cache_dims.x as u32, cache_dims.y as u32)
|
||||||
.scale_tolerance(SCALE_TOLERANCE)
|
.scale_tolerance(SCALE_TOLERANCE)
|
||||||
|
@ -226,6 +226,7 @@ impl GraphicCache {
|
|||||||
// Fit into an atlas
|
// Fit into an atlas
|
||||||
let mut loc = None;
|
let mut loc = None;
|
||||||
for (atlas_idx, (ref mut atlas, _)) in self.atlases.iter_mut().enumerate() {
|
for (atlas_idx, (ref mut atlas, _)) in self.atlases.iter_mut().enumerate() {
|
||||||
|
let dims = dims.map(|e| e.max(1));
|
||||||
if let Some(rectangle) = atlas.allocate(size2(i32::from(dims.x), i32::from(dims.y)))
|
if let Some(rectangle) = atlas.allocate(size2(i32::from(dims.x), i32::from(dims.y)))
|
||||||
{
|
{
|
||||||
let aabr = aabr_from_alloc_rect(rectangle);
|
let aabr = aabr_from_alloc_rect(rectangle);
|
||||||
@ -239,6 +240,7 @@ impl GraphicCache {
|
|||||||
// Create a new atlas
|
// Create a new atlas
|
||||||
None => {
|
None => {
|
||||||
let (mut atlas, texture) = create_atlas_texture(renderer);
|
let (mut atlas, texture) = create_atlas_texture(renderer);
|
||||||
|
let dims = dims.map(|e| e.max(1));
|
||||||
let aabr = atlas
|
let aabr = atlas
|
||||||
.allocate(size2(i32::from(dims.x), i32::from(dims.y)))
|
.allocate(size2(i32::from(dims.x), i32::from(dims.y)))
|
||||||
.map(aabr_from_alloc_rect)
|
.map(aabr_from_alloc_rect)
|
||||||
@ -314,7 +316,7 @@ fn create_atlas_texture(renderer: &mut Renderer) -> (SimpleAtlasAllocator, Textu
|
|||||||
let size = Vec2::new(w, h).map(|e| {
|
let size = Vec2::new(w, h).map(|e| {
|
||||||
(e * GRAPHIC_CACHE_RELATIVE_SIZE)
|
(e * GRAPHIC_CACHE_RELATIVE_SIZE)
|
||||||
.max(512)
|
.max(512)
|
||||||
.min(max_texture_size as u16)
|
.min(max_texture_size)
|
||||||
});
|
});
|
||||||
|
|
||||||
let atlas = SimpleAtlasAllocator::new(size2(i32::from(size.x), i32::from(size.y)));
|
let atlas = SimpleAtlasAllocator::new(size2(i32::from(size.x), i32::from(size.y)));
|
||||||
|
@ -664,6 +664,13 @@ impl Ui {
|
|||||||
} else {
|
} else {
|
||||||
[p2.into_array(), p1.into_array(), p3.into_array()]
|
[p2.into_array(), p1.into_array(), p3.into_array()]
|
||||||
};
|
};
|
||||||
|
/* // If triangle is counter-clockwise, reverse it.
|
||||||
|
let (v1, v2): (Vec3<f32>, Vec3<f32>) = ((p2 - p1).into(), (p3 - p1).into());
|
||||||
|
let triangle = if v1.cross(v2).z > 0.0 {
|
||||||
|
[p2.into_array(), p1.into_array(), p3.into_array()]
|
||||||
|
} else {
|
||||||
|
[p1.into_array(), p2.into_array(), p3.into_array()]
|
||||||
|
}; */
|
||||||
mesh.push_tri(create_ui_tri(
|
mesh.push_tri(create_ui_tri(
|
||||||
triangle,
|
triangle,
|
||||||
[[0.0; 2]; 3],
|
[[0.0; 2]; 3],
|
||||||
|
@ -450,10 +450,7 @@ impl Window {
|
|||||||
factory,
|
factory,
|
||||||
win_color_view,
|
win_color_view,
|
||||||
win_depth_view,
|
win_depth_view,
|
||||||
settings.graphics.aa_mode,
|
settings.graphics.render_mode,
|
||||||
settings.graphics.cloud_mode,
|
|
||||||
settings.graphics.fluid_mode,
|
|
||||||
settings.graphics.lighting_mode,
|
|
||||||
)?,
|
)?,
|
||||||
window,
|
window,
|
||||||
cursor_grabbed: false,
|
cursor_grabbed: false,
|
||||||
|
@ -11,7 +11,7 @@ bitvec = "0.17.4"
|
|||||||
fxhash = "0.2.1"
|
fxhash = "0.2.1"
|
||||||
image = "0.22.3"
|
image = "0.22.3"
|
||||||
itertools = "0.8.2"
|
itertools = "0.8.2"
|
||||||
vek = "0.10.0"
|
vek = { version = "0.11.2", features = ["serde"] }
|
||||||
noise = { version = "0.6.0", default-features = false }
|
noise = { version = "0.6.0", default-features = false }
|
||||||
num = "0.2.0"
|
num = "0.2.0"
|
||||||
ordered-float = "1.0"
|
ordered-float = "1.0"
|
||||||
@ -29,5 +29,6 @@ serde_derive = "1.0.102"
|
|||||||
ron = "0.5.1"
|
ron = "0.5.1"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
criterion = "0.3"
|
||||||
pretty_env_logger = "0.3.0"
|
pretty_env_logger = "0.3.0"
|
||||||
minifb = "0.14.0"
|
minifb = "0.14.0"
|
||||||
|
@ -72,6 +72,8 @@ impl Civs {
|
|||||||
pub fn generate(seed: u32, sim: &mut WorldSim) -> Self {
|
pub fn generate(seed: u32, sim: &mut WorldSim) -> Self {
|
||||||
let mut this = Self::default();
|
let mut this = Self::default();
|
||||||
let rng = ChaChaRng::from_seed(seed_expan::rng_state(seed));
|
let rng = ChaChaRng::from_seed(seed_expan::rng_state(seed));
|
||||||
|
// let path_rng = RandomField::new(rng.gen());
|
||||||
|
|
||||||
let mut ctx = GenCtx { sim, rng };
|
let mut ctx = GenCtx { sim, rng };
|
||||||
|
|
||||||
for _ in 0..INITIAL_CIV_COUNT {
|
for _ in 0..INITIAL_CIV_COUNT {
|
||||||
@ -81,6 +83,30 @@ impl Civs {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* {
|
||||||
|
let v = (0..sim.chunks.len() as i32).collect::<Vec<_>>();
|
||||||
|
// Find edge wewghts.
|
||||||
|
let e = (0..sim.chunks.len() as i32)
|
||||||
|
.into_par_iter()
|
||||||
|
.flat_map(|posi| {
|
||||||
|
let pos = uniform_idx_as_vec2(posi);
|
||||||
|
NEIGHBORS
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.filter_map(|(idx, dir)| walk_in_dir(sim, pos, dir).map(|w| (w, (posi * NEIGHBORS.len() + idx) as i32)))
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
// Connect all civiizations with paths simultaneously using a minimum spanning tree.
|
||||||
|
let mst = par_boruvka(
|
||||||
|
v, e,
|
||||||
|
|u, v| vec2_as_uniform_idx(u, v) as i32,
|
||||||
|
|posi| uniform_idx_as_vec2(posi).x,
|
||||||
|
|posi| uniform_idx_as_vec2(posi).y,
|
||||||
|
);
|
||||||
|
// Add path connections for all edges.
|
||||||
|
G
|
||||||
|
} */
|
||||||
|
|
||||||
for _ in 0..INITIAL_CIV_COUNT * 3 {
|
for _ in 0..INITIAL_CIV_COUNT * 3 {
|
||||||
attempt(5, || {
|
attempt(5, || {
|
||||||
let loc = find_site_loc(&mut ctx, None)?;
|
let loc = find_site_loc(&mut ctx, None)?;
|
||||||
@ -440,6 +466,62 @@ impl Civs {
|
|||||||
Some(site)
|
Some(site)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* fn write_paths(&mut self, ctx: &mut GenCtx<impl Rng>, path_rng: &Vec2<RandomField>, paths: impl Iterator<(i32, i32, usize)>) {
|
||||||
|
paths.for_each(|(i, j, neighbor)| {
|
||||||
|
let neighbor = neighbor & 7;
|
||||||
|
let to_neighbor_dir = NEIGHBORS[neighbor];
|
||||||
|
let from_neighbor_dir = NEIGHBORS[7 - neighbor];
|
||||||
|
let from_idx = Vec2::new(i, j);
|
||||||
|
let to_idx = from_idx + to_neighbor_dir;
|
||||||
|
let from_chunk = ctx.sim.get_mut(from_idx).unwrap();
|
||||||
|
from_chunk.path.neighbors |= 1 << to_neighbor_dir;
|
||||||
|
from_chunk.path.offset = path_rng.map(|rng| (rng.get(from_idx) & 31) as f32);
|
||||||
|
let to_chunk = ctx.sim.get_mut(to_idx).unwrap();
|
||||||
|
to_chunk.path.neighbors |= 1 << from_neighbor_dir;
|
||||||
|
to_chunk.path.offset = path_rng.map(|rng| (rng.get(to_idx) & 31) as f32);
|
||||||
|
|
||||||
|
// from_idx.path.neighbors |= 1 << ((to_prev_idx as u8 + 4) % 8);
|
||||||
|
// ctx.sim.get_mut(locs[2]).unwrap().path.neighbors |=
|
||||||
|
// 1 << ((to_next_idx as u8 + 4) % 8);
|
||||||
|
// let mut chunk = ctx.sim.get_mut(locs[1]).unwrap();
|
||||||
|
// TODO: Split out so we don't run these repeatedly on the same chunk.
|
||||||
|
// to_idx.path.offset = path_rng.map(|rng| (rng.get(to_idx) & 31) as f32);
|
||||||
|
});
|
||||||
|
/* for locs in path.nodes().windows(3) {
|
||||||
|
let to_prev_idx = NEIGHBORS
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.find(|(_, dir)| **dir == locs[0] - locs[1])
|
||||||
|
.expect("Track locations must be neighbors")
|
||||||
|
.0;
|
||||||
|
let to_next_idx = NEIGHBORS
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.find(|(_, dir)| **dir == locs[2] - locs[1])
|
||||||
|
.expect("Track locations must be neighbors")
|
||||||
|
.0;
|
||||||
|
|
||||||
|
ctx.sim.get_mut(locs[0]).unwrap().path.neighbors |=
|
||||||
|
1 << ((to_prev_idx as u8 + 4) % 8);
|
||||||
|
ctx.sim.get_mut(locs[2]).unwrap().path.neighbors |=
|
||||||
|
1 << ((to_next_idx as u8 + 4) % 8);
|
||||||
|
let mut chunk = ctx.sim.get_mut(locs[1]).unwrap();
|
||||||
|
chunk.path.neighbors |=
|
||||||
|
(1 << (to_prev_idx as u8)) | (1 << (to_next_idx as u8));
|
||||||
|
chunk.path.offset = Vec2::new(
|
||||||
|
ctx.rng.gen_range(-16.0, 16.0),
|
||||||
|
ctx.rng.gen_range(-16.0, 16.0),
|
||||||
|
);
|
||||||
|
} */
|
||||||
|
|
||||||
|
/* // Take note of the track
|
||||||
|
let track = self.tracks.insert(Track { cost, path });
|
||||||
|
self.track_map
|
||||||
|
.entry(site)
|
||||||
|
.or_default()
|
||||||
|
.insert(nearby, track); */
|
||||||
|
} */
|
||||||
|
|
||||||
fn tick(&mut self, _ctx: &mut GenCtx<impl Rng>, years: f32) {
|
fn tick(&mut self, _ctx: &mut GenCtx<impl Rng>, years: f32) {
|
||||||
for site in self.sites.iter_mut() {
|
for site in self.sites.iter_mut() {
|
||||||
site.simulate(years, &self.places.get(site.place).nat_res);
|
site.simulate(years, &self.places.get(site.place).nat_res);
|
||||||
|
@ -14,9 +14,9 @@ pub mod util;
|
|||||||
|
|
||||||
// Reexports
|
// Reexports
|
||||||
pub use crate::config::CONFIG;
|
pub use crate::config::CONFIG;
|
||||||
|
pub use block::BlockGen;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
block::BlockGen,
|
|
||||||
column::{ColumnGen, ColumnSample},
|
column::{ColumnGen, ColumnSample},
|
||||||
util::{Grid, Sampler},
|
util::{Grid, Sampler},
|
||||||
};
|
};
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
// pub mod boruvka;
|
||||||
pub mod fast_noise;
|
pub mod fast_noise;
|
||||||
pub mod grid;
|
pub mod grid;
|
||||||
pub mod random;
|
pub mod random;
|
||||||
|
Loading…
Reference in New Issue
Block a user