package Ġde . fab max . k ool . modules . k sl . blocks Ċ Ċ import Ġde . fab max . k ool . math . Vec 2 f Ċ import Ġde . fab max . k ool . math . Vec 3 f Ċ import Ġde . fab max . k ool . modules . k sl . lang .* Ċ import Ġde . fab max . k ool . util . Cas ca ded Shadow Map Ċ import Ġde . fab max . k ool . util . Shadow Map Ċ import Ġde . fab max . k ool . util . Simple Shadow Map Ċ import Ġkotlin . math . abs Ċ Ċ fun ĠK sl Scope Builder . vertex Shadow Block ( cfg : ĠShadow Config , Ġblock : ĠShadow Block Vertex Stage . () Ġ-> ĠUnit ): ĠShadow Block Vertex Stage Ġ{ ĊĠĠĠ Ġval Ġshadow Block Ġ= ĠShadow Block Vertex Stage ( cfg , Ġparent Stage . program . next Name (" shadow Block "), Ġthis ) ĊĠĠĠ Ġshadow Block . block () ĊĠĠĠ Ġops Ġ+= Ġshadow Block ĊĠĠĠ Ġreturn Ġshadow Block Ċ } Ċ Ċ fun ĠK sl Scope Builder . fragment Shadow Block ( vertex Stage : ĠShadow Block Vertex Stage , Ġshadow Factors : ĠK sl Array Scalar < K sl Type Float 1 >): ĠShadow Block Fragment Stage Ġ{ ĊĠĠĠ Ġval Ġshadow Block Ġ= ĠShadow Block Fragment Stage ( vertex Stage , Ġshadow Factors , Ġparent Stage . program . next Name (" shadow Block "), Ġthis ) ĊĠĠĠ Ġops Ġ+= Ġshadow Block ĊĠĠĠ Ġreturn Ġshadow Block Ċ } Ċ Ċ class ĠShadow Block Vertex Stage ( cfg : ĠShadow Config , Ġname : ĠString , Ġparent Scope : ĠK sl Scope Builder ) Ġ: ĠK sl Block ( name , Ġparent Scope ) Ġ{ ĊĠĠĠ Ġvar Ġin Position World Space Ġ= Ġin Float 3 (" in Position World Space ") ĊĠĠĠ Ġvar Ġin Normal World Space Ġ= Ġin Float 3 (" in Normal World Space ") ĊĊĠĠĠ Ġval Ġshadow Data : ĠShadow Data ĊĠĠĠ Ġvar Ġpositions Light Space : ĠK sl Inter Stage Vector Array < K sl Type Float 4 , ĠK sl Type Float 1 >? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġprivate Ġset ĊĠĠĠ Ġvar Ġnormal Zs Light Space : ĠK sl Inter Stage Scalar Array < K sl Type Float 1 >? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġprivate Ġset ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġbody . apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcheck ( parent Stage Ġis ĠK sl Vertex Stage ) Ġ{ Ġ" Simple Shadow Map Block Vertex Stage Ġcan Ġonly Ġbe Ġadded Ġto ĠK sl Vertex Stage " Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġparent Scope . parent Stage . program . apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshadow Data Ġ= ĠShadow Data ( cfg , Ġthis ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( shadow Data . num Sub Maps Ġ> Ġ 0 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpositions Light Space Ġ= Ġinter Stage Float 4 Array ( shadow Data . num Sub Maps ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnormal Zs Light Space Ġ= Ġinter Stage Float 1 Array ( shadow Data . num Sub Maps ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġshadow Data . shadow Map Infos . forEach Ġ{ Ġmap Info Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmap Info . sub Maps . forEach Indexed Ġ{ Ġi , Ġsub Map Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsub Map Idx Ġ= Ġmap Info . from Index In cl Ġ+ Ġi ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġview Proj Ġ= Ġshadow Data . shadow MapView Proj M ats [ sub Map Idx ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnormal Light Space Ġ= Ġfloat 3 Var ( normalize (( view Proj Ġ* Ġconst Float 4 ( in Normal World Space , Ġ 0 f . const )). xyz )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġnormal Zs Light Space !!. input [ sub Map Idx ] Ġset Ġnormal Light Space . z ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpositions Light Space !!. input [ sub Map Idx ] Ġset Ġview Proj Ġ* Ġconst Float 4 ( in Position World Space , Ġ 1 f . const ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġpositions Light Space !!. input [ sub Map Idx ]. xyz Ġ+= Ġnormal Light Space Ġ* Ġabs ( sub Map . shader Depth Offset ). const ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ class ĠShadow Block Fragment Stage ( ĊĠĠĠ Ġvertex Stage : ĠShadow Block Vertex Stage , ĊĠĠĠ Ġshadow Factors : ĠK sl Array Scalar < K sl Type Float 1 >, ĊĠĠĠ Ġname : ĠString , Ġparent Scope : ĠK sl Scope Builder ) ĊĠĠĠ Ġ: ĠK sl Block ( name , Ġparent Scope ) Ġ{ ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġbody . apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcheck ( parent Stage Ġis ĠK sl Fragment Stage ) Ġ{ Ġ" Simple Shadow Map Block Fragment Stage Ġcan Ġonly Ġbe Ġadded Ġto ĠK sl Fragment Stage " Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdepth Maps Ġ= Ġvertex Stage . shadow Data . depth Maps ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvertex Stage . shadow Data . shadow Map Infos . forEach Ġ{ Ġmap Info Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlight Idx Ġ= Ġmap Info . shadow Map . light Index ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshadow Factors [ light Idx ] Ġset Ġ 1 f . const ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpositions Light Space Ġ= Ġvertex Stage . positions Light Space !! ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnormal Zs Light Space Ġ= Ġvertex Stage . normal Zs Light Space !! ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġwhen Ġ( map Info . shadow Map ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠSimple Shadow Map Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsub Map Idx Ġ= Ġmap Info . from Index In cl ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpos Light Space Ġ= Ġpositions Light Space . output [ sub Map Idx ] ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ` if ` Ġ( normal Zs Light Space . output [ sub Map Idx ] Ġlt Ġ 0 f . const ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġnormal Ġpoints Ġtowards Ġlight Ġsource , Ġcompute Ġshadow Ġfactor ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshadow Factors [ light Idx ] Ġset Ġget Shadow Map Factor ( depth Maps . value [ sub Map Idx ], Ġpos Light Space , Ġmap Info . sample Pattern ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}. ` else ` Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġnormal Ġpoints Ġaway Ġfrom Ġlight Ġsource , Ġset Ġshadow Ġfactor Ġto Ġ 0 Ġ( shadow ed ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshadow Factors [ light Idx ] Ġset Ġ 0 f . const ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠCas ca ded Shadow Map Ġ-> Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ` if ` Ġ( normal Zs Light Space . output [ map Info . from Index In cl ] Ġlt Ġ 0 f . const ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġnormal Ġpoints Ġtowards Ġlight Ġsource , Ġcompute Ġshadow Ġfactor ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsample W Ġ= Ġfloat Var ( 0 f . const ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsample Sum Ġ= Ġfloat Var ( 0 f . const ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġproj Pos Ġ= Ġfloat 3 Var () ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( i Ġin Ġmap Info . from Index In cl Ġuntil Ġmap Info . to Index Ex cl ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġcheck Ġfor Ġeach Ġshadow Ġmap Ġ( sorted Ġfrom Ġhigh Ġdetail Ġto Ġlow Ġdetail ) Ġif Ġprojected ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġposition Ġis Ġinside Ġmap Ġbounds , Ġif Ġso Ġsample Ġit Ġand Ġstop ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpos Light Space Ġ= Ġpositions Light Space . output [ i ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġproj Pos Ġset Ġpos Light Space . xyz Ġ/ Ġpos Light Space . w ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ` if ` Ġ( sample W Ġlt Ġ 0 . 9 9 9 f . const Ġand ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġall ( proj Pos Ġgt ĠVec 3 f ( 0 f , Ġ 0 f , Ġ- 1 f ). const ) Ġand ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġall ( proj Pos Ġlt ĠVec 3 f ( 1 f , Ġ 1 f , Ġ 1 f ). const )) Ġ{ ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġdetermine Ġhow Ġclose Ġproj Ġpos Ġis Ġto Ġshadow Ġmap Ġborder Ġand Ġuse Ġthat Ġto Ġblend ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġbetween Ġcas ca des ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġp Ġ= Ġfloat 2 Var ( abs (( proj Pos . float 2 (" xy ") Ġ- Ġ 0 . 5 f . const ) Ġ* Ġ 2 f . const )) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġc Ġ= Ġ 1 f . const Ġ- Ġclamp ( max ( p . x , Ġp . y ) Ġ- Ġ 0 . 9 f . const , Ġ 0 f . const , Ġ 0 . 0 5 f . const ) Ġ* Ġ 1 0 f . const ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġw Ġ= Ġfloat Var ( c Ġ* Ġ( 1 f . const Ġ- Ġsample W )) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġprojected Ġposition Ġis Ġinside Ġshadow Ġmap Ġbounds , Ġsample Ġshadow Ġmap ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsample Sum Ġ+= Ġget Shadow Map Factor ( depth Maps . value [ i ], Ġpos Light Space , Ġmap Info . sample Pattern ) Ġ* Ġw ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsample W Ġ+= Ġw ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ` if ` Ġ( sample W Ġgt Ġ 0 f . const ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshadow Factors [ light Idx ] Ġset Ġsample Sum Ġ/ Ġsample W ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}. ` else ` Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġnormal Ġpoints Ġaway Ġfrom Ġlight Ġsource , Ġset Ġshadow Ġfactor Ġto Ġ 0 Ġ( shadow ed ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġshadow Factors [ light Idx ] Ġset Ġ 0 f . const ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġthrow ĠIllegalArgumentException (" Unsupported ĠShadow Map Ġtype : Ġ${ map Info . shadow Map }") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ Ċ class ĠShadow Config Ġ{ ĊĠĠĠ Ġval Ġshadow Maps Ġ= Ġmutable ListOf < Shadow Map Config >() ĊĊĠĠĠ Ġfun Ġadd Shadow Map ( shadow Map : ĠShadow Map , Ġsample Pattern : ĠList < Vec 2 f > Ġ= ĠSAMPLE _ PATTERN _ 4 x 4 ) Ġ{ ĊĠĠĠĠĠĠĠ Ġshadow Maps Ġ+= ĠShadow Map Config ( shadow Map , Ġsample Pattern ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġadd Shadow Maps ( shadow Maps : ĠCollection < Shadow Map >, Ġsample Pattern : ĠList < Vec 2 f > Ġ= ĠSAMPLE _ PATTERN _ 4 x 4 ) Ġ{ ĊĠĠĠĠĠĠĠ Ġthis . shadow Maps Ġ+= Ġshadow Maps . map Ġ{ ĠShadow Map Config ( it , Ġsample Pattern ) Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġclass ĠShadow Map Config ( val Ġshadow Map : ĠShadow Map , Ġval Ġsample Pattern : ĠList < Vec 2 f > Ġ= ĠSAMPLE _ PATTERN _ 4 x 4 ) ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠSAMPLE _ PATTERN _ 1 x 1 : ĠList < Vec 2 f > Ġ= ĠlistOf ( Vec 2 f . ZERO ) ĊĠĠĠĠĠĠĠ Ġval ĠSAMPLE _ PATTERN _ 4 x 4 : ĠList < Vec 2 f > Ġ= Ġmutable ListOf < Vec 2 f >(). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( y Ġin Ġ 0 .. 3 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( x Ġin Ġ 0 .. 3 ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġv Ġ= ĠVec 2 f (- 1 . 5 f Ġ+ Ġx , Ġ- 1 . 5 f Ġ+ Ġy ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( v Ġ! in Ġthis ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġadd ( v ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ