diff --git a/engine/shaders/common.nocompile.glsl b/engine/shaders/common.nocompile.glsl index 68129c5..5e8b987 100644 --- a/engine/shaders/common.nocompile.glsl +++ b/engine/shaders/common.nocompile.glsl @@ -1,6 +1,25 @@ const float PI = 3.14159265359; const float EPSILON = 0.005; +const vec2 PoissionPCFDisk[16] = { + vec2( -0.94201624, -0.39906216 ), + vec2( 0.94558609, -0.76890725 ), + vec2( -0.094184101, -0.92938870 ), + vec2( 0.34495938, 0.29387760 ), + vec2( -0.91588581, 0.45771432 ), + vec2( -0.81544232, -0.87912464 ), + vec2( -0.38277543, 0.27676845 ), + vec2( 0.97484398, 0.75648379 ), + vec2( 0.44323325, -0.97511554 ), + vec2( 0.53742981, -0.47373420 ), + vec2( -0.26496911, -0.41893023 ), + vec2( 0.79197514, 0.19090188 ), + vec2( -0.24188840, 0.99706507 ), + vec2( -0.81409955, 0.91437590 ), + vec2( 0.19984126, 0.78641367 ), + vec2( 0.14383161, -0.14100790 ) +}; + const vec2 PoissonOffsets[64] = { vec2(0.0617981, 0.07294159), vec2(0.6470215, 0.7474022), diff --git a/engine/shaders/rendering.nocompile.glsl b/engine/shaders/rendering.nocompile.glsl index a3a8e2e..d579267 100644 --- a/engine/shaders/rendering.nocompile.glsl +++ b/engine/shaders/rendering.nocompile.glsl @@ -66,7 +66,7 @@ struct ComputedLightInformation { float pcf_sun(const vec4 shadowCoords, const float uvRadius) { float sum = 0; for(int i = 0; i < 16; i++) { - const float z = texture(sun_shadow, shadowCoords.xy + PoissonOffsets[i] * uvRadius).r; + const float z = texture(sun_shadow, shadowCoords.xy + PoissionPCFDisk[i] * uvRadius).r; sum += (z < (shadowCoords.z - 0.005)) ? 0.0 : 1.0; } @@ -91,8 +91,7 @@ void blocker_distance_sun(const vec3 shadowCoords, const float uvLightSize, inou blockers = 0; for(int i = 0; i < numBlockerSearchSamples; i++) { - const float z = texture(sun_shadow, - shadowCoords.xy + PoissonOffsets[i] * searchWidth).r; + const float z = texture(sun_shadow, shadowCoords.xy + PoissionPCFDisk[i] * searchWidth).r; if(z < shadowCoords.z) { blockerSum += z; blockers++; @@ -105,11 +104,12 @@ void blocker_distance_sun(const vec3 shadowCoords, const float uvLightSize, inou float pcss_sun(const vec4 shadowCoords, float light_size_uv) { float average_blocker_depth = 0.0; int num_blockers = 0; + blocker_distance_sun(shadowCoords.xyz, light_size_uv, average_blocker_depth, num_blockers); if(num_blockers < 1) return 1.0; - const float penumbraWidth = penumbra_size(-shadowCoords.z, average_blocker_depth); + const float penumbraWidth = penumbra_size(shadowCoords.z, average_blocker_depth); const float uvRadius = penumbraWidth * light_size_uv * 0.1 / shadowCoords.z; return pcf_sun(shadowCoords, uvRadius); @@ -145,7 +145,7 @@ ComputedLightInformation calculate_sun(Light light) { float pcf_spot(const vec4 shadowCoords, const int index, const float uvRadius) { float sum = 0; for(int i = 0; i < 16; i++) { - const float z = texture(spot_shadow, vec3(shadowCoords.xy + PoissonOffsets[i] * uvRadius, index)).r; + const float z = texture(spot_shadow, vec3(shadowCoords.xy + PoissionPCFDisk[i] * uvRadius, index)).r; sum += (z < (shadowCoords.z - 0.001)) ? 0.0 : 1.0; } @@ -160,8 +160,7 @@ void blocker_distance_spot(const vec3 shadowCoords, const int index, const float blockers = 0; for(int i = 0; i < numBlockerSearchSamples; i++) { - const float z = texture(spot_shadow, - vec3(shadowCoords.xy + PoissonOffsets[i] * searchWidth, index)).r; + const float z = texture(spot_shadow, vec3(shadowCoords.xy + PoissionPCFDisk[i] * searchWidth, index)).r; if(z < shadowCoords.z) { blockerSum += z; blockers++; @@ -174,6 +173,7 @@ void blocker_distance_spot(const vec3 shadowCoords, const int index, const float float pcss_spot(const vec4 shadowCoords, const int index, float light_size_uv) { float average_blocker_depth = 0.0; int num_blockers = 0; + blocker_distance_spot(shadowCoords.xyz, index, light_size_uv, average_blocker_depth, num_blockers); if(num_blockers < 1) return 1.0; @@ -197,7 +197,7 @@ ComputedLightInformation calculate_spot(Light light) { const vec4 shadowCoord = fragPostSpotLightSpace[last_spot_light] / fragPostSpotLightSpace[last_spot_light].w; #ifdef SHADOW_FILTER_NONE - shadow = (texture(spot_shadow, vec3(shadowCoord.xy, last_spot_light)).r < shadowCoord.z) ? 0.0 : 1.0; + shadow = (texture(spot_shadow, vec3(shadowCoord.xy, last_spot_light)).r < shadowCoord.z - 0.005) ? 0.0 : 1.0; #endif #ifdef SHADOW_FILTER_PCF shadow = pcf_spot(shadowCoord, last_spot_light, 0.01); @@ -223,14 +223,23 @@ ComputedLightInformation calculate_spot(Light light) { #ifdef POINT_SHADOWS_SUPPORTED +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) +); + float pcf_point(const vec3 shadowCoords, const int index, const float uvRadius) { float sum = 0; - for(int i = 0; i < 16; i++) { - const float z = texture(point_shadow, vec4(shadowCoords.xyz + vec3(PoissonOffsets[i].xy, PoissonOffsets[i].x) * uvRadius, index)).r; + for(int i = 0; i < 20; i++) { + const float z = texture(point_shadow, vec4(shadowCoords.xyz + sampleOffsetDirections[i] * uvRadius, index)).r; sum += (z < length(shadowCoords) - 0.05) ? 0.0 : 1.0; } - return sum / 16; + return sum / 20; } #ifdef SHADOW_FILTER_PCSS @@ -240,9 +249,8 @@ void blocker_distance_point(const vec3 shadowCoords, const int index, const floa float blockerSum = 0.0; blockers = 0; - for(int i = 0; i < numBlockerSearchSamples; i++) { - const float z = texture(point_shadow, - vec4(shadowCoords + vec3(PoissonOffsets[i], PoissonOffsets[i].x) * searchWidth, index)).r; + for(int i = 0; i < 20; i++) { + const float z = texture(point_shadow, vec4(shadowCoords + sampleOffsetDirections[i] * 0.05, index)).r; if(z < length(shadowCoords)) { blockerSum += z; blockers++; @@ -255,14 +263,15 @@ void blocker_distance_point(const vec3 shadowCoords, const int index, const floa float pcss_point(const vec3 shadowCoords, const int index, float light_size_uv) { float average_blocker_depth = 0.0; int num_blockers = 0; + blocker_distance_point(shadowCoords.xyz, index, light_size_uv, average_blocker_depth, num_blockers); if(num_blockers < 1) return 1.0; + + const float dist = length(shadowCoords); + const float penumbraWidth = penumbra_size(dist, average_blocker_depth); - const float depth = length(shadowCoords); - const float penumbraWidth = penumbra_size(-depth, average_blocker_depth); - - const float uvRadius = penumbraWidth * light_size_uv; + const float uvRadius = penumbraWidth * light_size_uv / dist; return pcf_point(shadowCoords, index, uvRadius); } #endif @@ -286,7 +295,7 @@ ComputedLightInformation calculate_point(Light light) { shadow = (dist <= sampledDist + 0.05) ? 1.0 : 0.0; #endif #ifdef SHADOW_FILTER_PCF - shadow = pcf_point(lightVec, int(light.shadowsEnable.z), 1.0); + shadow = pcf_point(lightVec, int(light.shadowsEnable.z), 0.05); #endif #ifdef SHADOW_FILTER_PCSS shadow = pcss_point(lightVec, int(light.shadowsEnable.z), light.shadowsEnable.y);