@@ -839,6 +839,154 @@ 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 many different shaders at once.
846
+ With a regular uniform this takes a lot of work as all these shaders need to be
847
+ tracked and the uniform needs to be set for each of them. Global uniforms allow
848
+ you to create and update uniforms that will be available in all shaders.
849
+
850
+ Global uniforms are especially useful for environmental effects that affect many
851
+ objects in a scene, like having foliage bend when the player is nearby, or having
852
+ objects move with the wind.
853
+
854
+ All these use cases are feasible thanks to global uniforms, which can be used in
855
+ every shader type (``canvas_item ``, ``spatial ``, ``particles ``, ``sky `` and
856
+ ``fog ``).
857
+
858
+ To create a global uniform, open the **Project Settings ** then go to the
859
+ **Shader Globals ** tab. Specify a name for the uniform (case-sensitive) and a
860
+ type, then click **Add ** in the top-right corner of the dialog. You can then
861
+ edit the value assigned to the uniform by clicking the value in the list of
862
+ uniforms:
863
+
864
+ .. figure :: img/shading_language_adding_global_uniforms.webp
865
+ :align: center
866
+ :alt: Adding a global uniform in the Shader Globals tab of the Project Settings
867
+
868
+ Adding a global uniform in the Shader Globals tab of the Project Settings
869
+
870
+ After creating a global uniform, you can use it in a shader as follows:
871
+
872
+ ::
873
+
874
+ shader_type canvas_item;
875
+
876
+ global uniform vec4 my_color;
877
+
878
+ void fragment() {
879
+ COLOR = my_color.rgb;
880
+ }
881
+
882
+ Note that the global uniform *must * exist in the Project Settings at the time
883
+ the shader is saved, or compilation will fail.
884
+
885
+ To change the value of a global uniform at run-time, use the
886
+ :ref: `RenderingServer.global_shader_parameter_set <class_RenderingServer_method_global_shader_parameter_set >`
887
+ method in a script:
888
+
889
+ ::
890
+
891
+ RenderingServer.global_shader_parameter_set("my_color", Color(0.3, 0.6, 1.0))
892
+
893
+ Assigning global uniform values can be done as many times as desired without
894
+ impacting performance, as setting data doesn't require synchronization between
895
+ the CPU and GPU.
896
+
897
+ You can also add or remove global uniforms at run-time:
898
+
899
+ ::
900
+
901
+ RenderingServer.global_shader_parameter_add("my_color", RenderingServer.GLOBAL_VAR_TYPE_COLOR, Color(0.3, 0.6, 1.0))
902
+ RenderingServer.global_shader_parameter_remove("my_color")
903
+
904
+ Adding or removing global uniforms at run-time has a performance cost, although
905
+ it's not as pronounced compared to getting global uniform values from a script
906
+ (see the warning below).
907
+
908
+ .. warning ::
909
+
910
+ While you *can * query the value of a global uniform at run-time in a script
911
+ using ``RenderingServer.global_shader_parameter_get("uniform_name") ``, this
912
+ has a large performance penalty as the rendering thread needs to synchronize
913
+ with the calling thread.
914
+
915
+ Therefore, it's not recommended to read global shader uniform values
916
+ continuously in a script. If you need to read values in a script after
917
+ setting them, consider creating an :ref: `autoload <doc_singletons_autoload >`
918
+ where you store the values you need to query at the same time you're setting
919
+ them as global uniforms.
920
+
921
+ .. _doc_shading_language_per_instance_uniforms :
922
+
923
+ Per-instance uniforms
924
+ ^^^^^^^^^^^^^^^^^^^^^
925
+
926
+ .. note ::
927
+
928
+ Per-instance uniforms are only available in ``spatial `` (3D) shaders.
929
+
930
+ Sometimes, you want to modify a parameter on each node using the material. As an
931
+ example, in a forest full of trees, when you want each tree to have a slightly
932
+ different color that is editable by hand. Without per-instance uniforms, this
933
+ requires creating a unique material for each tree (each with a slightly
934
+ different hue). This makes material management more complex, and also has a
935
+ performance overhead due to the scene requiring more unique material instances.
936
+ Vertex colors could also be used here, but they'd require creating unique copies
937
+ of the mesh for each different color, which also has a performance overhead.
938
+
939
+ Per-instance uniforms are set on each GeometryInstance3D, rather than on each
940
+ Material instance. Take this into account when working with meshes that have
941
+ multiple materials assigned to them, or MultiMesh setups.
942
+
943
+ ::
944
+
945
+ shader_type spatial;
946
+
947
+ // Provide a hint to edit as a color. Optionally, a default value can be provided.
948
+ // If no default value is provided, the type's default is used (e.g. opaque black for colors).
949
+ instance uniform vec4 my_color : source_color = vec4(1.0, 0.5, 0.0, 1.0);
950
+
951
+ void fragment() {
952
+ ALBEDO = my_color.rgb;
953
+ }
954
+
955
+ After saving the shader, you can change the per-instance uniform's value using
956
+ the inspector:
957
+
958
+ .. figure :: img/shading_language_per_instance_uniforms_inspector.webp
959
+ :align: center
960
+ :alt: Setting a per-instance uniform's value in the GeometryInstance3D section of the inspector
961
+
962
+ Setting a per-instance uniform's value in the GeometryInstance3D section of the inspector
963
+
964
+ Per-instance uniform values can also be set at run-time using
965
+ `set_instance_shader_parameter<class_GeometryInstance3D_method_set_instance_shader_parameter> `
966
+ method on a node that inherits from :ref: `class_GeometryInstance3D `:
967
+
968
+ ::
969
+
970
+ $MeshInstance3D.set_instance_shader_parameter("my_color", Color(0.3, 0.6, 1.0))
971
+
972
+ When using per-instance uniforms, there are some restrictions you should be aware of:
973
+
974
+ - **Per-instance uniforms do not support textures **, only regular scalar and
975
+ vector types. As a workaround, you can pass a texture array as a regular
976
+ uniform, then pass the index of the texture to be drawn using a per-instance
977
+ uniform.
978
+ - There is a practical maximum limit of 16 instance uniforms per shader.
979
+ - If your mesh uses multiple materials, the parameters for the first mesh
980
+ material found will "win" over the subsequent ones, unless they have the same
981
+ name, index *and * type. In this case, all parameters are affected correctly.
982
+ - If you run into the above situation, you can avoid clashes by manually
983
+ specifying the index (0-15) of the instance uniform by using the
984
+ ``instance_index `` hint:
985
+
986
+ ::
987
+
988
+ instance uniform vec4 my_color : source_color, instance_index(5);
989
+
842
990
Built-in variables
843
991
------------------
844
992
0 commit comments