mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Greedy messhing for shadows.
This commit is contained in:
parent
a4d87e1875
commit
560501df05
@ -76,6 +76,7 @@ void main() {
|
|||||||
// 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 * vec4(f_pos, 1);
|
||||||
|
// 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);
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,7 @@ void main() {
|
|||||||
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 / 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);
|
||||||
}
|
}
|
||||||
|
@ -32,10 +32,13 @@ float attenuation_strength(vec3 rpos) {
|
|||||||
uniform samplerCubeShadow t_shadow_maps;
|
uniform samplerCubeShadow t_shadow_maps;
|
||||||
// uniform samplerCube t_shadow_maps;
|
// uniform samplerCube t_shadow_maps;
|
||||||
|
|
||||||
|
// uniform sampler2DArray t_directed_shadow_maps;
|
||||||
|
|
||||||
float VectorToDepth (vec3 Vec)
|
float VectorToDepth (vec3 Vec)
|
||||||
{
|
{
|
||||||
vec3 AbsVec = abs(Vec);
|
vec3 AbsVec = abs(Vec);
|
||||||
float LocalZcomp = max(AbsVec.x, max(AbsVec.y, AbsVec.z));
|
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
|
// Replace f and n with the far and near plane values you used when
|
||||||
// you drew your cube map.
|
// you drew your cube map.
|
||||||
@ -43,8 +46,15 @@ float VectorToDepth (vec3 Vec)
|
|||||||
// const float n = 1.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 = (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;
|
float NormZComp = shadow_proj_factors.x - shadow_proj_factors.y / LocalZcomp;
|
||||||
|
// NormZComp = -1000.0 / (NormZComp + 10000.0);
|
||||||
return (NormZComp + 1.0) * 0.5;
|
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[]
|
const vec3 sampleOffsetDirections[20] = vec3[]
|
||||||
@ -59,27 +69,34 @@ const vec3 sampleOffsetDirections[20] = vec3[]
|
|||||||
|
|
||||||
float ShadowCalculation(uint lightIndex, vec3 fragToLight, /*float currentDepth*/vec3 fragPos)
|
float ShadowCalculation(uint lightIndex, vec3 fragToLight, /*float currentDepth*/vec3 fragPos)
|
||||||
{
|
{
|
||||||
// float shadow = 0.0;
|
if (lightIndex != 0u) {
|
||||||
float bias = 0.0;//-0.1;//0.0;//0.1
|
return 1.0;
|
||||||
// int samples = 20;
|
};
|
||||||
|
|
||||||
|
float shadow = 0.0;
|
||||||
|
float bias = -0.015;//-0.05;//-0.1;//0.0;//0.1
|
||||||
|
int samples = 20;
|
||||||
// float lightDistance = length(fragToLight);
|
// float lightDistance = length(fragToLight);
|
||||||
// float viewDistance = length(cam_pos.xyz - fragPos);
|
float viewDistance = length(cam_pos.xyz - fragPos);
|
||||||
// // float diskRadius = 0.00001;
|
// float diskRadius = 0.00001;
|
||||||
// // float diskRadius = 1.0;
|
// float diskRadius = 1.0;
|
||||||
// float diskRadius = (1.0 + (/*viewDistance*/viewDistance / screen_res.w)) / 2.0;
|
// float diskRadius = 0.05;
|
||||||
// // float diskRadius = lightDistance;
|
float diskRadius = (1.0 + (/*viewDistance*/viewDistance / screen_res.w)) / 25.0;
|
||||||
// for(int i = 0; i < samples; ++i)
|
// float diskRadius = lightDistance;
|
||||||
// {
|
for(int i = 0; i < samples; ++i)
|
||||||
// float currentDepth = VectorToDepth(fragToLight + sampleOffsetDirections[i] * diskRadius) + bias;
|
{
|
||||||
// // float closestDepth = texture(depthMap, fragToLight).r;
|
float currentDepth = VectorToDepth(fragToLight + sampleOffsetDirections[i] * diskRadius) + bias;
|
||||||
// // closestDepth *= far_plane; // Undo mapping [0;1]
|
// float closestDepth = texture(depthMap, fragToLight).r;
|
||||||
// /* if(currentDepth - bias > closestDepth)
|
// closestDepth *= far_plane; // Undo mapping [0;1]
|
||||||
// shadow += 1.0;*/
|
/* if(currentDepth - bias > closestDepth)
|
||||||
// float visibility = texture(t_shadow_maps, vec4(fragToLight, currentDepth));
|
shadow += 1.0;*/
|
||||||
// shadow += visibility;
|
float visibility = texture(t_shadow_maps, vec4(fragToLight, currentDepth)/*, -2.5*/);
|
||||||
// }
|
shadow += visibility;
|
||||||
// shadow /= float(samples);
|
// float closestDepth = texture(t_shadow_maps, vec3(fragToLight)/*, -2.5*/).r;
|
||||||
// // shadow = shadow * shadow * (3.0 - 2.0 * shadow);
|
// 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
|
// 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 bias = 0.0;///*0.05*/0.01;//0.05;// 0.05;
|
||||||
@ -95,15 +112,11 @@ float ShadowCalculation(uint lightIndex, vec3 fragToLight, /*float currentDepth*
|
|||||||
// currentDepth += bias;
|
// currentDepth += bias;
|
||||||
// currentDepth = -1000.0 / (currentDepth + 10000.0);
|
// currentDepth = -1000.0 / (currentDepth + 10000.0);
|
||||||
// currentDepth /= screen_res.w;
|
// currentDepth /= screen_res.w;
|
||||||
float currentDepth = VectorToDepth(fragToLight) + bias;
|
// float currentDepth = VectorToDepth(fragToLight) + bias;
|
||||||
if (lightIndex != 0u) {
|
|
||||||
return 1.0;
|
|
||||||
};
|
|
||||||
|
|
||||||
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*/);
|
// float visibility = texture(t_shadow_maps, vec4(fragToLight, 0.0), currentDepth);// / (screen_res.w/* - screen_res.z*/)/*1.0 -bias*//*-(currentDepth - bias) / screen_res.w*//*-screen_res.w*/);
|
||||||
|
// return visibility;
|
||||||
return visibility;
|
return shadow;
|
||||||
// return shadow;
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
float ShadowCalculation(uint lightIndex, vec3 fragToLight, /*float currentDepth*/vec3 fragPos)
|
float ShadowCalculation(uint lightIndex, vec3 fragToLight, /*float currentDepth*/vec3 fragPos)
|
||||||
@ -284,7 +297,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.
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
// 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()
|
||||||
@ -35,14 +35,14 @@ void main()
|
|||||||
// distance.
|
// distance.
|
||||||
/*if (FragLayer > 0) */{
|
/*if (FragLayer > 0) */{
|
||||||
// get distance between fragment and light source
|
// get distance between fragment and light source
|
||||||
// float lightDistance = length(FragPos - lights[((FragLayer - 1) & 31)].light_pos.xyz);
|
// float lightDistance = length(FragPos - lights[((/*FragLayer*/1 - 1) & 31)].light_pos.xyz);
|
||||||
|
|
||||||
// map to [0;1] range by dividing by far_plane
|
// // map to [0;1] range by dividing by far_plane
|
||||||
// lightDistance = lightDistance / /*FragPos.w;*/screen_res.w;
|
// lightDistance = lightDistance / screen_res.w;//FragPos.w;//screen_res.w;
|
||||||
|
|
||||||
// write this as modified depth
|
// // write this as modified depth
|
||||||
// lightDistance = -1000.0 / (lightDistance + 10000.0);
|
// // lightDistance = -1000.0 / (lightDistance + 10000.0);
|
||||||
// lightDistance /= screen_res.w;
|
// // lightDistance /= screen_res.w;
|
||||||
// gl_FragDepth = lightDistance;// / /*FragPos.w;*/screen_res.w;//-1000.0 / (lightDistance + 1000.0);//lightDistance
|
// gl_FragDepth = lightDistance;// / /*FragPos.w;*/screen_res.w;//-1000.0 / (lightDistance + 1000.0);//lightDistance
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -169,7 +169,7 @@
|
|||||||
|
|
||||||
layout (triangles/*, invocations = 6*/) in;
|
layout (triangles/*, invocations = 6*/) in;
|
||||||
|
|
||||||
layout (triangle_strip, max_vertices = /*MAX_LAYER_VERTICES_PER_FACE*/96) out;
|
layout (triangle_strip, max_vertices = /*MAX_LAYER_VERTICES_PER_FACE*//*96*/18) out;
|
||||||
|
|
||||||
struct ShadowLocals {
|
struct ShadowLocals {
|
||||||
mat4 shadowMatrices;
|
mat4 shadowMatrices;
|
||||||
@ -245,6 +245,10 @@ void main() {
|
|||||||
int layer_face = layer_base + face;
|
int layer_face = layer_base + face;
|
||||||
gl_Layer = face;//layer_face; // built-in variable that specifies to which face we render.
|
gl_Layer = face;//layer_face; // built-in variable that specifies to which face we render.
|
||||||
gl_Position = shadowMats[layer_face].shadowMatrices * vec4(FragPos, 1.0);
|
gl_Position = shadowMats[layer_face].shadowMatrices * vec4(FragPos, 1.0);
|
||||||
|
// gl_Position.z = -((gl_Position.z + screen_res.z) / (screen_res.w - screen_res.z)) * lightDistance;
|
||||||
|
// gl_Position.z = gl_Position.z / screen_res.w;
|
||||||
|
// gl_Position.z = gl_Position.z / gl_Position.w;
|
||||||
|
// gl_Position.z = -1000.0 / (gl_Position.z + 10000.0);
|
||||||
// lightDistance = -(lightDistance + screen_res.z) / (screen_res.w - screen_res.z);
|
// lightDistance = -(lightDistance + screen_res.z) / (screen_res.w - screen_res.z);
|
||||||
// gl_Position.z = lightDistance;
|
// gl_Position.z = lightDistance;
|
||||||
EmitVertex();
|
EmitVertex();
|
||||||
|
@ -27,7 +27,8 @@
|
|||||||
* */
|
* */
|
||||||
|
|
||||||
in uint v_pos_norm;
|
in uint v_pos_norm;
|
||||||
in uint v_col_light;
|
// in uint v_col_light;
|
||||||
|
// in vec4 v_pos;
|
||||||
|
|
||||||
// Light projection matrices.
|
// Light projection matrices.
|
||||||
layout (std140)
|
layout (std140)
|
||||||
@ -42,11 +43,12 @@ 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));
|
||||||
// f_pos = f_chunk_pos + model_offs;
|
|
||||||
// f_pos = v_pos;
|
|
||||||
vec3 f_pos = f_chunk_pos + model_offs;
|
vec3 f_pos = f_chunk_pos + model_offs;
|
||||||
|
// f_pos = v_pos;
|
||||||
|
// vec3 f_pos = f_chunk_pos + model_offs;
|
||||||
|
|
||||||
gl_Position = /*all_mat * */vec4(f_pos/*, 1.0*/, /*float(((f_pos_norm >> 29) & 0x7u) ^ 0x1)*/uintBitsToFloat(v_pos_norm)/*1.0*/);
|
// gl_Position = v_pos + vec4(model_offs, 0.0);
|
||||||
|
gl_Position = /*all_mat * */vec4(f_pos/*, 1.0*/, /*float(((f_pos_norm >> 29) & 0x7u) ^ 0x1)*//*uintBitsToFloat(v_pos_norm)*/1.0);
|
||||||
// shadowMapCoord = lights[gl_InstanceID].light_pos * gl_Vertex;
|
// shadowMapCoord = lights[gl_InstanceID].light_pos * gl_Vertex;
|
||||||
// vec4(v_pos, 0.0, 1.0);
|
// vec4(v_pos, 0.0, 1.0);
|
||||||
}
|
}
|
||||||
|
@ -298,9 +298,13 @@ void main() {
|
|||||||
|
|
||||||
// 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 = sqrt(dot(f_ao_vec * abs(voxel_norm), sqrt(1.0 - delta_sides * delta_sides)) / 3.0);
|
||||||
// f_ao = dot(abs(voxel_norm), f_ao_vec);
|
|
||||||
// voxel_norm = f_norm;
|
// vec3 ao_pos2 = min(fract(f_pos), 1.0 - fract(f_pos));
|
||||||
|
// f_ao = sqrt(dot(ao_pos2, ao_pos2));
|
||||||
|
// // f_ao = dot(abs(voxel_norm), f_ao_vec);
|
||||||
|
// // voxel_norm = f_norm;
|
||||||
|
|
||||||
// Note: because voxels, we reduce the normal for reflections to just its z component, dpendng on distance to camera.
|
// Note: because voxels, we reduce the normal for reflections to just its z component, dpendng on distance to camera.
|
||||||
// Idea: the closer we are to facing top-down, the more the norm should tend towards up-z.
|
// Idea: the closer we are to facing top-down, the more the norm should tend towards up-z.
|
||||||
|
@ -95,6 +95,7 @@ void main() {
|
|||||||
proj_mat *
|
proj_mat *
|
||||||
view_mat *
|
view_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 / 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);
|
||||||
}
|
}
|
||||||
|
@ -70,6 +70,8 @@ void main() {
|
|||||||
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 / 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);
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,15 @@ out vec4 tgt_color;
|
|||||||
#include <lod.glsl>
|
#include <lod.glsl>
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
// vec4 light_col = vec4(
|
||||||
|
// hash(floor(vec4(f_pos.x, 0, 0, 0))),
|
||||||
|
// hash(floor(vec4(0, f_pos.y, 0, 1))),
|
||||||
|
// hash(floor(vec4(0, 0, f_pos.z, 2))),
|
||||||
|
// 1.0
|
||||||
|
// );
|
||||||
|
// vec3 f_col = light_col.rgb;//vec4(1.0, 0.0, 0.0, 1.0);
|
||||||
|
// tgt_color = vec4(f_col, 1.0);
|
||||||
|
// return;
|
||||||
// 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 ++) {
|
||||||
@ -62,10 +71,13 @@ void main() {
|
|||||||
// // vec3 f_norm = normals[(f_pos_norm >> 29) & 0x7u];
|
// // vec3 f_norm = normals[(f_pos_norm >> 29) & 0x7u];
|
||||||
|
|
||||||
// // use the light to fragment vector to sample from the depth map
|
// // use the light to fragment vector to sample from the depth map
|
||||||
// float bias = 0.05;//0.05;
|
// float bias = 0.0;//0.05;//0.05;
|
||||||
// // float closestDepth = texture(t_shadow_maps, vec4(fragToLight, i)/*, 0.0*//*, bias*/).r;
|
// // float closestDepth = texture(t_shadow_maps, vec4(fragToLight, i)/*, 0.0*//*, bias*/).r;
|
||||||
// // float closestDepth = texture(t_shadow_maps, vec4(fragToLight, lightIndex), bias);
|
// // float closestDepth = texture(t_shadow_maps, vec4(fragToLight, lightIndex), bias);
|
||||||
// float closestDepth = texture(t_shadow_maps, vec4(fragToLight, i + 1)/*, bias*/).r;
|
// // float closestDepth = texture(t_shadow_maps, vec4(fragToLight, i + 1)/*, bias*/).r;
|
||||||
|
// float currentDepth = VectorToDepth(fragToLight) + bias;
|
||||||
|
// float closestDepth = texture(t_shadow_maps, vec3(fragToLight)/*, -2.5*/).r;
|
||||||
|
//
|
||||||
// // float visibility = texture(t_shadow_maps, vec4(fragToLight, i + 1), -(length(fragToLight) - bias)/* / screen_res.w*/);
|
// // float visibility = texture(t_shadow_maps, vec4(fragToLight, i + 1), -(length(fragToLight) - bias)/* / screen_res.w*/);
|
||||||
// // it is currently in linear range between [0,1]. Re-transform back to original value
|
// // it is currently in linear range between [0,1]. Re-transform back to original value
|
||||||
// // closestDepth *= screen_res.w; // far plane
|
// // closestDepth *= screen_res.w; // far plane
|
||||||
@ -74,7 +86,8 @@ void main() {
|
|||||||
// // float shadow = currentDepth - bias > closestDepth ? 1.0 : 0.0;
|
// // float shadow = currentDepth - bias > closestDepth ? 1.0 : 0.0;
|
||||||
|
|
||||||
// // tgt_color += light_col * vec4(vec3(/*closestDepth*/visibility/* + bias*//* / screen_res.w */) * 1.0 / light_shadow_count.x, 0.0);
|
// // tgt_color += light_col * vec4(vec3(/*closestDepth*/visibility/* + bias*//* / screen_res.w */) * 1.0 / light_shadow_count.x, 0.0);
|
||||||
// tgt_color.rgb += light_col * vec3(closestDepth + 0.05 / screen_res.w) * 1.0 /*/ light_shadow_count.x*/ * light_strength;
|
// // tgt_color.rgb += light_col * vec3(closestDepth + 0.05 / screen_res.w) * 1.0 /*/ light_shadow_count.x*/ * light_strength;
|
||||||
|
// tgt_color.rgb += light_col * vec3(closestDepth) * 1.0 / screen_res.w /*/ light_shadow_count.x*/ * light_strength;
|
||||||
// sum += light_strength;
|
// sum += light_strength;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
@ -99,6 +99,8 @@ void main() {
|
|||||||
gl_Position =
|
gl_Position =
|
||||||
all_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 / 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);
|
||||||
}
|
}
|
||||||
|
@ -7,11 +7,16 @@ use crate::render::{self, Mesh};
|
|||||||
pub trait Meshable<'a, P: render::Pipeline, T: render::Pipeline> {
|
pub trait Meshable<'a, P: render::Pipeline, T: render::Pipeline> {
|
||||||
type Pipeline: render::Pipeline;
|
type Pipeline: render::Pipeline;
|
||||||
type TranslucentPipeline: render::Pipeline;
|
type TranslucentPipeline: render::Pipeline;
|
||||||
|
type ShadowPipeline: render::Pipeline;
|
||||||
type Supplement;
|
type Supplement;
|
||||||
|
|
||||||
// Generate meshes - one opaque, one translucent
|
// Generate meshes - one opaque, one translucent, one shadow
|
||||||
fn generate_mesh(
|
fn generate_mesh(
|
||||||
&'a self,
|
&'a self,
|
||||||
supp: Self::Supplement,
|
supp: Self::Supplement,
|
||||||
) -> (Mesh<Self::Pipeline>, Mesh<Self::TranslucentPipeline>);
|
) -> (
|
||||||
|
Mesh<Self::Pipeline>,
|
||||||
|
Mesh<Self::TranslucentPipeline>,
|
||||||
|
Mesh<Self::ShadowPipeline>,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@ -20,13 +20,20 @@ where
|
|||||||
* &'a V: BaseVol<Vox=Cell>, */
|
* &'a V: BaseVol<Vox=Cell>, */
|
||||||
{
|
{
|
||||||
type Pipeline = FigurePipeline;
|
type Pipeline = FigurePipeline;
|
||||||
|
type ShadowPipeline = FigurePipeline;
|
||||||
type Supplement = (Vec3<f32>, Vec3<f32>);
|
type Supplement = (Vec3<f32>, Vec3<f32>);
|
||||||
type TranslucentPipeline = FigurePipeline;
|
type TranslucentPipeline = FigurePipeline;
|
||||||
|
|
||||||
|
// TODO: Make sprites cast shadows?
|
||||||
|
|
||||||
fn generate_mesh(
|
fn generate_mesh(
|
||||||
&'a self,
|
&'a self,
|
||||||
(offs, scale): Self::Supplement,
|
(offs, scale): Self::Supplement,
|
||||||
) -> (Mesh<Self::Pipeline>, Mesh<Self::TranslucentPipeline>) {
|
) -> (
|
||||||
|
Mesh<Self::Pipeline>,
|
||||||
|
Mesh<Self::TranslucentPipeline>,
|
||||||
|
Mesh<Self::ShadowPipeline>,
|
||||||
|
) {
|
||||||
let mut mesh = Mesh::new();
|
let mut mesh = Mesh::new();
|
||||||
|
|
||||||
let vol_iter = (self.lower_bound().x..self.upper_bound().x)
|
let vol_iter = (self.lower_bound().x..self.upper_bound().x)
|
||||||
@ -74,7 +81,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(mesh, Mesh::new())
|
(mesh, Mesh::new(), Mesh::new())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,13 +93,20 @@ where
|
|||||||
* &'a V: BaseVol<Vox=Cell>, */
|
* &'a V: BaseVol<Vox=Cell>, */
|
||||||
{
|
{
|
||||||
type Pipeline = SpritePipeline;
|
type Pipeline = SpritePipeline;
|
||||||
|
type ShadowPipeline = SpritePipeline;
|
||||||
type Supplement = (Vec3<f32>, Vec3<f32>);
|
type Supplement = (Vec3<f32>, Vec3<f32>);
|
||||||
type TranslucentPipeline = SpritePipeline;
|
type TranslucentPipeline = SpritePipeline;
|
||||||
|
|
||||||
|
// TODO: Make sprites cast shadows?
|
||||||
|
|
||||||
fn generate_mesh(
|
fn generate_mesh(
|
||||||
&'a self,
|
&'a self,
|
||||||
(offs, scale): Self::Supplement,
|
(offs, scale): Self::Supplement,
|
||||||
) -> (Mesh<Self::Pipeline>, Mesh<Self::TranslucentPipeline>) {
|
) -> (
|
||||||
|
Mesh<Self::Pipeline>,
|
||||||
|
Mesh<Self::TranslucentPipeline>,
|
||||||
|
Mesh<Self::ShadowPipeline>,
|
||||||
|
) {
|
||||||
let mut mesh = Mesh::new();
|
let mut mesh = Mesh::new();
|
||||||
|
|
||||||
let vol_iter = (self.lower_bound().x..self.upper_bound().x)
|
let vol_iter = (self.lower_bound().x..self.upper_bound().x)
|
||||||
@ -139,7 +153,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(mesh, Mesh::new())
|
(mesh, Mesh::new(), Mesh::new())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
mesh::{vol, Meshable},
|
mesh::{vol, Meshable},
|
||||||
render::{self, FluidPipeline, Mesh, TerrainPipeline},
|
render::{self, mesh::Quad, FluidPipeline, Mesh, ShadowPipeline, TerrainPipeline},
|
||||||
};
|
};
|
||||||
use common::{
|
use common::{
|
||||||
terrain::{Block, BlockKind},
|
terrain::{Block, BlockKind},
|
||||||
@ -12,6 +12,7 @@ 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;
|
||||||
|
|
||||||
trait Blendable {
|
trait Blendable {
|
||||||
fn is_blended(&self) -> bool;
|
fn is_blended(&self) -> bool;
|
||||||
@ -202,13 +203,18 @@ impl<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug>
|
|||||||
Meshable<'a, TerrainPipeline, FluidPipeline> for VolGrid2d<V>
|
Meshable<'a, TerrainPipeline, FluidPipeline> for VolGrid2d<V>
|
||||||
{
|
{
|
||||||
type Pipeline = TerrainPipeline;
|
type Pipeline = TerrainPipeline;
|
||||||
|
type ShadowPipeline = ShadowPipeline;
|
||||||
type Supplement = Aabb<i32>;
|
type Supplement = Aabb<i32>;
|
||||||
type TranslucentPipeline = FluidPipeline;
|
type TranslucentPipeline = FluidPipeline;
|
||||||
|
|
||||||
fn generate_mesh(
|
fn generate_mesh(
|
||||||
&'a self,
|
&'a self,
|
||||||
range: Self::Supplement,
|
range: Self::Supplement,
|
||||||
) -> (Mesh<Self::Pipeline>, Mesh<Self::TranslucentPipeline>) {
|
) -> (
|
||||||
|
Mesh<Self::Pipeline>,
|
||||||
|
Mesh<Self::TranslucentPipeline>,
|
||||||
|
Mesh<Self::ShadowPipeline>,
|
||||||
|
) {
|
||||||
let mut light = calc_light(range, self);
|
let mut light = calc_light(range, self);
|
||||||
|
|
||||||
let mut lowest_opaque = range.size().d;
|
let mut lowest_opaque = range.size().d;
|
||||||
@ -463,7 +469,84 @@ impl<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug>
|
|||||||
// opaque_mesh
|
// opaque_mesh
|
||||||
// });
|
// });
|
||||||
|
|
||||||
(opaque_mesh, fluid_mesh)
|
let mut shadow_mesh = Mesh::new();
|
||||||
|
|
||||||
|
let x_size = (range.size().w - 2) as usize;
|
||||||
|
let y_size = (range.size().h - 2) as usize;
|
||||||
|
let z_size = (z_end - z_start + 1) as usize;
|
||||||
|
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)
|
||||||
|
greedy_mesh_cross_section(
|
||||||
|
Vec3::new(y_size, z_size, x_size),
|
||||||
|
|pos| {
|
||||||
|
should_draw_greedy(
|
||||||
|
Vec3::new(pos.z, pos.x, pos.y),
|
||||||
|
draw_delta,
|
||||||
|
Vec3::unit_x(), /* , pos.z, 0, x_size */
|
||||||
|
|pos| flat_get(pos),
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|pos, dim, faces_forward| {
|
||||||
|
shadow_mesh.push_quad(create_quad_greedy(
|
||||||
|
Vec3::new(pos.z, pos.x, pos.y),
|
||||||
|
mesh_delta,
|
||||||
|
dim,
|
||||||
|
Vec2::new(Vec3::unit_y(), Vec3::unit_z()),
|
||||||
|
Vec3::unit_x(),
|
||||||
|
faces_forward,
|
||||||
|
));
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// y (u = z, v = x)
|
||||||
|
greedy_mesh_cross_section(
|
||||||
|
Vec3::new(z_size, x_size, y_size),
|
||||||
|
|pos| {
|
||||||
|
should_draw_greedy(
|
||||||
|
Vec3::new(pos.y, pos.z, pos.x),
|
||||||
|
draw_delta,
|
||||||
|
Vec3::unit_y(), /* , pos.z, 0, y_size */
|
||||||
|
|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(
|
||||||
|
Vec3::new(x_size, y_size, z_size),
|
||||||
|
|pos| {
|
||||||
|
should_draw_greedy(
|
||||||
|
Vec3::new(pos.x, pos.y, pos.z),
|
||||||
|
draw_delta,
|
||||||
|
Vec3::unit_z(), /* , pos.z, 0, z_size */
|
||||||
|
|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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -493,6 +576,154 @@ fn faces_to_make<M: Clone>(
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
// let origin = (uv.x * origin.x + uv.y * origin.y + norm * origin.z) +
|
||||||
|
// Vec3::new(0, 0, z_start + range.min.z - 1);//Vec3::new(-1, -1, z_start +
|
||||||
|
// range.min.z - 1);
|
||||||
|
let origin = origin.map(|e| e as f32); // + orientation.z;
|
||||||
|
// let origin = uv.x * origin.x + uv.y * origin.y + norm * origin.z +
|
||||||
|
// Vec3::new(0.0, 0.0, (z_start + range.min.z - 1) as f32);
|
||||||
|
/* if (origin.x < 0.0 || origin.y < 0.0) {
|
||||||
|
return;
|
||||||
|
} */
|
||||||
|
// let ori = if faces_forward { Vec3::new(u, v, norm) } else { Vec3::new(uv.y,
|
||||||
|
// uv.x, -norm) };
|
||||||
|
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)
|
||||||
|
};
|
||||||
|
// let (uv, norm, origin) = if faces_forward { (uv, norm, origin) } else {
|
||||||
|
// (Vec2::new(uv.y, uv.x), -norm, origin) }; let (uv, norm, origin) = if
|
||||||
|
// faces_forward { (uv, norm, origin) } else { (Vec2::new(uv.y, uv.x), -norm,
|
||||||
|
// origin/* - norm*/) }; let origin = Vec3::new(origin.x as f32., origin.y
|
||||||
|
// as f32, (origin.z + z_start) as f32); let norm = norm.map(|e| e as f32);
|
||||||
|
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(
|
||||||
|
pos: Vec3<usize>,
|
||||||
|
draw_delta: Vec3<i32>,
|
||||||
|
delta: Vec3<i32>,
|
||||||
|
/* depth, min_depth, max_depth, */ flat_get: impl Fn(Vec3<i32>) -> Block,
|
||||||
|
) -> Option<bool> {
|
||||||
|
let pos = pos.map(|e| e as i32) + draw_delta; // - delta;
|
||||||
|
//
|
||||||
|
/* if (depth as isize) <= min_depth {
|
||||||
|
// let to = flat_get(pos).is_opaque();
|
||||||
|
debug_assert!(depth <= max_depth);
|
||||||
|
/* if depth >= max_depth - 1 {
|
||||||
|
let from = flat_get(pos - delta).is_opaque();
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
} */
|
||||||
|
if flat_get(pos + delta).is_opaque() {
|
||||||
|
Some(true)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else */
|
||||||
|
{
|
||||||
|
let from = flat_get(pos - delta).is_opaque(); // map(|v| v.is_opaque()).unwrap_or(false);
|
||||||
|
//
|
||||||
|
/* if depth > max_depth {
|
||||||
|
if from {
|
||||||
|
// Backward-facing
|
||||||
|
Some(false)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else */
|
||||||
|
{
|
||||||
|
let to = flat_get(pos).is_opaque(); //map(|v| v.is_opaque()).unwrap_or(false);
|
||||||
|
if from == to {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
// If going from transparent to opaque, forward facing; otherwise, backward
|
||||||
|
// facing.
|
||||||
|
Some(from)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
impl<V: BaseVol<Vox = Block> + ReadVol + Debug> Meshable for VolGrid3d<V> {
|
impl<V: BaseVol<Vox = Block> + ReadVol + Debug> Meshable for VolGrid3d<V> {
|
||||||
type Pipeline = TerrainPipeline;
|
type Pipeline = TerrainPipeline;
|
||||||
|
@ -1,15 +1,20 @@
|
|||||||
use super::{
|
use super::{
|
||||||
super::{util::arr_to_mat, Pipeline, ShadowDepthStencilFmt, TerrainLocals},
|
super::{util::arr_to_mat, Pipeline, ShadowDepthStencilFmt, TerrainLocals},
|
||||||
terrain::Vertex,
|
|
||||||
Globals, Light, 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_pipeline_inner, gfx_vertex_struct_meta,
|
||||||
};
|
};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
gfx_defines! {
|
gfx_defines! {
|
||||||
|
vertex Vertex {
|
||||||
|
// pos: [f32; 4] = "v_pos",
|
||||||
|
pos_norm: u32 = "v_pos_norm",
|
||||||
|
// col_light: u32 = "v_col_light",
|
||||||
|
}
|
||||||
|
|
||||||
constant Locals {
|
constant Locals {
|
||||||
shadow_matrices: [[f32; 4]; 4] = "shadowMatrices",
|
shadow_matrices: [[f32; 4]; 4] = "shadowMatrices",
|
||||||
}
|
}
|
||||||
@ -35,6 +40,39 @@ gfx_defines! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Vertex {
|
||||||
|
pub fn new(pos: Vec3<f32>, norm: Vec3<f32>) -> Self {
|
||||||
|
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 }
|
||||||
|
};
|
||||||
|
// let ao = 0xFFu32;
|
||||||
|
// let light = 0xFFu32;
|
||||||
|
// let col = Rgb::new(1.0f32, 0.0, 0.0);
|
||||||
|
let meta = true;
|
||||||
|
|
||||||
|
const EXTRA_NEG_Z: f32 = 32768.0;
|
||||||
|
|
||||||
|
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,
|
||||||
|
/* 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, */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Locals {
|
impl Locals {
|
||||||
pub fn new(shadow_mat: Mat4<f32>) -> Self {
|
pub fn new(shadow_mat: Mat4<f32>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -388,7 +388,7 @@ impl Renderer {
|
|||||||
),
|
),
|
||||||
RenderError,
|
RenderError,
|
||||||
> {
|
> {
|
||||||
let levels = 1;
|
let levels = 1; //10;
|
||||||
|
|
||||||
/* let color_cty = <<TgtColorFmt as gfx::format::Formatted>::Channel as gfx::format::ChannelTyped
|
/* let color_cty = <<TgtColorFmt as gfx::format::Formatted>::Channel as gfx::format::ChannelTyped
|
||||||
>::get_channel_type();
|
>::get_channel_type();
|
||||||
@ -420,7 +420,7 @@ impl Renderer {
|
|||||||
let shadow_tex = factory
|
let shadow_tex = factory
|
||||||
.create_texture(
|
.create_texture(
|
||||||
gfx::texture::Kind::/*CubeArray*/Cube(size / 4 /* size * 2*//*, 32 */),
|
gfx::texture::Kind::/*CubeArray*/Cube(size / 4 /* size * 2*//*, 32 */),
|
||||||
1 as gfx::texture::Level,
|
levels as gfx::texture::Level,
|
||||||
gfx::memory::Bind::SHADER_RESOURCE | gfx::memory::Bind::DEPTH_STENCIL,
|
gfx::memory::Bind::SHADER_RESOURCE | gfx::memory::Bind::DEPTH_STENCIL,
|
||||||
gfx::memory::Usage::Data,
|
gfx::memory::Usage::Data,
|
||||||
Some(depth_stencil_cty),
|
Some(depth_stencil_cty),
|
||||||
@ -431,18 +431,21 @@ impl Renderer {
|
|||||||
|
|
||||||
let mut sampler_info = gfx::texture::SamplerInfo::new(
|
let mut sampler_info = gfx::texture::SamplerInfo::new(
|
||||||
gfx::texture::FilterMethod::Bilinear,
|
gfx::texture::FilterMethod::Bilinear,
|
||||||
gfx::texture::WrapMode::Border,
|
gfx::texture::WrapMode::Clamp, //Border,
|
||||||
);
|
);
|
||||||
sampler_info.comparison = Some(Comparison::LessEqual);
|
sampler_info.comparison = Some(Comparison::Less);
|
||||||
|
// sampler_info.lod_bias = (-3.0).into();
|
||||||
|
// sampler_info.lod_range = (1.into(), (levels - 1).into());
|
||||||
sampler_info.border = [1.0; 4].into();
|
sampler_info.border = [1.0; 4].into();
|
||||||
let shadow_tex_sampler = factory.create_sampler(sampler_info);
|
let shadow_tex_sampler = factory.create_sampler(sampler_info);
|
||||||
/* let tgt_shadow_view = factory.view_texture_as_depth_stencil::<ShadowDepthStencilFmt>(
|
let tgt_shadow_view = factory.view_texture_as_depth_stencil::<ShadowDepthStencilFmt>(
|
||||||
&shadow_tex,
|
&shadow_tex,
|
||||||
0,
|
0, // levels,
|
||||||
Some(1),
|
None, // Some(1),
|
||||||
gfx::texture::DepthStencilFlags::empty(),
|
gfx::texture::DepthStencilFlags::empty(),
|
||||||
)?; */
|
)?;
|
||||||
let tgt_shadow_view = factory.view_texture_as_depth_stencil_trivial(&shadow_tex)?;
|
// let tgt_shadow_view =
|
||||||
|
// factory.view_texture_as_depth_stencil_trivial(&shadow_tex)?;
|
||||||
/* let tgt_shadow_res = factory.view_texture_as_shader_resource::<TgtColorFmt>(
|
/* let tgt_shadow_res = factory.view_texture_as_shader_resource::<TgtColorFmt>(
|
||||||
&tgt_color_tex,
|
&tgt_color_tex,
|
||||||
(0, levels - 1),
|
(0, levels - 1),
|
||||||
@ -879,6 +882,7 @@ impl Renderer {
|
|||||||
/// frame.
|
/// frame.
|
||||||
pub fn render_terrain_chunk(
|
pub fn render_terrain_chunk(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
// model: &Model<shadow::ShadowPipeline>,
|
||||||
model: &Model<terrain::TerrainPipeline>,
|
model: &Model<terrain::TerrainPipeline>,
|
||||||
globals: &Consts<Globals>,
|
globals: &Consts<Globals>,
|
||||||
locals: &Consts<terrain::Locals>,
|
locals: &Consts<terrain::Locals>,
|
||||||
@ -921,7 +925,7 @@ impl Renderer {
|
|||||||
/// Queue the rendering of the player silhouette in the upcoming frame.
|
/// Queue the rendering of the player silhouette in the upcoming frame.
|
||||||
pub fn render_shadow(
|
pub fn render_shadow(
|
||||||
&mut self,
|
&mut self,
|
||||||
model: &Model<terrain::TerrainPipeline>,
|
model: &Model<shadow::ShadowPipeline>,
|
||||||
globals: &Consts<Globals>,
|
globals: &Consts<Globals>,
|
||||||
terrain_locals: &Consts<terrain::Locals>,
|
terrain_locals: &Consts<terrain::Locals>,
|
||||||
locals: &Consts<shadow::Locals>,
|
locals: &Consts<shadow::Locals>,
|
||||||
@ -1506,14 +1510,14 @@ fn create_shadow_pipeline<P: gfx::pso::PipelineInit>(
|
|||||||
// Second-depth shadow mapping: should help reduce z-fighting provided all objects
|
// Second-depth shadow mapping: should help reduce z-fighting provided all objects
|
||||||
// are "watertight" (every triangle edge is shared with at most one other
|
// are "watertight" (every triangle edge is shared with at most one other
|
||||||
// triangle); this *should* be true for Veloren.
|
// triangle); this *should* be true for Veloren.
|
||||||
cull_face: /*gfx::state::CullFace::Nothing*/match cull_face {
|
cull_face, /*gfx::state::CullFace::Nothing*//*match cull_face {
|
||||||
gfx::state::CullFace::Front => gfx::state::CullFace::Back,
|
gfx::state::CullFace::Front => gfx::state::CullFace::Back,
|
||||||
gfx::state::CullFace::Back => gfx::state::CullFace::Front,
|
gfx::state::CullFace::Back => gfx::state::CullFace::Front,
|
||||||
gfx::state::CullFace::Nothing => gfx::state::CullFace::Nothing,
|
gfx::state::CullFace::Nothing => gfx::state::CullFace::Nothing,
|
||||||
},
|
}*/
|
||||||
method: gfx::state::RasterMethod::Fill,
|
method: gfx::state::RasterMethod::Fill,
|
||||||
offset: None,//Some(gfx::state::Offset(4, /*10*/-10)),
|
offset: None, //Some(gfx::state::Offset(2, 10)),
|
||||||
samples:None,//Some(gfx::state::MultiSample),
|
samples: None, // Some(gfx::state::MultiSample),
|
||||||
},
|
},
|
||||||
pipe,
|
pipe,
|
||||||
)?,
|
)?,
|
||||||
|
@ -43,8 +43,8 @@ const SHADOW_MAX_DIST: f32 = 96.0; // The distance beyond which shadows may not
|
|||||||
// const NEAR_PLANE: f32 = 0.5;
|
// const NEAR_PLANE: f32 = 0.5;
|
||||||
// const FAR_PLANE: f32 = 100000.0;
|
// const FAR_PLANE: f32 = 100000.0;
|
||||||
|
|
||||||
const SHADOW_NEAR: f32 = 1.0; //1.0; //0.5;//1.0; // Near plane for shadow map rendering.
|
const SHADOW_NEAR: f32 = 0.25; //1.0; //0.5;//1.0; // Near plane for shadow map rendering.
|
||||||
const SHADOW_FAR: f32 = 128.0; //25.0; //100000.0;//25.0; // Far plane for shadow map rendering.
|
const SHADOW_FAR: f32 = 128.0; //100000.0;//128.0; //25.0; //100000.0;//25.0; // Far plane for shadow map rendering.
|
||||||
|
|
||||||
/// Above this speed is considered running
|
/// Above this speed is considered running
|
||||||
/// Used for first person camera effects
|
/// Used for first person camera effects
|
||||||
|
@ -2,7 +2,8 @@ use crate::{
|
|||||||
mesh::Meshable,
|
mesh::Meshable,
|
||||||
render::{
|
render::{
|
||||||
Consts, FluidPipeline, Globals, Instances, Light, Mesh, Model, Renderer, Shadow,
|
Consts, FluidPipeline, Globals, Instances, Light, Mesh, Model, Renderer, Shadow,
|
||||||
ShadowLocals, SpriteInstance, SpritePipeline, TerrainLocals, TerrainPipeline, Texture,
|
ShadowLocals, ShadowPipeline, SpriteInstance, SpritePipeline, TerrainLocals,
|
||||||
|
TerrainPipeline, Texture,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -27,10 +28,12 @@ struct TerrainChunkData {
|
|||||||
load_time: f32,
|
load_time: f32,
|
||||||
opaque_model: Model<TerrainPipeline>,
|
opaque_model: Model<TerrainPipeline>,
|
||||||
fluid_model: Option<Model<FluidPipeline>>,
|
fluid_model: Option<Model<FluidPipeline>>,
|
||||||
|
shadow_model: Model<ShadowPipeline>,
|
||||||
sprite_instances: HashMap<(BlockKind, usize), Instances<SpriteInstance>>,
|
sprite_instances: HashMap<(BlockKind, usize), Instances<SpriteInstance>>,
|
||||||
locals: Consts<TerrainLocals>,
|
locals: Consts<TerrainLocals>,
|
||||||
|
|
||||||
visible: bool,
|
visible: bool,
|
||||||
|
can_shadow: bool,
|
||||||
z_bounds: (f32, f32),
|
z_bounds: (f32, f32),
|
||||||
frustum_last_plane_index: u8,
|
frustum_last_plane_index: u8,
|
||||||
}
|
}
|
||||||
@ -48,6 +51,7 @@ struct MeshWorkerResponse {
|
|||||||
z_bounds: (f32, f32),
|
z_bounds: (f32, f32),
|
||||||
opaque_mesh: Mesh<TerrainPipeline>,
|
opaque_mesh: Mesh<TerrainPipeline>,
|
||||||
fluid_mesh: Mesh<FluidPipeline>,
|
fluid_mesh: Mesh<FluidPipeline>,
|
||||||
|
shadow_mesh: Mesh<ShadowPipeline>,
|
||||||
sprite_instances: HashMap<(BlockKind, usize), Vec<SpriteInstance>>,
|
sprite_instances: HashMap<(BlockKind, usize), Vec<SpriteInstance>>,
|
||||||
started_tick: u64,
|
started_tick: u64,
|
||||||
}
|
}
|
||||||
@ -254,12 +258,13 @@ fn mesh_worker<V: BaseVol<Vox = Block> + RectRasterableVol + ReadVol + Debug>(
|
|||||||
volume: <VolGrid2d<V> as SampleVol<Aabr<i32>>>::Sample,
|
volume: <VolGrid2d<V> as SampleVol<Aabr<i32>>>::Sample,
|
||||||
range: Aabb<i32>,
|
range: Aabb<i32>,
|
||||||
) -> MeshWorkerResponse {
|
) -> MeshWorkerResponse {
|
||||||
let (opaque_mesh, fluid_mesh) = volume.generate_mesh(range);
|
let (opaque_mesh, fluid_mesh, shadow_mesh) = volume.generate_mesh(range);
|
||||||
MeshWorkerResponse {
|
MeshWorkerResponse {
|
||||||
pos,
|
pos,
|
||||||
z_bounds,
|
z_bounds,
|
||||||
opaque_mesh,
|
opaque_mesh,
|
||||||
fluid_mesh,
|
fluid_mesh,
|
||||||
|
shadow_mesh,
|
||||||
// Extract sprite locations from volume
|
// Extract sprite locations from volume
|
||||||
sprite_instances: {
|
sprite_instances: {
|
||||||
let mut instances = HashMap::new();
|
let mut instances = HashMap::new();
|
||||||
@ -2106,6 +2111,9 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
|
shadow_model: renderer
|
||||||
|
.create_model(&response.shadow_mesh)
|
||||||
|
.expect("Failed to upload chunk mesh to the GPU!"),
|
||||||
sprite_instances: response
|
sprite_instances: response
|
||||||
.sprite_instances
|
.sprite_instances
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@ -2130,6 +2138,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
}])
|
}])
|
||||||
.expect("Failed to upload chunk locals to the GPU!"),
|
.expect("Failed to upload chunk locals to the GPU!"),
|
||||||
visible: false,
|
visible: false,
|
||||||
|
can_shadow: false,
|
||||||
z_bounds: response.z_bounds,
|
z_bounds: response.z_bounds,
|
||||||
frustum_last_plane_index: 0,
|
frustum_last_plane_index: 0,
|
||||||
});
|
});
|
||||||
@ -2155,8 +2164,8 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
// Limit focus_pos to chunk bounds and ensure the chunk is within the fog
|
// Limit focus_pos to chunk bounds and ensure the chunk is within the fog
|
||||||
// boundary
|
// boundary
|
||||||
let nearest_in_chunk = Vec2::from(focus_pos).clamped(chunk_pos, chunk_pos + chunk_sz);
|
let nearest_in_chunk = Vec2::from(focus_pos).clamped(chunk_pos, chunk_pos + chunk_sz);
|
||||||
let in_range = Vec2::<f32>::from(focus_pos).distance_squared(nearest_in_chunk)
|
let distance_2 = Vec2::<f32>::from(focus_pos).distance_squared(nearest_in_chunk);
|
||||||
< loaded_distance.powf(2.0);
|
let in_range = distance_2 < loaded_distance.powf(2.0);
|
||||||
|
|
||||||
if !in_range {
|
if !in_range {
|
||||||
chunk.visible = in_range;
|
chunk.visible = in_range;
|
||||||
@ -2176,6 +2185,9 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
|
|
||||||
chunk.frustum_last_plane_index = last_plane_index;
|
chunk.frustum_last_plane_index = last_plane_index;
|
||||||
chunk.visible = in_frustum;
|
chunk.visible = in_frustum;
|
||||||
|
// FIXME: Hack that only works when only the lantern casts point shadows
|
||||||
|
// (and hardcodes the shadow distance). Should ideally exist per-light, too.
|
||||||
|
chunk.can_shadow = distance_2 < (128.0 * 128.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2207,11 +2219,12 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
.take(self.chunks.len());
|
.take(self.chunks.len());
|
||||||
|
|
||||||
// Shadows
|
// Shadows
|
||||||
|
// let mut shadow_vertex_count = 0;
|
||||||
for (_, chunk) in chunk_iter.clone() {
|
for (_, chunk) in chunk_iter.clone() {
|
||||||
/* if chunk.visible */
|
if chunk.can_shadow {
|
||||||
{
|
// shadow_vertex_count += chunk.shadow_model.vertex_range.len();
|
||||||
renderer.render_shadow(
|
renderer.render_shadow(
|
||||||
&chunk.opaque_model,
|
&chunk.shadow_model,
|
||||||
globals,
|
globals,
|
||||||
&chunk.locals,
|
&chunk.locals,
|
||||||
shadow_mats,
|
shadow_mats,
|
||||||
@ -2227,10 +2240,13 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
renderer.flush_shadows();
|
renderer.flush_shadows();
|
||||||
|
|
||||||
// Terrain
|
// Terrain
|
||||||
|
// let mut terrain_vertex_count = 0;
|
||||||
for (_, chunk) in chunk_iter {
|
for (_, chunk) in chunk_iter {
|
||||||
|
// terrain_vertex_count += chunk.opaque_model.vertex_range.len();
|
||||||
if chunk.visible {
|
if chunk.visible {
|
||||||
renderer.render_terrain_chunk(
|
renderer.render_terrain_chunk(
|
||||||
&chunk.opaque_model,
|
&chunk.opaque_model,
|
||||||
|
// &chunk.shadow_model,
|
||||||
globals,
|
globals,
|
||||||
&chunk.locals,
|
&chunk.locals,
|
||||||
lights,
|
lights,
|
||||||
@ -2240,6 +2256,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// println!("Vertex count (shadow / terrain / ratio): {:?} / {:?} / {:?}", shadow_vertex_count, terrain_vertex_count, shadow_vertex_count as f64 / terrain_vertex_count as f64);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_translucent(
|
pub fn render_translucent(
|
||||||
|
Loading…
Reference in New Issue
Block a user