-
Notifications
You must be signed in to change notification settings - Fork 272
Open
Labels
GraphicsGraphical featureGraphical feature
Description
Problem this feature should fix
Shadows in Overload are currently very sharp, which make them look unnatural.
Expected solution
We should implement a different soft-shadow solution than regular PCF, to improve the overall quality of the shadows.
We could also expose a "softness" setting to user through the directional light component.
Test implementation using PCF with poisson disk sampling
float CalculateSoftShadow(sampler2D shadowMap, vec3 projCoords, float bias, float texelSize)
{
// Poisson disk sample pattern for better quality with fewer samples
const vec2 poissonDisk[16] = vec2[](
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)
);
// Shadow softness - higher values create softer shadows
float softness = 3.0;
// Random rotation angle based on position to reduce banding
float rotationAngle = fract(sin(dot(projCoords.xy, vec2(12.9898, 78.233))) * 43758.5453) * 6.28318;
float s = sin(rotationAngle);
float c = cos(rotationAngle);
mat2 rotation = mat2(c, -s, s, c);
float shadow = 0.0;
int samples = 16;
for (int i = 0; i < samples; i++)
{
vec2 offset = rotation * poissonDisk[i] * texelSize * softness;
vec3 offsettedProjCoords = vec3(projCoords.xy + offset, projCoords.z);
shadow += SampleShadow(shadowMap, offsettedProjCoords, bias);
}
return shadow / float(samples);
}
Metadata
Metadata
Assignees
Labels
GraphicsGraphical featureGraphical feature