Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

Effetti a schermo intero in XR

Quando si aggiungono effetti a schermo intero personalizzati all'applicazione XR, un approccio consiste nell'utilizzare un quad a schermo intero e applicare gli effetti allo shader di tale quad. Aggiungi un nodo MeshInstance3D alla scena come figlio del nodo XRCamera3D e imposta la proprietà mesh su un QuadMesh. Impostare la larghezza e l'altezza del quad su 2.

../../_images/xr_full_screen_effects_starting_quad.webp

È quindi possibile aggiungere uno shader al quad per farlo coprire lo schermo. Si fa impostando la proprietà POSITION integrata nello shader dei vertici su vec4(VERTEX.xy, 1.0, 1.0). Tuttavia, quando si crea un effetto centrato direttamente di fronte alla visuale dell'utente (come un effetto vignettatura), il risultato finale potrebbe apparire errato in XR.

Di seguito sono mostrate le immagini dalla visuale dell'occhio destro con uno shader di vignettatura, sia dal visore sia dalla destinazione di rendering stessa. Le immagini a sinistra mostrano uno shader non modificato; quelle a destra adattano il quad sull'intero schermo tramite la matrice di proiezione. Mentre l'immagine a sinistra è centrata nella destinazione di rendering, appare fuori centro nella visuale del visore. Ma, dopo aver applicato la matrice di proiezione, si nota che l'effetto è centrato nel visore stesso.

../../_images/xr_full_screen_effects_vignette_before_after.webp

Applicare la matrice di proiezione

Per centrare correttamente l'effetto, la POSITION del quad sull'interno schermo deve tenere conto del campo visivo asimmetrico. Per farlo, garantendo anche che il quad copra completamente l'intera area di rendering, possiamo suddividerlo e applicare la matrice di proiezione ai vertici interni. Aumentiamo la larghezza e la profondità della suddivisione del quad.

../../_images/xr_full_screen_effects_ending_quad.webp

Poi, nella funzione vertex del nostro shader, applichiamo un offset dalla matrice di proiezione ai vertici interni. Ecco un esempio di come si potrebbe fare con il semplice shader di vignettatura mostrato sopra:

shader_type spatial;
render_mode depth_test_disabled, skip_vertex_transform, unshaded, cull_disabled;

// Modify VERTEX.xy using the projection matrix to correctly center the effect.
void vertex() {
        vec2 vert_pos = VERTEX.xy;

        if (length(vert_pos) < 0.99) {
                vec4 offset = PROJECTION_MATRIX * vec4(0.0, 0.0, 1.0, 1.0);
                vert_pos += (offset.xy / offset.w);
        }

        POSITION = vec4(vert_pos, 1.0, 1.0);
}

void fragment() {
        ALBEDO = vec3(0.0);
        ALPHA = dot(UV * 2.0 - 1.0, UV * 2.0 - 1.0) * 2.0;
}

Nota

Per ulteriori informazioni sul FOV asimmetrico e a cosa serve, consulta Meta Asymmetric Field of View FAQ.

Limitazioni

Questo metodo per effetti a schermo intero non causa problemi di prestazioni per effetti per ogni pixel, come lo shader di vignettatura descritto prima. Tuttavia, si sconsiglia di leggere dalla texture dello schermo quando si utilizza questa tecnica. Tali effetti che richiedono questa lettura, effettivamente, disabilitano tutte le ottimizzazioni sulle prestazioni di rendering in XR. Questo perché, durante la lettura dalla texture dello schermo, Godot crea una copia completa del buffer di rendering; ciò aumenta drasticamente il carico di lavoro per la GPU e può causare problemi di prestazioni.