Use proper 3d poission samples for point lights
This commit is contained in:
parent
31238c20ad
commit
87a81111eb
2 changed files with 47 additions and 19 deletions
|
@ -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),
|
||||
|
|
|
@ -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);
|
||||
|
|
Reference in a new issue