Sì, è un problema di precisione. Non proprio un problema di float, solo precisione finita.
In teoria la mappa delle ombre memorizza la "distanza dall'oggetto più vicino dalla luce". Ma in pratica memorizza "distanza ± eps dalla luce".
Quindi, durante il test, i tuoi frammenti si allontanano alla stessa luce. Ma ancora, in pratica ± eps2. Quindi, se si confrontano questi due valori, risulta che l'eps varia in modo diverso quando si interpola per il rendering o l'ombreggiatura della mappa ombra. Quindi, se si confronta d ± eps < d2 ± eps2
, se d2==d
, si potrebbe ottenere il risultato errato perché eps!=eps2
. Ma se confronti d ± eps < d2 + max(eps) + max(eps2) ± eps2
starai bene.
In questo esempio d2==d
. Questo è chiamato auto ombreggiamento. E può essere facilmente risolto con il pregiudizio di cui sopra, o semplicemente non testando te stesso in raytracing.
Diventa molto più complicato con oggetti diversi e quando eps ed eps2 sono molto diversi. Un modo per gestirlo è controllare l'eps (http://developer.download.nvidia.com/SDK/10.5/opengl/src/cascaded_shadow_maps/doc/cascaded_shadow_maps.pdf). Oppure si possono prendere molti più campioni.
Per provare a rispondere alla domanda: il problema principale è che il mapping ombra confronta le distanze ideali. Ma quelle distanze non sono ideali ma quantizzate. E i valori quantizzati di solito vanno bene, ma in questo caso li stiamo confrontando in due spazi diversi.