89 3D: Shadow descriptors and stable bounds
3D reference map · First 3D picture
procedure
(shadow-bias3d [ #:world-normal-offset world-normal-offset #:slope-scale slope-scale #:constant-depth-offset constant-depth-offset #:pcf-radius-texels pcf-radius-texels]) → shadow-bias3d? world-normal-offset : nonnegative-real? = 0 slope-scale : nonnegative-real? = 0 constant-depth-offset : nonnegative-real? = 0 pcf-radius-texels : exact-nonnegative-integer? = 1
procedure
(shadow-bias3d? value) → boolean?
value : any/c
procedure
(shadow-bias3d-world-normal-offset bias) → nonnegative-real?
bias : shadow-bias3d?
procedure
(shadow-bias3d-slope-scale bias) → nonnegative-real?
bias : shadow-bias3d?
procedure
(shadow-bias3d-constant-depth-offset bias) → nonnegative-real?
bias : shadow-bias3d?
procedure
→ exact-nonnegative-integer? bias : shadow-bias3d?
procedure
(shadow-settings3d [ #:map-size map-size #:bias bias #:depth-bias depth-bias #:normal-bias normal-bias #:pcf-radius pcf-radius #:bounds bounds #:near near #:far far #:prepared-bounds-key prepared-bounds-key]) → shadow-settings3d? map-size : exact-positive-integer? = 1024 bias : (or/c #f shadow-bias3d?) = #f depth-bias : (or/c #f nonnegative-real?) = #f normal-bias : (or/c #f nonnegative-real?) = #f pcf-radius : (or/c #f exact-nonnegative-integer?) = #f bounds : (or/c #f aabb3?) = #f near : (or/c #f positive-real?) = #f far : (or/c #f positive-real?) = #f prepared-bounds-key : (or/c #f symbol?) = #f
procedure
(shadow-settings3d? value) → boolean?
value : any/c
procedure
(shadow-settings3d-map-size settings) → exact-positive-integer?
settings : shadow-settings3d?
procedure
(shadow-settings3d-bias settings) → (or/c #f shadow-bias3d?)
settings : shadow-settings3d?
procedure
(shadow-settings3d-depth-bias settings) → nonnegative-real?
settings : shadow-settings3d?
procedure
(shadow-settings3d-normal-bias settings) → nonnegative-real?
settings : shadow-settings3d?
procedure
(shadow-settings3d-pcf-radius settings)
→ exact-nonnegative-integer? settings : shadow-settings3d?
procedure
(shadow-settings3d-bounds settings) → (or/c #f aabb3?)
settings : shadow-settings3d?
procedure
(shadow-settings3d-near settings) → (or/c #f positive-real?)
settings : shadow-settings3d?
procedure
(shadow-settings3d-far settings) → (or/c #f positive-real?)
settings : shadow-settings3d?
procedure
(shadow-settings3d-prepared-bounds-key settings)
→ (or/c #f symbol?) settings : shadow-settings3d?
procedure
(directional-shadow3d [#:settings settings])
→ directional-shadow3d? settings : shadow-settings3d? = (shadow-settings3d)
procedure
(spot-shadow3d [#:settings settings]) → spot-shadow3d?
settings : shadow-settings3d? = (shadow-settings3d)
procedure
(directional-shadow3d? value) → boolean?
value : any/c
procedure
(directional-shadow3d-settings shadow) → shadow-settings3d?
shadow : directional-shadow3d?
procedure
(spot-shadow3d? value) → boolean?
value : any/c
procedure
(spot-shadow3d-settings shadow) → shadow-settings3d?
shadow : spot-shadow3d?
procedure
(shadow3d-kind shadow) → (or/c 'directional 'spot)
shadow : shadow3d?
procedure
(shadow3d-settings shadow) → shadow-settings3d?
shadow : shadow3d?
struct
(struct prepared-shadow-bounds3d ( light-id frame-range bounds light-space-bounds diagnostics) #:transparent) light-id : symbol? frame-range : pair? bounds : aabb3? light-space-bounds : aabb3? diagnostics : immutable-hash?
procedure
(prepare-shadow-bounds3d views #:light-id light-id [ #:frame-range frame-range]) → prepared-shadow-bounds3d? views : (or/c view3d? (nonempty-listof view3d?)) light-id : symbol? frame-range : pair? = #f
procedure
(prepared-shadow-bounds3d-key prepared) → vector?
prepared : prepared-shadow-bounds3d?
procedure
(shadow-map3d-identity view light-id prepared) → vector? view : view3d? light-id : symbol? prepared : prepared-shadow-bounds3d?
struct
(struct shadow-map3d ( width height depth camera settings bounds diagnostics) #:transparent) width : exact-positive-integer? height : exact-positive-integer? depth : immutable-vector? camera : camera3d? settings : shadow-settings3d? bounds : aabb3? diagnostics : immutable-hash?
procedure
(shadow-map3d-factor map world-position world-normal light-direction) → real? map : shadow-map3d? world-position : vec3? world-normal : vec3? light-direction : vec3?
procedure
(shadow-light-camera3d light settings bounds) → camera3d? light : (or/c directional-light3d? spot-light3d?) settings : shadow-settings3d? bounds : aabb3?
Current limitation. The software and OpenGL renderers create one directional or spot depth map per descriptor and multiply only diffuse and specular terms by its PCF result. Ambient and emission remain unchanged. Only opaque mesh instances cast or receive; transparent surfaces, strokes, markers, billboards, and point-light cube shadows are not supported. Direct-frame fitting can shimmer, and a too-small explicit region yields unshadowed outside samples. The OpenGL backend caches context-owned GPU maps by eligible casters, light pose/settings, and bounds, deliberately excluding viewing-camera motion. Semantic shadow-bias3d values avoid backend-specific depth tuning by moving the receiver in world space before each renderer projects it. The legacy depth/normal fields retain their original backend-specific behavior for image compatibility.
struct
(struct light-attenuation3d (mode parameters) #:transparent) mode : (or/c 'constant 'inverse-square 'polynomial) parameters : immutable-hash?
procedure
(constant-attenuation3d [#:factor factor]) → light-attenuation3d?
factor : nonnegative-real? = 1
procedure
(inverse-square-attenuation3d [ #:reference-distance reference-distance #:cutoff cutoff]) → light-attenuation3d? reference-distance : positive-real? = 1 cutoff : (or/c #f positive-real?) = #f
procedure
(polynomial-attenuation3d [ #:constant constant #:linear linear #:quadratic quadratic #:cutoff cutoff]) → light-attenuation3d? constant : nonnegative-real? = 1 linear : nonnegative-real? = 0 quadratic : nonnegative-real? = 0 cutoff : (or/c #f positive-real?) = #f
procedure
(light-attenuation3d-factor attenuation distance) → nonnegative-real? attenuation : light-attenuation3d? distance : nonnegative-real?
procedure
(spot-smoothstep3d progress) → (and/c real? (between/c 0 1))
progress : finite-real?
procedure
(spot-cone-factor3d inner-angle outer-angle angle) → (and/c real? (between/c 0 1)) inner-angle : nonnegative-real? outer-angle : positive-real? angle : nonnegative-real?
Point and spot lights are evaluated by both the deterministic software reference renderer and the optional OpenGL backend. They use the same named constant, inverse-square, and polynomial attenuation policies, optional range, and smoothstep spot-cone rule. OpenGL packs the authored non-ambient light sequence into fixed uniform records, so it retains the frame’s light order rather than approximating finite sources as directional lights.
Current limitation. The OpenGL implementation has explicit fixed limits of four directional, eight point, and four spot lights per lit view. It rejects an over-limit frame before drawing. Directional and spot shadow maps are supported, but point-light cube shadows are not supported.