mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Shadow maps work for lantern.
This commit is contained in:
parent
243d0837b8
commit
a4d87e1875
@ -1,4 +1,4 @@
|
||||
#version 400 core
|
||||
#version 330 core
|
||||
|
||||
#include <constants.glsl>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 400 core
|
||||
#version 330 core
|
||||
|
||||
#include <constants.glsl>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 400 core
|
||||
#version 330 core
|
||||
|
||||
#include <constants.glsl>
|
||||
|
||||
|
@ -10,6 +10,7 @@ uniform u_globals {
|
||||
vec4 tick;
|
||||
vec4 screen_res;
|
||||
uvec4 light_shadow_count;
|
||||
vec4 shadow_proj_factors;
|
||||
uvec4 medium;
|
||||
ivec4 select_pos;
|
||||
vec4 gamma;
|
||||
|
@ -3,6 +3,7 @@
|
||||
struct Light {
|
||||
vec4 light_pos;
|
||||
vec4 light_col;
|
||||
// mat4 light_proj;
|
||||
};
|
||||
|
||||
layout (std140)
|
||||
@ -26,27 +27,86 @@ float attenuation_strength(vec3 rpos) {
|
||||
}
|
||||
|
||||
#ifdef HAS_SHADOW_MAPS
|
||||
uniform samplerCubeArrayShadow t_shadow_maps;
|
||||
// uniform samplerCubeArrayShadow t_shadow_maps;
|
||||
// uniform samplerCubeArray t_shadow_maps;
|
||||
uniform samplerCubeShadow t_shadow_maps;
|
||||
// uniform samplerCube t_shadow_maps;
|
||||
|
||||
float ShadowCalculation(uint lightIndex, vec3 fragToLight, float currentDepth)
|
||||
float VectorToDepth (vec3 Vec)
|
||||
{
|
||||
// return 1.0;
|
||||
vec3 AbsVec = abs(Vec);
|
||||
float LocalZcomp = max(AbsVec.x, max(AbsVec.y, AbsVec.z));
|
||||
|
||||
// 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 = shadow_proj_factors.x - shadow_proj_factors.y / LocalZcomp;
|
||||
return (NormZComp + 1.0) * 0.5;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
// float shadow = 0.0;
|
||||
float bias = 0.0;//-0.1;//0.0;//0.1
|
||||
// int samples = 20;
|
||||
// float lightDistance = length(fragToLight);
|
||||
// float viewDistance = length(cam_pos.xyz - fragPos);
|
||||
// // float diskRadius = 0.00001;
|
||||
// // float diskRadius = 1.0;
|
||||
// float diskRadius = (1.0 + (/*viewDistance*/viewDistance / screen_res.w)) / 2.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));
|
||||
// shadow += visibility;
|
||||
// }
|
||||
// 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;
|
||||
// float closestDepth = texture(t_shadow_maps, vec4(fragToLight, lightIndex)/*, 0.0*//*, 0.0*//*, bias*/).r;
|
||||
// // float closestDepth = texture(t_shadow_maps, vec4(fragToLight, lightIndex), bias);
|
||||
// // it is currently in linear range between [0,1]. Re-transform back to original value
|
||||
// closestDepth *= screen_res.w; // far plane
|
||||
// // now test for shadows
|
||||
// // float shadow = /*currentDepth*/(screen_res.w - bias) > closestDepth ? 1.0 : 0.0;
|
||||
// float shadow = currentDepth - bias > closestDepth ? 1.0 : 0.0;
|
||||
// float 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), (currentDepth/* + screen_res.z*/) / screen_res.w);// / (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, 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;
|
||||
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*/);
|
||||
|
||||
return visibility;
|
||||
// return shadow;
|
||||
}
|
||||
#else
|
||||
float ShadowCalculation(uint lightIndex, vec3 fragToLight, float currentDepth)
|
||||
float ShadowCalculation(uint lightIndex, vec3 fragToLight, /*float currentDepth*/vec3 fragPos)
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
@ -164,7 +224,7 @@ float lights_at(vec3 wpos, vec3 wnorm, vec3 /*cam_to_frag*/view_dir, vec3 mu, ve
|
||||
// Multiply the vec3 only once
|
||||
const float PI = 3.1415926535897932384626433832795;
|
||||
const float PI_2 = 2 * PI;
|
||||
float square_factor = /*2.0 * PI_2 * */2.0 * L.light_col.a;
|
||||
float square_factor = /*2.0 * PI_2 * *//*2.0 * */L.light_col.a;
|
||||
vec3 color = /*srgb_to_linear*/L.light_col.rgb;
|
||||
|
||||
// // Only access the array once
|
||||
@ -199,9 +259,11 @@ float lights_at(vec3 wpos, vec3 wnorm, vec3 /*cam_to_frag*/view_dir, vec3 mu, ve
|
||||
is_direct = true;
|
||||
#endif
|
||||
vec3 direct_light = PI * color * strength * square_factor * light_reflection_factor(/*direct_norm_dir*/wnorm, /*cam_to_frag*/view_dir, direct_light_dir, k_d, k_s, alpha, voxel_lighting);
|
||||
float computed_shadow = ShadowCalculation(i, -difference, light_distance);
|
||||
directed_light += /*is_direct ? */max(computed_shadow, /*LIGHT_AMBIENCE*/0.0) * direct_light * square_factor/* : vec3(0.0)*/;
|
||||
ambient_light += is_direct ? vec3(0.0) : vec3(0.0); // direct_light * square_factor * LIGHT_AMBIENCE;
|
||||
float computed_shadow = ShadowCalculation(i, -difference, 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 ? mix(/*LIGHT_AMBIENCE*/0.0, 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 += direct_light * (1.0 - square_factor * LIGHT_AMBIENCE);
|
||||
|
||||
vec3 cam_light_diff = light_pos - focus_pos.xyz;
|
||||
float cam_distance_2 = dot(cam_light_diff, cam_light_diff);// + 0.0001;
|
||||
|
@ -513,8 +513,8 @@ vec3 illuminate(float max_light, vec3 view_dir, /*vec3 max_light, */vec3 emitted
|
||||
// vec3 c = sqrt(col_adjusted) * T;
|
||||
// vec3 c = /*col_adjusted * */col_adjusted * T;
|
||||
|
||||
return color;
|
||||
// return c;
|
||||
// return color;
|
||||
return c;
|
||||
// float sum_col = color.r + color.g + color.b;
|
||||
// return /*srgb_to_linear*/(/*0.5*//*0.125 * */vec3(pow(color.x, gamma), pow(color.y, gamma), pow(color.z, gamma)));
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
// However, in the future we might apply some depth transforms here.
|
||||
|
||||
#version 330 core
|
||||
// #extension ARB_texture_storage : enable
|
||||
|
||||
#include <constants.glsl>
|
||||
|
||||
@ -25,17 +26,23 @@
|
||||
// Currently, we only need lights for the light position
|
||||
#include <light.glsl>
|
||||
|
||||
in vec4 FragPos; // FragPos from GS (output per emitvertex)
|
||||
flat in int FragLayer;
|
||||
// in vec3 FragPos; // FragPos from GS (output per emitvertex)
|
||||
// flat in int FragLayer;
|
||||
|
||||
void main()
|
||||
{
|
||||
// get distance between fragment and light source
|
||||
float lightDistance = length(FragPos.xyz - lights[FragLayer & 31].light_pos.xyz);
|
||||
// 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 - 1) & 31)].light_pos.xyz);
|
||||
|
||||
// map to [0;1] range by dividing by far_plane
|
||||
lightDistance = lightDistance / /*FragPos.w;*/screen_res.w;
|
||||
// map to [0;1] range by dividing by far_plane
|
||||
// lightDistance = lightDistance / /*FragPos.w;*/screen_res.w;
|
||||
|
||||
// write this as modified depth
|
||||
gl_FragDepth = lightDistance;
|
||||
// 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
|
||||
}
|
||||
}
|
||||
|
@ -2,10 +2,30 @@
|
||||
|
||||
// NOTE: We only technically need this for cube map arrays and geometry shader
|
||||
// instancing.
|
||||
#version 400 core
|
||||
#version 330 core
|
||||
// #extension ARB_texture_storage : enable
|
||||
|
||||
// Currently, we only need globals for the max light count (light_shadow_count.x).
|
||||
#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 max light count (light_shadow_count.x)
|
||||
// and the far plane (scene_res.z).
|
||||
#include <globals.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
|
||||
// each.
|
||||
@ -140,14 +160,14 @@
|
||||
// Since wgpu doesn't support geometry shaders anyway, it seems likely that we'll have
|
||||
// to do the multiple draw calls, anyway... I don't think gl_Layer can be set from
|
||||
// outside a geometry shader. But in wgpu, such a thing is much cheaper, anyway.
|
||||
#define MAX_POINT_LIGHTS 32
|
||||
#define MAX_POINT_LIGHTS 31
|
||||
|
||||
// We use geometry shader instancing to construct each face separately.
|
||||
#define MAX_LAYER_VERTICES_PER_FACE (MAX_POINT_LIGHTS * VERTICES_PER_FACE)
|
||||
|
||||
#define MAX_LAYER_FACES (MAX_POINT_LIGHTS * FACES_PER_POINT_LIGHT)
|
||||
|
||||
layout (triangles, invocations = 6) in;
|
||||
layout (triangles/*, invocations = 6*/) in;
|
||||
|
||||
layout (triangle_strip, max_vertices = /*MAX_LAYER_VERTICES_PER_FACE*/96) out;
|
||||
|
||||
@ -166,33 +186,70 @@ uniform u_light_shadows {
|
||||
// 128, which would mean FragPos would sum to 4 * 3 * 32 = 384; this could be
|
||||
// remedied only by setting MAX_POINT_LIGHTS to ), we might enable it again soon.
|
||||
//
|
||||
out vec4 FragPos; // FragPos from GS (output per emitvertex)
|
||||
flat out int FragLayer; // Current layer
|
||||
// out vec3 FragPos; // FragPos from GS (output per emitvertex)
|
||||
// flat out int FragLayer; // Current layer
|
||||
|
||||
// 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));
|
||||
|
||||
void main() {
|
||||
// return;
|
||||
// NOTE: Assuming that light_shadow_count.x < MAX_POINT_LIGHTS. We could min
|
||||
// it, but that might make this less optimized, and I'd like to keep this loop as
|
||||
// optimized as is reasonably possible.
|
||||
int face = gl_InvocationID;
|
||||
// int face = gl_InvocationID;
|
||||
|
||||
for (int layer = 0; layer < light_shadow_count.x; ++layer)
|
||||
// Part 1: emit directed lights.
|
||||
/* if (face <= light_shadow_count.z) {
|
||||
// Directed light.
|
||||
for(int i = 0; i < VERTICES_PER_FACE; ++i) // for each triangle vertex
|
||||
{
|
||||
// NOTE: See above, we don't make FragPos a uniform.
|
||||
FragPos = gl_in[i].gl_Position;
|
||||
FragLayer = 0; // 0 is the directed light layer.
|
||||
// vec4 FragPos = gl_in[i].gl_Position;
|
||||
gl_Layer = i; // built-in variable that specifies to which face we render.
|
||||
gl_Position = shadowMats[i].shadowMatrices * FragPos;
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
} */
|
||||
|
||||
// Part 2: emit point lights.
|
||||
/* if (light_shadow_count.x == 1) {
|
||||
return;
|
||||
} */
|
||||
for (int layer = 1; layer <= /*light_shadow_count.x*/1; ++layer)
|
||||
{
|
||||
int layer_base = layer * FACES_PER_POINT_LIGHT;
|
||||
// We use instancing here in order to increase the number of emitted vertices.
|
||||
// int face = gl_InvocationID;
|
||||
// for(int face = 0; face < FACES_PER_POINT_LIGHT; ++face)
|
||||
// {
|
||||
int layer_face = layer * FACES_PER_POINT_LIGHT + face;
|
||||
for(int 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;
|
||||
for(int i = 0; i < VERTICES_PER_FACE; ++i) // for each triangle vertex
|
||||
{
|
||||
// NOTE: See above, we don't make FragPos a uniform.
|
||||
FragPos = gl_in[i].gl_Position;
|
||||
FragLayer = layer;
|
||||
vec3 FragPos = gl_in[i].gl_Position.xyz;
|
||||
// FragPos = gl_in[i].gl_Position.xyz;
|
||||
// FragLayer = layer;
|
||||
// float lightDistance = length(FragPos - lights[((layer - 1) & 31)].light_pos.xyz);
|
||||
// lightDistance /= screen_res.w;
|
||||
|
||||
// vec4 FragPos = gl_in[i].gl_Position;
|
||||
gl_Layer = layer_face; // built-in variable that specifies to which face we render.
|
||||
gl_Position = shadowMats[layer_face].shadowMatrices * FragPos;
|
||||
// NOTE: Our normals map to the same thing as cube map normals, *except* that their normal direction is
|
||||
// swapped; we can fix this by doing normal ^ 0x1u. However, we also want to cull back faces, not front
|
||||
// faces, so we only care about the shadow cast by the *back* of the triangle, which means we ^ 0x1u
|
||||
// again and cancel it out.
|
||||
// int face = int(((floatBitsToUint(gl_Position.w) >> 29) & 0x7u) ^ 0x1u);
|
||||
int layer_face = layer_base + face;
|
||||
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);
|
||||
// lightDistance = -(lightDistance + screen_res.z) / (screen_res.w - screen_res.z);
|
||||
// gl_Position.z = lightDistance;
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
#version 330 core
|
||||
// #extension ARB_texture_storage : enable
|
||||
|
||||
#include <constants.glsl>
|
||||
|
||||
@ -45,7 +46,7 @@ void main() {
|
||||
// f_pos = v_pos;
|
||||
vec3 f_pos = f_chunk_pos + model_offs;
|
||||
|
||||
gl_Position = /*all_mat * */vec4(f_pos, 1.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;
|
||||
// vec4(v_pos, 0.0, 1.0);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 400 core
|
||||
#version 330 core
|
||||
|
||||
#include <constants.glsl>
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
#version 400 core
|
||||
#version 330 core
|
||||
// #extension GL_ARB_texture_storage : require
|
||||
|
||||
#include <constants.glsl>
|
||||
|
||||
@ -38,34 +39,50 @@ out vec4 tgt_color;
|
||||
|
||||
void main() {
|
||||
// tgt_color = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
// for (uint i = 0u; i < light_shadow_count.x; i ++) {
|
||||
// float sum = 0.0;
|
||||
// for (uint i = 0u; i < /* 6 * */light_shadow_count.x; i ++) {
|
||||
// // uint i = 1u;
|
||||
// Light L = lights[i];
|
||||
// Light L = lights[i/* / 6*/];
|
||||
|
||||
// vec4 light_col = vec4(
|
||||
// /* vec4 light_col = vec4(
|
||||
// hash(vec4(1.0, 0.0, 0.0, i)),
|
||||
// hash(vec4(1.0, 1.0, 0.0, i)),
|
||||
// hash(vec4(1.0, 0.0, 1.0, i)),
|
||||
// 1.0
|
||||
// );
|
||||
// ); */
|
||||
// vec3 light_col = vec3(1.0);//L.light_col.rgb;
|
||||
// float light_strength = L.light_col.a / 255.0;
|
||||
// // float light_strength = 1.0 / light_shadow_count.x;
|
||||
|
||||
// vec3 light_pos = L.light_pos.xyz;
|
||||
|
||||
// // Pre-calculate difference between light and fragment
|
||||
// vec3 fragToLight = f_pos - light_pos;
|
||||
|
||||
// // vec3 f_norm = normals[(f_pos_norm >> 29) & 0x7u];
|
||||
|
||||
// // use the light to fragment vector to sample from the depth map
|
||||
// float bias = 0.05;//0.05;
|
||||
// // float closestDepth = texture(t_shadow_maps, vec4(fragToLight, i)/*, 0.0*//*, bias*/).r;
|
||||
// // float closestDepth = texture(t_shadow_maps, vec4(fragToLight, lightIndex), bias);
|
||||
// float visibility = texture(t_shadow_maps, vec4(fragToLight, i), (length(fragToLight) - bias)/* / screen_res.w*/);
|
||||
// float closestDepth = texture(t_shadow_maps, vec4(fragToLight, i + 1)/*, bias*/).r;
|
||||
// // 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
|
||||
// // closestDepth *= screen_res.w; // far plane
|
||||
// // now test for shadows
|
||||
// // float shadow = /*currentDepth*/(screen_res.w - bias) > closestDepth ? 1.0 : 0.0;
|
||||
// // float shadow = currentDepth - bias > closestDepth ? 1.0 : 0.0;
|
||||
|
||||
// tgt_color += light_col * vec4(vec3(/*closestDepth*/visibility/* + bias*//* / screen_res.w */) * 1.0 / light_shadow_count.x, 0.0);
|
||||
// // 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;
|
||||
// sum += light_strength;
|
||||
// }
|
||||
|
||||
// /* if (light_shadow_count.x == 1) {
|
||||
// tgt_color.rgb = vec3(0.0);
|
||||
// } */
|
||||
// if (sum > 0.0) {
|
||||
// tgt_color.rgb /= sum;
|
||||
// }
|
||||
// return;
|
||||
|
||||
|
@ -14,6 +14,10 @@ use common::terrain::BlockKind;
|
||||
use gfx::{self, gfx_constant_struct_meta, gfx_defines, gfx_impl_struct_meta};
|
||||
use vek::*;
|
||||
|
||||
pub const MAX_POINT_LIGHT_COUNT: usize = 32;
|
||||
pub const MAX_FIGURE_SHADOW_COUNT: usize = 24;
|
||||
pub const MAX_DIRECTED_LIGHT_COUNT: usize = 6;
|
||||
|
||||
gfx_defines! {
|
||||
constant Globals {
|
||||
view_mat: [[f32; 4]; 4] = "view_mat",
|
||||
@ -37,6 +41,7 @@ gfx_defines! {
|
||||
/// w, z represent the near and far planes of the shadow map.
|
||||
screen_res: [f32; 4] = "screen_res",
|
||||
light_shadow_count: [u32; 4] = "light_shadow_count",
|
||||
shadow_proj_factors: [f32; 4] = "shadow_proj_factors",
|
||||
medium: [u32; 4] = "medium",
|
||||
select_pos: [i32; 4] = "select_pos",
|
||||
gamma: [f32; 4] = "gamma",
|
||||
@ -47,6 +52,7 @@ gfx_defines! {
|
||||
constant Light {
|
||||
pos: [f32; 4] = "light_pos",
|
||||
col: [f32; 4] = "light_col",
|
||||
// proj: [[f32; 4]; 4] = "light_proj";
|
||||
}
|
||||
|
||||
constant Shadow {
|
||||
@ -70,6 +76,7 @@ impl Globals {
|
||||
shadow_planes: Vec2<f32>,
|
||||
light_count: usize,
|
||||
shadow_count: usize,
|
||||
directed_light_count: usize,
|
||||
medium: BlockKind,
|
||||
select_pos: Option<Vec3<i32>>,
|
||||
gamma: f32,
|
||||
@ -92,7 +99,18 @@ impl Globals {
|
||||
shadow_planes.x,
|
||||
shadow_planes.y,
|
||||
],
|
||||
light_shadow_count: [light_count as u32, shadow_count as u32, 0, 0],
|
||||
light_shadow_count: [
|
||||
(light_count % MAX_POINT_LIGHT_COUNT) as u32,
|
||||
(shadow_count % MAX_FIGURE_SHADOW_COUNT) as u32,
|
||||
(directed_light_count % MAX_DIRECTED_LIGHT_COUNT) as u32,
|
||||
0,
|
||||
],
|
||||
shadow_proj_factors: [
|
||||
(shadow_planes.y + shadow_planes.x) / (shadow_planes.y - shadow_planes.x),
|
||||
(2.0 * shadow_planes.y * shadow_planes.x) / (shadow_planes.y - shadow_planes.x),
|
||||
0.0,
|
||||
0.0,
|
||||
],
|
||||
medium: [if medium.is_fluid() { 1 } else { 0 }; 4],
|
||||
select_pos: select_pos
|
||||
.map(|sp| Vec4::from(sp) + Vec4::unit_w())
|
||||
@ -121,6 +139,7 @@ impl Default for Globals {
|
||||
Vec2::new(1.0, 25.0),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
BlockKind::Air,
|
||||
None,
|
||||
1.0,
|
||||
|
@ -31,7 +31,7 @@ gfx_defines! {
|
||||
// Shadow stuff
|
||||
light_shadows: gfx::ConstantBuffer<Locals> = "u_light_shadows",
|
||||
|
||||
tgt_depth_stencil: gfx::DepthTarget<ShadowDepthStencilFmt> = gfx::preset::depth::LESS_EQUAL_TEST,//,Stencil::new(Comparison::Always,0xff,(StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))),
|
||||
tgt_depth_stencil: gfx::DepthTarget<ShadowDepthStencilFmt> = gfx::preset::depth::LESS_EQUAL_WRITE,//,Stencil::new(Comparison::Always,0xff,(StencilOp::Keep,StencilOp::Keep,StencilOp::Keep))),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -419,7 +419,7 @@ impl Renderer {
|
||||
let depth_stencil_cty = <<ShadowDepthStencilFmt as gfx::format::Formatted>::Channel as gfx::format::ChannelTyped>::get_channel_type();
|
||||
let shadow_tex = factory
|
||||
.create_texture(
|
||||
gfx::texture::Kind::CubeArray(size / 4, 32),
|
||||
gfx::texture::Kind::/*CubeArray*/Cube(size / 4 /* size * 2*//*, 32 */),
|
||||
1 as gfx::texture::Level,
|
||||
gfx::memory::Bind::SHADER_RESOURCE | gfx::memory::Bind::DEPTH_STENCIL,
|
||||
gfx::memory::Usage::Data,
|
||||
@ -436,7 +436,12 @@ impl Renderer {
|
||||
sampler_info.comparison = Some(Comparison::LessEqual);
|
||||
sampler_info.border = [1.0; 4].into();
|
||||
let shadow_tex_sampler = factory.create_sampler(sampler_info);
|
||||
|
||||
/* let tgt_shadow_view = factory.view_texture_as_depth_stencil::<ShadowDepthStencilFmt>(
|
||||
&shadow_tex,
|
||||
0,
|
||||
Some(1),
|
||||
gfx::texture::DepthStencilFlags::empty(),
|
||||
)?; */
|
||||
let tgt_shadow_view = factory.view_texture_as_depth_stencil_trivial(&shadow_tex)?;
|
||||
/* let tgt_shadow_res = factory.view_texture_as_shader_resource::<TgtColorFmt>(
|
||||
&tgt_color_tex,
|
||||
@ -454,7 +459,24 @@ impl Renderer {
|
||||
gfx::format::Swizzle::new(),
|
||||
)?;
|
||||
|
||||
Ok((tgt_shadow_view, tgt_shadow_res, shadow_tex_sampler))
|
||||
/* let tgt_sun_res = factory.view_texture_as_depth_stencil::<ShadowDepthStencilFmt>(
|
||||
&shadow_tex,
|
||||
0,
|
||||
Some(0),
|
||||
gfx::texture::DepthStencilFlags::RO_DEPTH,
|
||||
)?;
|
||||
let tgt_moon_res = factory.view_texture_as_depth_stencil::<ShadowDepthStencilFmt>(
|
||||
&shadow_tex,
|
||||
0,
|
||||
Some(1),
|
||||
gfx::texture::DepthStencilFlags::RO_DEPTH,
|
||||
)?; */
|
||||
|
||||
Ok((
|
||||
tgt_shadow_view,
|
||||
tgt_shadow_res,
|
||||
/* tgt_directed_res, */ shadow_tex_sampler,
|
||||
))
|
||||
}
|
||||
|
||||
/// Get the resolution of the render target.
|
||||
@ -465,13 +487,23 @@ impl Renderer {
|
||||
)
|
||||
}
|
||||
|
||||
/// Get the resolution of the shadow render target.
|
||||
pub fn get_shadow_resolution(&self) -> Vec2<u16> {
|
||||
if let Some(shadow_map) = &self.shadow_map {
|
||||
let dims = shadow_map.depth_stencil_view.get_dimensions();
|
||||
Vec2::new(dims.0, dims.1)
|
||||
} else {
|
||||
Vec2::new(1, 1)
|
||||
}
|
||||
}
|
||||
|
||||
/// Queue the clearing of the depth target ready for a new frame to be
|
||||
/// rendered.
|
||||
pub fn clear(&mut self) {
|
||||
if let Some(shadow_map) = self.shadow_map.as_mut() {
|
||||
shadow_map
|
||||
.encoder
|
||||
.clear_depth(&shadow_map.depth_stencil_view, 1.0);
|
||||
let encoder = &mut shadow_map.encoder;
|
||||
encoder.clear_depth(&shadow_map.depth_stencil_view, 1.0);
|
||||
// encoder.clear_stencil(&shadow_map.depth_stencil_view, 0);
|
||||
}
|
||||
self.encoder.clear_depth(&self.tgt_depth_stencil_view, 1.0);
|
||||
self.encoder.clear_stencil(&self.tgt_depth_stencil_view, 0);
|
||||
@ -481,7 +513,8 @@ impl Renderer {
|
||||
/// Perform all queued draw calls for shadows.
|
||||
pub fn flush_shadows(&mut self) {
|
||||
if let Some(shadow_map) = self.shadow_map.as_mut() {
|
||||
shadow_map.encoder.flush(&mut self.device);
|
||||
let encoder = &mut shadow_map.encoder;
|
||||
encoder.flush(&mut self.device);
|
||||
}
|
||||
}
|
||||
|
||||
@ -489,7 +522,8 @@ impl Renderer {
|
||||
/// items.
|
||||
pub fn flush(&mut self) {
|
||||
if let Some(shadow_map) = self.shadow_map.as_mut() {
|
||||
shadow_map.encoder.flush(&mut self.device);
|
||||
let encoder = &mut shadow_map.encoder;
|
||||
encoder.flush(&mut self.device);
|
||||
}
|
||||
self.encoder.flush(&mut self.device);
|
||||
self.device.cleanup();
|
||||
@ -902,7 +936,8 @@ impl Renderer {
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
shadow_map.encoder.draw(
|
||||
let encoder = &mut shadow_map.encoder;
|
||||
encoder.draw(
|
||||
&gfx::Slice {
|
||||
start: model.vertex_range().start,
|
||||
end: model.vertex_range().end,
|
||||
@ -1471,14 +1506,14 @@ fn create_shadow_pipeline<P: gfx::pso::PipelineInit>(
|
||||
// Second-depth shadow mapping: should help reduce z-fighting provided all objects
|
||||
// are "watertight" (every triangle edge is shared with at most one other
|
||||
// triangle); this *should* be true for Veloren.
|
||||
cull_face: /*cull_face*//*gfx::state::CullFace::Nothing*/match cull_face {
|
||||
cull_face: /*gfx::state::CullFace::Nothing*/match cull_face {
|
||||
gfx::state::CullFace::Front => gfx::state::CullFace::Back,
|
||||
gfx::state::CullFace::Back => gfx::state::CullFace::Front,
|
||||
gfx::state::CullFace::Nothing => gfx::state::CullFace::Nothing,
|
||||
},
|
||||
method: gfx::state::RasterMethod::Fill,
|
||||
offset: Some(gfx::state::Offset(4, /*10*/10)),
|
||||
samples: None,//Some(gfx::state::MultiSample),
|
||||
offset: None,//Some(gfx::state::Offset(4, /*10*/-10)),
|
||||
samples:None,//Some(gfx::state::MultiSample),
|
||||
},
|
||||
pipe,
|
||||
)?,
|
||||
|
@ -35,6 +35,7 @@ const CURSOR_PAN_SCALE: f32 = 0.005;
|
||||
|
||||
const MAX_LIGHT_COUNT: usize = 32;
|
||||
const MAX_SHADOW_COUNT: usize = 24;
|
||||
const NUM_DIRECTED_LIGHTS: usize = 2;
|
||||
const LIGHT_DIST_RADIUS: f32 = 64.0; // The distance beyond which lights may not emit light from their origin
|
||||
const SHADOW_DIST_RADIUS: f32 = 8.0;
|
||||
const SHADOW_MAX_DIST: f32 = 96.0; // The distance beyond which shadows may not be visible
|
||||
@ -42,8 +43,8 @@ const SHADOW_MAX_DIST: f32 = 96.0; // The distance beyond which shadows may not
|
||||
// const NEAR_PLANE: f32 = 0.5;
|
||||
// const FAR_PLANE: f32 = 100000.0;
|
||||
|
||||
const SHADOW_NEAR: f32 = 0.5; //0.5;//1.0; // Near plane for shadow map rendering.
|
||||
const SHADOW_FAR: f32 = 512.0; //100000.0;//25.0; // Far plane for shadow map rendering.
|
||||
const SHADOW_NEAR: f32 = 1.0; //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.
|
||||
|
||||
/// Above this speed is considered running
|
||||
/// Used for first person camera effects
|
||||
@ -110,7 +111,7 @@ impl Scene {
|
||||
.create_consts(&[Shadow::default(); MAX_SHADOW_COUNT])
|
||||
.unwrap(),
|
||||
shadow_mats: renderer
|
||||
.create_consts(&[ShadowLocals::default(); MAX_LIGHT_COUNT * 6])
|
||||
.create_consts(&[ShadowLocals::default(); MAX_LIGHT_COUNT * 6 + 2])
|
||||
.unwrap(),
|
||||
camera: Camera::new(resolution.x / resolution.y, CameraMode::ThirdPerson),
|
||||
camera_input_state: Vec2::zero(),
|
||||
@ -358,9 +359,36 @@ impl Scene {
|
||||
.expect("Failed to update light constants");
|
||||
|
||||
// Update light projection matrices for the shadow map.
|
||||
let time_of_day = scene_data.state.get_time_of_day();
|
||||
let shadow_res = renderer.get_shadow_resolution();
|
||||
// NOTE: The aspect ratio is currently always 1 for our cube maps, since they
|
||||
// are equal on all sides.
|
||||
let shadow_aspect = 1.0;
|
||||
let shadow_aspect = shadow_res.x as f32 / shadow_res.y as f32;
|
||||
// First, add a projected matrix for our directed hard lights.
|
||||
let directed_view_proj = Mat4::orthographic_rh_no(FrustumPlanes {
|
||||
left: -(shadow_res.x as f32) / 2.0,
|
||||
right: shadow_res.x as f32 / 2.0,
|
||||
bottom: -(shadow_res.y as f32) / 2.0,
|
||||
top: shadow_res.y as f32 / 2.0,
|
||||
near: SHADOW_NEAR,
|
||||
far: SHADOW_FAR,
|
||||
});
|
||||
// Construct matrices to transform from world space to light space for the sun
|
||||
// and moon.
|
||||
const TIME_FACTOR: f32 = (std::f32::consts::PI * 2.0) / (3600.0 * 24.0);
|
||||
let angle_rad = time_of_day as f32 * TIME_FACTOR;
|
||||
let sun_dir = Vec3::new(angle_rad.sin(), 0.0, angle_rad.cos());
|
||||
let moon_dir = Vec3::new(-angle_rad.sin(), 0.0, angle_rad.cos() - 0.5);
|
||||
let sun_view_mat = Mat4::model_look_at_rh(-sun_dir, Vec3::zero(), Vec3::up());
|
||||
let moon_view_mat = Mat4::model_look_at_rh(-moon_dir, Vec3::zero(), Vec3::up());
|
||||
// Now, construct the full projection matrices in the first two directed light
|
||||
// slots.
|
||||
let mut shadow_mats = Vec::with_capacity(6 * (lights.len() + 1));
|
||||
shadow_mats.push(ShadowLocals::new(directed_view_proj * sun_view_mat));
|
||||
shadow_mats.push(ShadowLocals::new(directed_view_proj * moon_view_mat));
|
||||
// This leaves us with four dummy slots, which we push as defaults.
|
||||
shadow_mats.extend_from_slice(&[ShadowLocals::default(); 6 - NUM_DIRECTED_LIGHTS] as _);
|
||||
// Now, we tackle point lights.
|
||||
// First, create a perspective projection matrix at 90 degrees (to cover a whole
|
||||
// face of the cube map we're using).
|
||||
let shadow_proj =
|
||||
@ -376,18 +404,22 @@ impl Scene {
|
||||
(Vec3::new(0.0, 0.0, -1.0), Vec3::new(0.0, -1.0, 0.0)),
|
||||
];
|
||||
// NOTE: We could create the shadow map collection at the same time as the
|
||||
// lights, but then we'd have to sort them both, which wastes time.
|
||||
let shadow_mats = lights
|
||||
.iter()
|
||||
.flat_map(|light| {
|
||||
// Now, construct the full projection matrix by making the light look at each
|
||||
// cube face.
|
||||
let eye = Vec3::new(light.pos[0], light.pos[1], light.pos[2]);
|
||||
orientations.iter().map(move |&(forward, up)| {
|
||||
ShadowLocals::new(shadow_proj * Mat4::look_at_rh(eye, eye + forward, up))
|
||||
})
|
||||
// lights, but then we'd have to sort them both, which wastes time. Plus, we
|
||||
// want to prepend our directed lights.
|
||||
shadow_mats.extend(lights.iter().flat_map(|light| {
|
||||
// Now, construct the full projection matrix by making the light look at each
|
||||
// cube face.
|
||||
let eye = Vec3::new(light.pos[0], light.pos[1], light.pos[2]);
|
||||
orientations.iter().map(move |&(forward, up)| {
|
||||
ShadowLocals::new(shadow_proj * Mat4::look_at_rh(eye, eye + forward, up))
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
}));
|
||||
/* shadow_mats.push(
|
||||
Mat4::orthographic_rh_no
|
||||
float near_plane = 1.0f, far_plane = 7.5f;
|
||||
glm::mat4 lightProjection = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, near_plane, far_plane);
|
||||
|
||||
); */
|
||||
renderer
|
||||
.update_consts(&mut self.shadow_mats, &shadow_mats)
|
||||
.expect("Failed to update light constants");
|
||||
@ -402,12 +434,13 @@ impl Scene {
|
||||
self.loaded_distance,
|
||||
self.lod.get_data().tgt_detail as f32,
|
||||
self.map_bounds,
|
||||
scene_data.state.get_time_of_day(),
|
||||
time_of_day,
|
||||
scene_data.state.get_time(),
|
||||
renderer.get_resolution(),
|
||||
Vec2::new(SHADOW_NEAR, SHADOW_FAR),
|
||||
lights.len(),
|
||||
shadows.len(),
|
||||
NUM_DIRECTED_LIGHTS,
|
||||
scene_data
|
||||
.state
|
||||
.terrain()
|
||||
@ -422,8 +455,7 @@ impl Scene {
|
||||
.expect("Failed to update global constants");
|
||||
|
||||
// Maintain LoD.
|
||||
self.lod
|
||||
.maintain(renderer, scene_data.state.get_time_of_day());
|
||||
self.lod.maintain(renderer, time_of_day);
|
||||
|
||||
// Maintain the terrain.
|
||||
self.terrain.maintain(
|
||||
|
@ -223,6 +223,7 @@ impl Scene {
|
||||
Vec2::new(SHADOW_NEAR, SHADOW_FAR),
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
BlockKind::Air,
|
||||
None,
|
||||
scene_data.gamma,
|
||||
|
Loading…
Reference in New Issue
Block a user