Files
OrcaSlicer/resources/shaders/110/printbed_shadow.fs
T
2026-10-02 14:45:58 -03:00

45 lines
1.4 KiB
GLSL

#version 110
// Draws the build-plate as a receiver of the same depth shadow map used for object/self shadows,
// so the plate, objects, and self-shadows all come from one unified technique.
uniform sampler2D shadow_map;
uniform mat4 shadow_light_vp;
uniform float shadow_intensity;
uniform float shadow_map_texel;
// Plate area a shadow can reach, min xy then max xy; the rest is skipped before any lookup.
uniform vec4 shadow_bounds;
varying vec4 world_pos;
// Fraction of the 5x5 PCF kernel occluded from the light. Matches the object shadow shader.
float shadow_occlusion()
{
vec4 lp = shadow_light_vp * world_pos;
vec3 proj = lp.xyz / lp.w;
proj = proj * 0.5 + 0.5;
if (proj.z > 1.0)
return 0.0;
// The plate is a pure receiver (never rendered into the shadow map), so a tiny constant
// bias for numerical safety is enough here.
float bias = 0.0004;
float sum = 0.0;
for (int x = -2; x <= 2; ++x) {
for (int y = -2; y <= 2; ++y) {
float closest = texture2D(shadow_map, proj.xy + vec2(float(x), float(y)) * shadow_map_texel).r;
sum += (proj.z - bias > closest) ? 1.0 : 0.0;
}
}
return sum / 25.0;
}
void main()
{
if (any(lessThan(world_pos.xy, shadow_bounds.xy)) || any(greaterThan(world_pos.xy, shadow_bounds.zw)))
discard;
float occ = shadow_occlusion();
if (occ <= 0.0)
discard;
gl_FragColor = vec4(0.0, 0.0, 0.0, shadow_intensity * occ);
}