@@ -507,3 +507,158 @@ If you want the lights to add together, add the light contribution to ``DIFFUSE_
507
507
materials from appearing in screen-space reflections or refraction.
508
508
:ref: `SDFGI <doc_using_sdfgi >` sharp reflections are not visible on transparent
509
509
materials (only rough reflections are visible on transparent materials).
510
+
511
+
512
+
513
+ Coordinate spaces
514
+ ^^^^^^^^^^^^^^^^^
515
+
516
+ Spatial shaders do their work across multiple coordinate spaces. Some built-in variables with the same name are in different
517
+ coordinate spaces in different processor functions.
518
+
519
+ +-------------------------------+----------------------------------------------------------------------------------------+
520
+ | Coordinate space | Description |
521
+ +===============================+========================================================================================+
522
+ | Model space | Also called "local space" or "local coordinates". Called "object space" in |
523
+ | | other renderers. Equivalent to the local coordinates used by Transform3D. |
524
+ +-------------------------------+----------------------------------------------------------------------------------------+
525
+ | World space | Equivalent to the global coordinates used by Transform3D. |
526
+ | | |
527
+ +-------------------------------+----------------------------------------------------------------------------------------+
528
+ | View space | Coordinate space relative to the camera. |
529
+ | | Called "camera space" or "eye space" in other renderers. |
530
+ +-------------------------------+----------------------------------------------------------------------------------------+
531
+ | Clip space | TODO |
532
+ +-------------------------------+----------------------------------------------------------------------------------------+
533
+ | Screen space | TODO |
534
+ +-------------------------------+----------------------------------------------------------------------------------------+
535
+ | Normalized device coordinates | Usually not used directly. ``xy `` alues range from ``-1.0 `` to ``1.0 ``, with |
536
+ | | ``(-1.0,-1.0) `` in the ``x `` and ``y `` being the upper-left corner of the screen, |
537
+ | | and ``(1.0,1.0) `` the lower right. ``z `` ranges from ``0.0 `` to ``1.0 `` |
538
+ +-------------------------------+----------------------------------------------------------------------------------------+
539
+
540
+ .. note ::
541
+
542
+ Godot 4.3 introduced a change to clip space. If you are using a shader that uses clip space directly and was
543
+ originally written for an earlier version, see `this <https://godotengine.org/article/introducing-reverse-z/ >`_.
544
+
545
+
546
+
547
+ Working with coordinate spaces
548
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
549
+
550
+ You don't need to know much matrix math in order to use coordinate spaces. You can convert vectors between different coordinate spaces by using the built-in transform matrices.
551
+
552
+ To transform a *position * vector ``VERTEX `` from view space to world space, multiply it by
553
+ the view-to-world matrix ``INV_VIEW_MATRIX ``:
554
+
555
+ .. code-block :: glsl
556
+
557
+ void fragment() {
558
+ vec3 position_world = (INV_VIEW_MATRIX * vec4(VERTEX, 1.0)).xyz;
559
+ }
560
+
561
+ To transform a *direction * vector, such as ``NORMAL ``, change the ``z `` field of the vec4 to ``0.0 `` :
562
+
563
+ .. code-block :: glsl
564
+
565
+ void fragment() {
566
+ vec3 normal_world = (INV_VIEW_MATRIX * vec4(NORMAL, 0.0)).xyz;
567
+ }
568
+
569
+ You can also compose multiple transformations together. To transform ``VERTEX `` from model space to view space, first
570
+ transform it from view to world space with ``MODEL_MATRIX ``, then transform it from world space to view space with ``VIEW_MATRIX ``.
571
+ Note the order of the matrices:
572
+
573
+ .. code-block :: glsl
574
+
575
+ void vertex() {
576
+ vec3 position_view = (VIEW_MATRIX * MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz;
577
+ }
578
+
579
+ You can transform to one coordinate space, do some operations, and transform back. This code scales ``VERTEX `` in model space,
580
+ translates it in world space, then transforms back into model space, so it can be passed to ``fragment() ``:
581
+
582
+ .. code-block :: glsl
583
+
584
+ void vertex() {
585
+ VERTEX *= 2.0;
586
+ vec3 position_world = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz;
587
+ position_world += vec3(1.0);
588
+ VERTEX = (inverse(MODEL_MATRIX) * vec4(position_world, 1.0)).xyz;
589
+ }
590
+
591
+ Clip space, screen space, and normalized device coordinates
592
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
593
+
594
+ Transforming between view space, clip space, and screen space is more complicated. You need to use normalized device coordinates,
595
+ an intermediate coordinate space.
596
+
597
+ View space position to screen space UV:
598
+
599
+ .. code-block :: glsl
600
+
601
+ vec2 screen_uv_from_view(vec3 position_view, mat4 projection_matrix) {
602
+ vec3 position_clip = projection_matrix * vec4(position_view, 1.0);
603
+ vec3 ndc = position_clip.xyz / position_clip.w;
604
+ return ndc.xy * 0.5 + 0.5;
605
+ }
606
+
607
+ Screen space UV (and depth) to view space position:
608
+
609
+ .. code-block :: glsl
610
+
611
+ vec3 view_position_from_uv_depth(vec2 screen_uv, float depth, mat4 inv_projection_matrix) {
612
+ vec3 ndc = vec3((screen_uv * 2.0) - 1.0, depth);
613
+ vec4 position_view = inv_projection_matrix * vec4(ndc, 1.0);
614
+ return position_view.xyz /= view_position.w;
615
+ }
616
+
617
+ Clip space to screen space:
618
+
619
+ .. code-block :: glsl
620
+
621
+ vec2 screen_uv_from_clip(vec3 position_clip, mat4 projection_matrix) {
622
+ vec3 ndc = position_clip.xyz / position_clip.w;
623
+ return ndc.xy * 0.5 + 0.5;
624
+ }
625
+
626
+ Screen space to clip space:
627
+
628
+ .. code-block :: glsl
629
+
630
+ vec3 clip_from_screen_uv_depth(vec3 ndc, float w) {
631
+ // TODO
632
+ }
633
+
634
+ Sometimes you may need to work with normalized device coordinates directly:
635
+
636
+ Clip space to NDC:
637
+
638
+ .. code-block :: glsl
639
+
640
+ vec3 ndc_from_clip(vec4 position_clip) {
641
+ return position_clip.xyz / position_clip.w;
642
+ }
643
+
644
+ Normalized device coordinates to clip space:
645
+
646
+ .. code-block :: glsl
647
+
648
+ // TODO
649
+
650
+ Normalized device coordinates to screen space:
651
+
652
+ .. code-block :: glsl
653
+
654
+ vec2 screen_uv_from_ndc(vec3 ndc)) {
655
+ return ndc.xy * 0.5 + 0.5;
656
+ }
657
+
658
+ Screen space (and depth) to normalized device coordinates:
659
+
660
+ .. code-block :: glsl
661
+
662
+ vec3 ndc_from_uv_depth(vec2 screen_uv, float depth)) {
663
+ return vec3((screen_uv * 2.0) - 1.0, depth);
664
+ }
0 commit comments