@@ -839,6 +839,191 @@ The syntax also supports subgroups (it's not mandatory to declare the base group
839
839
840
840
group_uniforms MyGroup.MySubgroup;
841
841
842
+ Global uniforms
843
+ ^^^^^^^^^^^^^^^
844
+
845
+ Sometimes, you want to modify a parameter in a lot of instances of a material.
846
+ This takes a lot of work as all these instances need to be tracked and the
847
+ uniform needs to be set for each of them.
848
+
849
+ Example use cases include:
850
+
851
+ 1. **Providing player information to all relevant shaders. ** You may want to let
852
+ your shaders know where the player is. As an example, the grass and some
853
+ bushes will bend when the player is close, simulating being pushed.
854
+ 2. **Modifying the world without actually modifying it. ** Modern games have a lot
855
+ of grass, yet you can do precise cuts to it, burn it, etc. How do they do it?
856
+ Is every bit of grass a mesh and an object? Not really, games generally just
857
+ use a texture aligned to the world (that often moves with you), with different
858
+ colors meaning different things. In this case they can use texture channels to
859
+ specify that the grass has been cut, burnt, etc. The vertex shader can make
860
+ the vertices disappear, or change the color based on this global uniform
861
+ texture.
862
+ 3. **Controlling the weather and environment. ** Nowadays, games have realistic
863
+ weather, with leaves and trees moving with the wind. Do they make animations
864
+ for each piece of grass? Not really, you can save the wind strength and
865
+ direction in a global uniform, then procedurally move the foliage with
866
+ different speed and intensity. This can even affect particle system shaders,
867
+ making fire and smoke propagate in the direction of the wind. Shooters often
868
+ have what is called a turbulence texture, which is a texture that contains
869
+ the local wind direction around the player. All relevant shaders can access
870
+ it and it's what allows explosions to move trees and grass around.
871
+ 4. **Making regular materials interact with the environment. ** This is often
872
+ overlooked. We think materials are edited and that's it, but that's not
873
+ always the case. Imagine it starts raining and you want your objects to
874
+ become wet. You need to change the metallic and roughness factors. For
875
+ floors, you want to draw droplets splashing. For walls, you want to draw the
876
+ water pouring down. You could control this with regular uniforms, but it
877
+ would be more time-consuming to set this on every material when it starts
878
+ raining.
879
+ 5. **Providing team colors. ** In team-based games, you can use global uniforms
880
+ to provide "friendly" and "enemy" colors that can automatically be used
881
+ everywhere relevant (player materials, map textures, special effects, GUI
882
+ elements, ...). This can be used to let players choose team colors freely, for
883
+ better accessibility. The "friendly" and "enemy" states themselves can be
884
+ determined by using a :ref: `per-instance uniform
885
+ <doc_shading_language_per_instance_uniforms>` that indicates the instance's
886
+ current team.
887
+
888
+ Gqlobal uniforms can help you add a lot of detail to your game. In Godot, they
889
+ work for every shader type, including the recently introduced sky shaders.
890
+
891
+ All these use cases are feasible thanks to global uniforms, which can be used in
892
+ every shader type (``canvas_item ``, ``spatial ``, ``particles ``, ``sky `` and
893
+ ``fog ``).
894
+
895
+ To create a global uniform, open the **Project Settings ** then go to the
896
+ **Shader Globals ** tab. Specify a name for the uniform (case-sensitive) and a
897
+ type, then click **Add ** in the top-right corner of the dialog. You can then
898
+ edit the value assigned to the uniform by clicking the value in the list of
899
+ uniforms:
900
+
901
+ .. figure :: img/shading_language_adding_global_uniforms.webp
902
+ :align: center
903
+ :alt: Adding a global uniform in the Shader Globals tab of the Project Settings
904
+
905
+ Adding a global uniform in the Shader Globals tab of the Project Settings
906
+
907
+ After creating a global uniform, you can use it in a shader as follows:
908
+
909
+ ::
910
+
911
+ shader_type canvas_item;
912
+
913
+ global uniform vec4 my_color;
914
+
915
+ void fragment() {
916
+ COLOR = my_color.rgb;
917
+ }
918
+
919
+ Note that the global uniform *must * exist in the Project Settings at the time
920
+ the shader is saved, or compilation will fail.
921
+
922
+ To change the value of a global uniform at run-time, use the
923
+ :ref: `RenderingServer.global_shader_parameter_set <class_RenderingServer_method_global_shader_parameter_set >`
924
+ method in a script:
925
+
926
+ ::
927
+
928
+ RenderingServer.global_shader_parameter_set("my_color", Color(0.3, 0.6, 1.0))
929
+
930
+ Assigning global uniform values can be done as many times as desired without
931
+ impacting performance, as setting data doesn't require synchronization between
932
+ the CPU and GPU.
933
+
934
+ You can also add or remove global uniforms at run-time:
935
+
936
+ ::
937
+
938
+ RenderingServer.global_shader_parameter_add("my_color", RenderingServer.GLOBAL_VAR_TYPE_COLOR, Color(0.3, 0.6, 1.0))
939
+ RenderingServer.global_shader_parameter_remove("my_color")
940
+
941
+ Adding or removing global uniforms at run-time has a performance cost, although
942
+ it's not as pronounced comparing to getting global uniform values from a script
943
+ (see the warning below).
944
+
945
+ .. warning ::
946
+
947
+ While you *can * query the value of a global uniform at run-time in a script
948
+ using ``RenderingServer.global_shader_parameter_set("uniform_name") ``, this
949
+ has a large performance penalty as the CPU must wait for the GPU to be
950
+ synchronized every time the value is queried.
951
+
952
+ Therefore, it's not recommended to read global shader uniform values
953
+ continuously in a script. If you need to read values in a script after
954
+ setting them, consider creating an :ref: `autoload <doc_singletons_autoload >`
955
+ where you store the values you need to query at the same time you're setting
956
+ them as global uniforms.
957
+
958
+ .. _doc_shading_language_per_instance_uniforms :
959
+
960
+ Per-instance uniforms
961
+ ^^^^^^^^^^^^^^^^^^^^^
962
+
963
+ .. note ::
964
+
965
+ Per-instance uniforms are only available in ``spatial `` (3D) shaders.
966
+
967
+ Sometimes, you want to modify a parameter on each node using the material. As an
968
+ example, in a forest full of trees, when you want each tree to have a slightly
969
+ different color that is editable by hand. Without per-instance uniforms, this
970
+ requires creating a unique material for each tree (each with a slightly
971
+ different hue). This makes material management more complex, and also has a
972
+ performance overhead due to the scene requiring more unique material instances.
973
+ Vertex colors could also be used here, but they'd require creating unique copies
974
+ of the mesh for each different color, which also has a performance overhead.
975
+
976
+ Per-instance uniforms are set on each GeometryInstance3D, rather than on each
977
+ Material instance. Take this into account when working with meshes that have
978
+ multiple materials assigned to them, or MultiMesh setups.
979
+
980
+ ::
981
+
982
+ shader_type spatial;
983
+
984
+ // Provide a hint to edit as a color. Optionally, a default value can be provided.
985
+ // If no default value is provided, the type's default is used (e.g. opaque black for colors).
986
+ instance uniform vec4 my_color : source_color = vec4(1.0, 0.5, 0.0, 1.0);
987
+
988
+ void fragment() {
989
+ ALBEDO = my_color.rgb;
990
+ }
991
+
992
+ After saving the shader, you can change the per-instance uniform's value using
993
+ the inspector:
994
+
995
+ .. figure :: img/shading_language_per_instance_uniforms_inspector.webp
996
+ :align: center
997
+ :alt: Setting a per-instance uniform's value in the GeometryInstance3D section of the inspector
998
+
999
+ Setting a per-instance uniform's value in the GeometryInstance3D section of the inspector
1000
+
1001
+ Per-instance uniform values can also be set at run-time using
1002
+ `set_instance_shader_parameter<class_GeometryInstance3D_method_set_instance_shader_parameter> `
1003
+ method on a node that inherits from :ref: `class_GeometryInstance3D `:
1004
+
1005
+ ::
1006
+
1007
+ $MeshInstance3D.set_instance_shader_parameter("my_color", Color(0.3, 0.6, 1.0))
1008
+
1009
+ When using per-instance uniforms, there are some restrictions you should be aware of:
1010
+
1011
+ - **Per-instance uniforms do not support textures **, only regular scalar and
1012
+ vector types. As a workaround, you can pass a texture array as a regular
1013
+ uniform, then pass the index of the texture to be drawn using a per-instance
1014
+ uniform.
1015
+ - There is a practical maximum limit of 16 instance uniforms per shader.
1016
+ - If your mesh uses multiple materials, the parameters for the first mesh
1017
+ material found will "win" over the subsequent ones, unless they have the same
1018
+ name, index *and * type. In this case, all parameters are affected correctly.
1019
+ - If you run into the above situation, you can avoid clashes by manually
1020
+ specifying the index (0-15) of the instance uniform by using the
1021
+ ``instance_index `` hint:
1022
+
1023
+ ::
1024
+
1025
+ instance uniform vec4 my_color : source_color, instance_index(5);
1026
+
842
1027
Built-in variables
843
1028
------------------
844
1029
0 commit comments