2018-03-11 11:58:50 +01:00
|
|
|
#version 150 core
|
|
|
|
|
|
|
|
uniform vec4 uColor;
|
|
|
|
uniform vec3 uLightDirection;
|
2018-03-11 14:16:23 +01:00
|
|
|
uniform vec3 uViewPosition;
|
2018-03-15 11:01:55 +01:00
|
|
|
uniform sampler2D uAlbedoTexture;
|
2018-03-16 11:36:20 +01:00
|
|
|
|
|
|
|
#define USE_SAMPLER2D_SHADOW 1
|
|
|
|
|
2019-04-23 23:17:10 +02:00
|
|
|
//
|
|
|
|
// Single Shadow MAp
|
|
|
|
//
|
|
|
|
|
2018-03-16 11:36:20 +01:00
|
|
|
#ifdef USE_SAMPLER2D_SHADOW
|
|
|
|
uniform sampler2DShadow uShadowMap;
|
|
|
|
#else
|
2018-03-15 11:01:55 +01:00
|
|
|
uniform sampler2D uShadowMap;
|
2018-03-16 11:36:20 +01:00
|
|
|
#endif
|
2018-03-11 11:58:50 +01:00
|
|
|
|
2019-04-23 23:17:10 +02:00
|
|
|
//
|
|
|
|
// Cascaded Shadow Maps
|
|
|
|
//
|
|
|
|
|
|
|
|
const int NUM_SPLITS = 4;
|
|
|
|
|
|
|
|
#ifdef USE_SAMPLER2D_SHADOW
|
|
|
|
uniform sampler2DShadow uShadowMaps[NUM_SPLITS];
|
|
|
|
#else
|
|
|
|
uniform sampler2D uShadowMaps[NUM_SPLITS];
|
|
|
|
#endif
|
|
|
|
|
|
|
|
uniform mat4 uViewToLightMatrix[NUM_SPLITS];
|
|
|
|
uniform float uShowCascadesAlpha;
|
|
|
|
uniform vec4 uShadowSplits;
|
|
|
|
uniform vec4 uShadowSplitBias;
|
|
|
|
|
2018-04-10 14:08:28 +02:00
|
|
|
uniform mat4 uModelMatrix;
|
|
|
|
uniform mat4 uViewMatrix;
|
|
|
|
|
2018-03-11 14:16:23 +01:00
|
|
|
in vec3 ioFragPosition;
|
2018-03-15 11:01:55 +01:00
|
|
|
in vec3 ioFragNormal;
|
|
|
|
in vec2 ioFragTexCoords;
|
|
|
|
smooth in vec4 ioFragColor;
|
|
|
|
in vec4 ioFragPosLightSpace;
|
2018-03-11 11:58:50 +01:00
|
|
|
|
|
|
|
out vec4 outColor;
|
2018-04-04 22:59:22 +02:00
|
|
|
out vec3 outPosition;
|
|
|
|
out vec3 outNormal;
|
2018-03-11 11:58:50 +01:00
|
|
|
|
2019-04-23 23:17:10 +02:00
|
|
|
float ShadowCalculationPCF_OLD(vec4 frag_pos_light_space) {
|
2018-03-16 11:36:20 +01:00
|
|
|
vec3 projected_coordinates = frag_pos_light_space.xyz / frag_pos_light_space.w;
|
|
|
|
projected_coordinates = projected_coordinates * 0.5 + 0.5;
|
|
|
|
|
|
|
|
float current_depth = projected_coordinates.z;
|
|
|
|
|
|
|
|
float bias = 0.00;
|
|
|
|
bias = max(0.005 * (1.0 - dot(ioFragNormal, uLightDirection)), 0.003);
|
|
|
|
|
|
|
|
float shadow = 0.0;
|
|
|
|
vec2 texel_size = 1.0 / textureSize(uShadowMap, 0);
|
|
|
|
for (int x = -1; x <= 1; ++x) {
|
|
|
|
for (int y = -1; y <= 1; ++y) {
|
|
|
|
#ifdef USE_SAMPLER2D_SHADOW
|
|
|
|
vec2 coordinate = projected_coordinates.xy + vec2(x, y) * texel_size;
|
|
|
|
float pcf_depth = texture(uShadowMap, vec3(coordinate, current_depth - bias));
|
|
|
|
#else
|
|
|
|
float pcf_depth = texture(uShadowMap, projected_coordinates.xy).r;
|
|
|
|
#endif
|
|
|
|
shadow += current_depth - bias > pcf_depth ? 1.0 : 0.0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
shadow /= 9.0;
|
|
|
|
|
|
|
|
return shadow;
|
|
|
|
}
|
|
|
|
|
2019-04-23 23:17:10 +02:00
|
|
|
#ifdef USE_SAMPLER2D_SHADOW
|
|
|
|
float ShadowCalculationPCF(sampler2DShadow shadow_map, vec4 frag_pos_light_space, vec3 frag_normal_light_space, float shadow_bias) {
|
|
|
|
#else
|
|
|
|
float ShadowCalculationPCF(sampler2D shadow_map, vec4 frag_pos_light_space, vec3 frag_normal_light_space, float shadow_bias) {
|
|
|
|
#endif
|
2018-03-15 11:01:55 +01:00
|
|
|
vec3 projected_coordinates = frag_pos_light_space.xyz / frag_pos_light_space.w;
|
|
|
|
projected_coordinates = projected_coordinates * 0.5 + 0.5;
|
|
|
|
|
2019-04-23 23:17:10 +02:00
|
|
|
if (abs(projected_coordinates.z) > 1.0 ) {
|
|
|
|
return 0.0;
|
|
|
|
}
|
|
|
|
|
2018-03-15 11:01:55 +01:00
|
|
|
float current_depth = projected_coordinates.z;
|
|
|
|
|
2019-04-23 23:17:10 +02:00
|
|
|
float bias = 0.00;
|
|
|
|
bias = max(shadow_bias * (1.0 - dot(frag_normal_light_space, uLightDirection)), shadow_bias);
|
2018-03-16 11:36:20 +01:00
|
|
|
|
2019-04-23 23:17:10 +02:00
|
|
|
float shadow = 0.0;
|
|
|
|
vec2 texel_size = 1.0 / textureSize(shadow_map, 0);
|
|
|
|
for (int x = -1; x <= 1; ++x) {
|
|
|
|
for (int y = -1; y <= 1; ++y) {
|
2018-03-16 11:36:20 +01:00
|
|
|
#ifdef USE_SAMPLER2D_SHADOW
|
2019-04-23 23:17:10 +02:00
|
|
|
vec2 coordinate = projected_coordinates.xy + vec2(x, y) * texel_size;
|
|
|
|
float pcf_depth = texture(shadow_map, vec3(coordinate, current_depth - bias));
|
2018-03-16 11:36:20 +01:00
|
|
|
#else
|
2019-04-23 23:17:10 +02:00
|
|
|
float pcf_depth = texture(shadow_map, projected_coordinates.xy).r;
|
2018-03-16 11:36:20 +01:00
|
|
|
#endif
|
2019-04-23 23:17:10 +02:00
|
|
|
shadow += current_depth - bias > pcf_depth ? 1.0 : 0.0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
shadow /= 9.0;
|
2018-03-16 11:36:20 +01:00
|
|
|
|
2019-04-23 23:17:10 +02:00
|
|
|
return shadow;
|
|
|
|
}
|
|
|
|
|
|
|
|
vec3 get_cascade_color (float depth) {
|
|
|
|
if (depth < uShadowSplits[0]) {
|
|
|
|
return vec3 (1.0, 0.0, 0.0);
|
|
|
|
} else if (depth < uShadowSplits[1]) {
|
|
|
|
return vec3 (1.0, 1.0, 0.0);
|
|
|
|
} else if (depth < uShadowSplits[2]) {
|
|
|
|
return vec3 (0.0, 1.0, 0.0);
|
|
|
|
}
|
|
|
|
|
|
|
|
return vec3 (0.0, 0.0, 1.0);
|
2018-03-15 11:01:55 +01:00
|
|
|
}
|
|
|
|
|
2018-03-11 11:58:50 +01:00
|
|
|
void main() {
|
2018-03-15 11:01:55 +01:00
|
|
|
vec4 albedo_color = texture(uAlbedoTexture, ioFragTexCoords) * ioFragColor * uColor;
|
2019-04-23 23:17:10 +02:00
|
|
|
vec3 position = ioFragPosition.xyz;
|
2018-03-15 11:01:55 +01:00
|
|
|
|
2018-03-11 14:16:23 +01:00
|
|
|
// ambient lighting
|
2018-03-15 23:00:53 +01:00
|
|
|
float ambient_strength = 0.2;
|
2018-03-15 11:01:55 +01:00
|
|
|
vec4 ambient = ambient_strength * albedo_color;
|
2018-03-11 11:58:50 +01:00
|
|
|
|
2018-03-11 14:16:23 +01:00
|
|
|
// diffuse lighting
|
2019-04-23 23:17:10 +02:00
|
|
|
vec3 normal = normalize(ioFragNormal);
|
2018-12-15 22:52:37 +01:00
|
|
|
vec3 light_dir = -(mat3(uViewMatrix)) * uLightDirection;
|
2019-04-23 23:17:10 +02:00
|
|
|
float diff = max(dot(normal, light_dir), 0.0);
|
2018-03-15 11:01:55 +01:00
|
|
|
vec4 diffuse = diff * albedo_color;
|
2018-03-11 11:58:50 +01:00
|
|
|
|
2018-03-11 14:16:23 +01:00
|
|
|
// specular lighting
|
2018-04-10 14:08:28 +02:00
|
|
|
vec3 view_dir = normalize(-ioFragPosition);
|
2018-03-11 17:30:56 +01:00
|
|
|
vec3 halfway_dir = normalize(light_dir + view_dir);
|
2018-03-11 14:16:23 +01:00
|
|
|
|
2019-04-23 23:17:10 +02:00
|
|
|
float spec = pow(max(dot(normal, halfway_dir), 0.0), 32);
|
2018-03-11 17:30:56 +01:00
|
|
|
vec4 specular = spec * vec4(0.5);
|
2018-03-11 14:16:23 +01:00
|
|
|
|
2018-03-15 11:01:55 +01:00
|
|
|
// shadow
|
2019-04-23 23:17:10 +02:00
|
|
|
float shadow = 0;
|
|
|
|
if (-position.z < uShadowSplits[0]) {
|
|
|
|
// shadow (need to transform position and normal to light space)
|
|
|
|
vec4 position_light_space = uViewToLightMatrix[0] * vec4(position, 1.0);
|
|
|
|
vec3 normal_light_space = (transpose(inverse(uViewToLightMatrix[0])) * vec4(normal, 1.0)).xyz;
|
|
|
|
shadow = ShadowCalculationPCF(uShadowMaps[0], position_light_space, normal, uShadowSplitBias[0]);
|
|
|
|
} else if (-position.z< uShadowSplits[1]) {
|
|
|
|
vec4 position_light_space = uViewToLightMatrix[1] * vec4(position, 1.0);
|
|
|
|
vec3 normal_light_space = (transpose(inverse(uViewToLightMatrix[1])) * vec4(normal, 1.0)).xyz;
|
|
|
|
shadow = ShadowCalculationPCF(uShadowMaps[1], position_light_space, normal, uShadowSplitBias[1]);
|
|
|
|
} else if (-position.z< uShadowSplits[2]) {
|
|
|
|
vec4 position_light_space = uViewToLightMatrix[2] * vec4(position, 1.0);
|
|
|
|
vec3 normal_light_space = (transpose(inverse(uViewToLightMatrix[2])) * vec4(normal, 1.0)).xyz;
|
|
|
|
shadow = ShadowCalculationPCF(uShadowMaps[2], position_light_space, normal, uShadowSplitBias[2]);
|
|
|
|
} else {
|
|
|
|
vec4 position_light_space = uViewToLightMatrix[3] * vec4(position, 1.0);
|
|
|
|
vec3 normal_light_space = (transpose(inverse(uViewToLightMatrix[3])) * vec4(normal, 1.0)).xyz;
|
|
|
|
shadow = ShadowCalculationPCF(uShadowMaps[3], position_light_space, normal, uShadowSplitBias[3]);
|
|
|
|
}
|
|
|
|
|
|
|
|
vec4 cascade = vec4(get_cascade_color(-position.z), 1.0);
|
|
|
|
ambient = (uShowCascadesAlpha * cascade) + (1.0 - uShowCascadesAlpha) * ambient;
|
|
|
|
outColor = (ambient + (1.0 - shadow) * (diffuse + specular));
|
|
|
|
|
|
|
|
// float shadow = ShadowCalculationPCF(uShadowMap, ioFragPosLightSpace, normal, 0.001);
|
2018-03-15 11:01:55 +01:00
|
|
|
outColor = ambient + (1.0 - shadow) * (diffuse + specular);
|
2018-04-04 22:59:22 +02:00
|
|
|
|
|
|
|
outPosition = ioFragPosition.xyz;
|
2018-04-10 14:08:28 +02:00
|
|
|
outNormal = normalize(ioFragNormal);
|
2018-03-11 11:58:50 +01:00
|
|
|
}
|