Skip to content

Commit 5eacb0c

Browse files
committed
Create xr postprocessing page
1 parent 721603d commit 5eacb0c

File tree

4 files changed

+62
-0
lines changed

4 files changed

+62
-0
lines changed
7.75 KB
Binary file not shown.
Binary file not shown.

tutorials/xr/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ Advanced topics
2929
openxr_settings
3030
xr_action_map
3131
xr_room_scale
32+
xr_postprocessing
3233
openxr_composition_layers
3334
openxr_hand_tracking
3435
openxr_body_tracking

tutorials/xr/xr_postprocessing.rst

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
.. _doc_xr_postprocessing:
2+
3+
XR post-processing
4+
==================
5+
6+
When adding custom post-processing effects to your XR application, the full screen quad
7+
method used in the :ref:`advanced post-processing tutorial <doc_advanced_postprocessing>`
8+
is very useful. However, when creating an effect that is centered straight ahead in the user's view
9+
(such as a vignette effect), the end result may look incorrect.
10+
11+
Applying the projection matrix
12+
------------------------------
13+
14+
Below shows two captures of the right-eye view with a vignette shader. The left capture is an
15+
unmodified shader; the right capture adjusts the full screen quad using the projection matrix.
16+
This adjustment is what we're looking for.
17+
18+
.. image:: img/xr_postprocessing_vignette_before_after.webp
19+
20+
To properly center the post-processing effect, the ``POSITION`` of the full screen quad
21+
needs to take the asymmetric field of view into account. To do this while also ensuring the quad
22+
has full coverage of the entire render target, we can subdivide the quad and apply the projection matrix
23+
to the inner vertices. Let's increase the subdivide width and depth of the quad.
24+
25+
.. image:: img/xr_postprocessing_quad.webp
26+
27+
Then, in the vertex function of our shader, we apply an offset from the projection matrix to
28+
the inner vertices. Here's an example of how you might do this with a simple vignette shader:
29+
30+
.. code-block:: glsl
31+
32+
shader_type spatial;
33+
render_mode depth_test_disabled, skip_vertex_transform, unshaded, cull_disabled;
34+
35+
void vertex() {
36+
vec2 vert_pos = VERTEX.xy;
37+
38+
if (length(vert_pos) < 0.99) {
39+
vec4 offset = PROJECTION_MATRIX * vec4(0.0, 0.0, 1.0, 1.0);
40+
vert_pos += (offset.xy / offset.w);
41+
}
42+
43+
POSITION = vec4(vert_pos, 1.0, 1.0);
44+
}
45+
46+
void fragment() {
47+
ALBEDO = vec3(0.0);
48+
ALPHA = dot(UV * 2.0 - 1.0, UV * 2.0 - 1.0) * 2.0;
49+
}
50+
51+
52+
.. note:: For more info on asymmetric FOV and its purpose, see this
53+
`Meta Asymmetric Field of View FAQ <https://developers.meta.com/horizon/documentation/unity/unity-asymmetric-fov-faq/>`_.
54+
55+
Limitations
56+
-----------
57+
58+
Currently, custom post-processing effects that require reading from the screen texture effectively disable all
59+
rendering performance optimizations in XR. This is because, when reading from the screen texture,
60+
Godot makes a full copy of the render buffer. Since this may create performance issues, it is recommended
61+
that custom effects be limited to per-pixel ones such as the above vignette shader.

0 commit comments

Comments
 (0)