Skip to content

Softer shadows #599

@adriengivry

Description

@adriengivry

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
Image

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

No one assigned

    Labels

    GraphicsGraphical feature

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions