Browse Source

Reorganize and improve shader Uniforms section

tetrapod00 11 months ago
parent
commit
3ee7142208
1 changed files with 181 additions and 160 deletions
  1. 181 160
      tutorials/shaders/shader_reference/shading_language.rst

+ 181 - 160
tutorials/shaders/shader_reference/shading_language.rst

@@ -14,6 +14,8 @@ If you are already familiar with GLSL, the :ref:`Godot Shader Migration
 Guide<doc_converting_glsl_to_godot_shaders>` is a resource that will help you
 transition from regular GLSL to Godot's shading language.
 
+.. _doc_shading_language_data_types:
+
 Data types
 ----------
 
@@ -813,10 +815,11 @@ There are two possible interpolation qualifiers:
 Uniforms
 --------
 
-Passing values to shaders is possible. These are global to the whole shader and
-are called *uniforms*. When a shader is later assigned to a material, the
-uniforms will appear as editable parameters in it. Uniforms can't be written
-from within the shader. Any GLSL type except for ``void`` can be a uniform.
+Passing values to shaders is possible with *uniforms*, which are defined in the
+global scope of the shader, outside of functions. When a shader is later
+assigned to a material, the uniforms will appear as editable parameters in the
+material's inspector. Uniforms can't be written from within the shader. Any
+:ref:`data type <doc_shading_language_data_types>` except for ``void`` can be a uniform.
 
 .. code-block:: glsl
 
@@ -826,49 +829,8 @@ from within the shader. Any GLSL type except for ``void`` can be a uniform.
 
     uniform vec3 colors[3];
 
-You can set uniforms in the editor in the material. Or you can set them through
-GDScript:
-
-.. code-block:: gdscript
-
-  material.set_shader_parameter("some_value", some_value)
-
-  material.set_shader_parameter("colors", [Vector3(1, 0, 0), Vector3(0, 1, 0), Vector3(0, 0, 1)])
-
-You can access ``int`` values as a readable dropdown widget using the ``hint_enum`` uniform:
-
-.. code-block:: glsl
-
-    uniform int noise_type : hint_enum("OpenSimplex2", "Cellular", "Perlin", "Value") = 0;
-
-.. note:: Unlike ``@export_enum`` in GDScript, the ``hint_enum`` uniform does not support
-          the use of ``String``\ s, it only supports ``int``\ s.
-
-You can assign explicit values to the ``hint_enum`` uniform using colon syntax similar to GDScript:
-
-.. code-block:: glsl
- 
-    uniform int character_speed: hint_enum("Slow:30", "Average:60", "Very Fast:200") = 60;
-
-The value will be stored as an integer, corresponding to the index of the selected option (i.e. 0, 1, or 2)
-or the value assigned by colon syntax (i.e. 30, 60, or 200).
-
-.. note:: The first argument to ``set_shader_parameter`` is the name of the uniform
-          in the shader. It must match *exactly* to the name of the uniform in
-          the shader or else it will not be recognized.
-
-.. note:: There is a limit to the total size of shader uniforms that you can use
-          in a single shader. On most desktop platforms, this limit is ``65536``
-          bytes, or 4096 ``vec4`` uniforms. On mobile platforms, the limit is
-          typically ``16384`` bytes, or 1024 ``vec4`` uniforms. Vector uniforms
-          smaller than a ``vec4``, such as ``vec2`` or ``vec3``, are padded to
-          the size of a ``vec4``. Scalar uniforms such as ``int`` or ``float``
-          are not padded, and ``bool`` is padded to the size of an ``int``.
-
-          Arrays count as the total size of their contents. If you need a uniform
-          array that is larger than this limit, consider packing the data into a
-          texture instead, since the *contents* of a texture do not count towards
-          this limit, only the size of the sampler uniform.
+You can set uniforms in the editor in the material's inspector. Alternately, you
+can set them :ref:`from code <doc_shading_language_setting_uniforms_from_code>`.
 
 Uniform hints
 ~~~~~~~~~~~~~
@@ -885,24 +847,16 @@ uniform is used for, and how the editor should allow users to modify it.
     uniform vec4 other_color : source_color = vec4(1.0); // Default values go after the hint.
     uniform sampler2D image : source_color;
 
-.. admonition:: Source Color
+Uniforms can also be assigned default values:
 
-    Any texture which contains *sRGB color data* requires a ``source_color`` hint
-    in order to be correctly sampled. This is because Godot renders in linear
-    color space, but some textures contain sRGB color data. If this hint is not
-    used, the texture will appear washed out.
+.. code-block:: glsl
 
-    Albedo and color textures should typically have a ``source_color`` hint. Normal,
-    roughness, metallic, and height textures typically do not need a ``source_color``
-    hint.
+    shader_type spatial;
 
-    Using ``source_color`` hint is required in the Forward+ and Mobile renderers,
-    and in ``canvas_item`` shaders when :ref:`HDR 2D<class_ProjectSettings_property_rendering/viewport/hdr_2d>`
-    is enabled. The ``source_color`` hint is optional for the Compatibility renderer,
-    and for ``canvas_item`` shaders if ``HDR 2D`` is disabled. However, it is
-    recommended to always use the ``source_color`` hint, because it works even
-    if you change renderers or disable ``HDR 2D``.
+    uniform vec4 some_vector = vec4(0.0);
+    uniform vec4 some_color : source_color = vec4(1.0);
 
+Note that when adding a default value and a hint, the default value goes after the hint.
 
 Full list of uniform hints below:
 
@@ -942,114 +896,51 @@ Full list of uniform hints below:
 | **sampler2D**        | hint_normal_roughness_texture                    | Texture is the normal roughness texture (only supported in Forward+).       |
 +----------------------+--------------------------------------------------+-----------------------------------------------------------------------------+
 
-GDScript uses different variable types than GLSL does, so when passing variables
-from GDScript to shaders, Godot converts the type automatically. Below is a
-table of the corresponding types:
+Using ``hint_enum``
+^^^^^^^^^^^^^^^^^^^
 
-+------------------------+-------------------------+------------------------------------------------------------+
-| GLSL type              | GDScript type           | Notes                                                      |
-+========================+=========================+============================================================+
-| **bool**               | **bool**                |                                                            |
-+------------------------+-------------------------+------------------------------------------------------------+
-| **bvec2**              | **int**                 | Bitwise packed int where bit 0 (LSB) corresponds to x.     |
-|                        |                         |                                                            |
-|                        |                         | For example, a bvec2 of (bx, by) could be created in       |
-|                        |                         | the following way:                                         |
-|                        |                         |                                                            |
-|                        |                         | .. code-block:: gdscript                                   |
-|                        |                         |                                                            |
-|                        |                         |   bvec2_input: int = (int(bx)) | (int(by) << 1)            |
-|                        |                         |                                                            |
-+------------------------+-------------------------+------------------------------------------------------------+
-| **bvec3**              | **int**                 | Bitwise packed int where bit 0 (LSB) corresponds to x.     |
-+------------------------+-------------------------+------------------------------------------------------------+
-| **bvec4**              | **int**                 | Bitwise packed int where bit 0 (LSB) corresponds to x.     |
-+------------------------+-------------------------+------------------------------------------------------------+
-| **int**                | **int**                 |                                                            |
-+------------------------+-------------------------+------------------------------------------------------------+
-| **ivec2**              | **Vector2i**            |                                                            |
-+------------------------+-------------------------+------------------------------------------------------------+
-| **ivec3**              | **Vector3i**            |                                                            |
-+------------------------+-------------------------+------------------------------------------------------------+
-| **ivec4**              | **Vector4i**            |                                                            |
-+------------------------+-------------------------+------------------------------------------------------------+
-| **uint**               | **int**                 |                                                            |
-+------------------------+-------------------------+------------------------------------------------------------+
-| **uvec2**              | **Vector2i**            |                                                            |
-+------------------------+-------------------------+------------------------------------------------------------+
-| **uvec3**              | **Vector3i**            |                                                            |
-+------------------------+-------------------------+------------------------------------------------------------+
-| **uvec4**              | **Vector4i**            |                                                            |
-+------------------------+-------------------------+------------------------------------------------------------+
-| **float**              | **float**               |                                                            |
-+------------------------+-------------------------+------------------------------------------------------------+
-| **vec2**               | **Vector2**             |                                                            |
-+------------------------+-------------------------+------------------------------------------------------------+
-| **vec3**               | **Vector3**, **Color**  | When Color is used, it will be interpreted as (r, g, b).   |
-+------------------------+-------------------------+------------------------------------------------------------+
-| **vec4**               | **Vector4**, **Color**, | When Color is used, it will be interpreted as (r, g, b, a).|
-|                        | **Rect2**, **Plane**,   |                                                            |
-|                        | **Quaternion**          | When Rect2 is used, it will be interpreted as              |
-|                        |                         | (position.x, position.y, size.x, size.y).                  |
-|                        |                         |                                                            |
-|                        |                         | When Plane is used it will be interpreted as               |
-|                        |                         | (normal.x, normal.y, normal.z, d).                         |
-|                        |                         |                                                            |
-|                        |                         |                                                            |
-+------------------------+-------------------------+------------------------------------------------------------+
-| **mat2**               | **Transform2D**         |                                                            |
-|                        |                         |                                                            |
-+------------------------+-------------------------+------------------------------------------------------------+
-| **mat3**               | **Basis**               |                                                            |
-+------------------------+-------------------------+------------------------------------------------------------+
-| **mat4**               | **Projection**,         | When a Transform3D is used, the w Vector is set to the     |
-|                        | **Transform3D**         | identity.                                                  |
-+------------------------+-------------------------+------------------------------------------------------------+
-| **sampler2D**          | **Texture2D**           |                                                            |
-+------------------------+-------------------------+------------------------------------------------------------+
-| **isampler2D**         | **Texture2D**           |                                                            |
-+------------------------+-------------------------+------------------------------------------------------------+
-| **usampler2D**         | **Texture2D**           |                                                            |
-+------------------------+-------------------------+------------------------------------------------------------+
-| **sampler2DArray**     | **Texture2DArray**      |                                                            |
-+------------------------+-------------------------+------------------------------------------------------------+
-| **isampler2DArray**    | **Texture2DArray**      |                                                            |
-+------------------------+-------------------------+------------------------------------------------------------+
-| **usampler2DArray**    | **Texture2DArray**      |                                                            |
-+------------------------+-------------------------+------------------------------------------------------------+
-| **sampler3D**          | **Texture3D**           |                                                            |
-+------------------------+-------------------------+------------------------------------------------------------+
-| **isampler3D**         | **Texture3D**           |                                                            |
-+------------------------+-------------------------+------------------------------------------------------------+
-| **usampler3D**         | **Texture3D**           |                                                            |
-+------------------------+-------------------------+------------------------------------------------------------+
-| **samplerCube**        | **Cubemap**             | See :ref:`doc_importing_images_changing_import_type` for   |
-|                        |                         | instructions on importing cubemaps for use in Godot.       |
-+------------------------+-------------------------+------------------------------------------------------------+
-| **samplerCubeArray**   | **CubemapArray**        | Only supported in Forward+ and Mobile, not Compatibility.  |
-+------------------------+-------------------------+------------------------------------------------------------+
-| **samplerExternalOES** | **ExternalTexture**     | Only supported in Compatibility/Android platform.          |
-+------------------------+-------------------------+------------------------------------------------------------+
+You can access ``int`` values as a readable dropdown widget using the ``hint_enum`` uniform:
 
-.. note:: Be careful when setting shader uniforms from GDScript, no error will
-          be thrown if the type does not match. Your shader will just exhibit
-          undefined behavior.
+.. code-block::
 
-.. warning::
-    As with the last note, no error will be thrown if the typing does not match while setting a shader uniform, this unintuitively includes setting a (GDscript) 64 bit int/float into a Godot shader language int/float (32 bit). This may lead to unintentional consequences in cases where high precision is required.
+    uniform int noise_type : hint_enum("OpenSimplex2", "Cellular", "Perlin", "Value") = 0;
 
-Uniforms can also be assigned default values:
+You can assign explicit values to the ``hint_enum`` uniform using colon syntax similar to GDScript:
 
-.. code-block:: glsl
+.. code-block::
+ 
+    uniform int character_speed: hint_enum("Slow:30", "Average:60", "Very Fast:200") = 60;
 
-    shader_type spatial;
+The value will be stored as an integer, corresponding to the index of the selected
+option (i.e. ``0``, ``1``, or ``2``) or the value assigned by colon syntax
+(i.e. ``30``, ``60``, or ``200``). When setting the value with
+``set_shader_parameter()``, you must use the integer value, not the ``String``
+name.
 
-    uniform vec4 some_vector = vec4(0.0);
-    uniform vec4 some_color : source_color = vec4(1.0);
+Using ``source_color``
+^^^^^^^^^^^^^^^^^^^^^^
 
-Note that when adding a default value and a hint, the default value goes after the hint.
+Any texture which contains *sRGB color data* requires a ``source_color`` hint
+in order to be correctly sampled. This is because Godot renders in linear
+color space, but some textures contain sRGB color data. If this hint is not
+used, the texture will appear washed out.
+
+Albedo and color textures should typically have a ``source_color`` hint. Normal,
+roughness, metallic, and height textures typically do not need a ``source_color``
+hint.
+
+Using ``source_color`` hint is required in the Forward+ and Mobile renderers,
+and in ``canvas_item`` shaders when :ref:`HDR 2D<class_ProjectSettings_property_rendering/viewport/hdr_2d>`
+is enabled. The ``source_color`` hint is optional for the Compatibility renderer,
+and for ``canvas_item`` shaders if ``HDR 2D`` is disabled. However, it is
+recommended to always use the ``source_color`` hint, because it works even
+if you change renderers or disable ``HDR 2D``.
 
-If you need to make multiple uniforms to be grouped in the specific category of an inspector, you can use a `group_uniform` keyword like:
+Uniform groups
+~~~~~~~~~~~~~~
+
+To group multiple uniforms in a section in the inspector, you can use a
+``group_uniform`` keyword like this:
 
 .. code-block:: glsl
 
@@ -1219,6 +1110,136 @@ When using per-instance uniforms, there are some restrictions you should be awar
 
     instance uniform vec4 my_color : source_color, instance_index(5);
 
+.. _doc_shading_language_setting_uniforms_from_code:
+
+Setting uniforms from code
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can set uniforms from GDScript:
+
+.. code-block:: gdscript
+
+  material.set_shader_parameter("some_value", some_value)
+
+  material.set_shader_parameter("colors", [Vector3(1, 0, 0), Vector3(0, 1, 0), Vector3(0, 0, 1)])
+
+.. note:: The first argument to ``set_shader_parameter`` is the name of the uniform
+          in the shader. It must match *exactly* to the name of the uniform in
+          the shader or else it will not be recognized.
+
+GDScript uses different variable types than GLSL does, so when passing variables
+from GDScript to shaders, Godot converts the type automatically. Below is a
+table of the corresponding types:
+
++------------------------+-------------------------+------------------------------------------------------------+
+| GLSL type              | GDScript type           | Notes                                                      |
++========================+=========================+============================================================+
+| **bool**               | **bool**                |                                                            |
++------------------------+-------------------------+------------------------------------------------------------+
+| **bvec2**              | **int**                 | Bitwise packed int where bit 0 (LSB) corresponds to x.     |
+|                        |                         |                                                            |
+|                        |                         | For example, a bvec2 of (bx, by) could be created in       |
+|                        |                         | the following way:                                         |
+|                        |                         |                                                            |
+|                        |                         | .. code-block:: gdscript                                   |
+|                        |                         |                                                            |
+|                        |                         |   bvec2_input: int = (int(bx)) | (int(by) << 1)            |
+|                        |                         |                                                            |
++------------------------+-------------------------+------------------------------------------------------------+
+| **bvec3**              | **int**                 | Bitwise packed int where bit 0 (LSB) corresponds to x.     |
++------------------------+-------------------------+------------------------------------------------------------+
+| **bvec4**              | **int**                 | Bitwise packed int where bit 0 (LSB) corresponds to x.     |
++------------------------+-------------------------+------------------------------------------------------------+
+| **int**                | **int**                 |                                                            |
++------------------------+-------------------------+------------------------------------------------------------+
+| **ivec2**              | **Vector2i**            |                                                            |
++------------------------+-------------------------+------------------------------------------------------------+
+| **ivec3**              | **Vector3i**            |                                                            |
++------------------------+-------------------------+------------------------------------------------------------+
+| **ivec4**              | **Vector4i**            |                                                            |
++------------------------+-------------------------+------------------------------------------------------------+
+| **uint**               | **int**                 |                                                            |
++------------------------+-------------------------+------------------------------------------------------------+
+| **uvec2**              | **Vector2i**            |                                                            |
++------------------------+-------------------------+------------------------------------------------------------+
+| **uvec3**              | **Vector3i**            |                                                            |
++------------------------+-------------------------+------------------------------------------------------------+
+| **uvec4**              | **Vector4i**            |                                                            |
++------------------------+-------------------------+------------------------------------------------------------+
+| **float**              | **float**               |                                                            |
++------------------------+-------------------------+------------------------------------------------------------+
+| **vec2**               | **Vector2**             |                                                            |
++------------------------+-------------------------+------------------------------------------------------------+
+| **vec3**               | **Vector3**, **Color**  | When Color is used, it will be interpreted as (r, g, b).   |
++------------------------+-------------------------+------------------------------------------------------------+
+| **vec4**               | **Vector4**, **Color**, | When Color is used, it will be interpreted as (r, g, b, a).|
+|                        | **Rect2**, **Plane**,   |                                                            |
+|                        | **Quaternion**          | When Rect2 is used, it will be interpreted as              |
+|                        |                         | (position.x, position.y, size.x, size.y).                  |
+|                        |                         |                                                            |
+|                        |                         | When Plane is used it will be interpreted as               |
+|                        |                         | (normal.x, normal.y, normal.z, d).                         |
+|                        |                         |                                                            |
+|                        |                         |                                                            |
++------------------------+-------------------------+------------------------------------------------------------+
+| **mat2**               | **Transform2D**         |                                                            |
+|                        |                         |                                                            |
++------------------------+-------------------------+------------------------------------------------------------+
+| **mat3**               | **Basis**               |                                                            |
++------------------------+-------------------------+------------------------------------------------------------+
+| **mat4**               | **Projection**,         | When a Transform3D is used, the w Vector is set to the     |
+|                        | **Transform3D**         | identity.                                                  |
++------------------------+-------------------------+------------------------------------------------------------+
+| **sampler2D**          | **Texture2D**           |                                                            |
++------------------------+-------------------------+------------------------------------------------------------+
+| **isampler2D**         | **Texture2D**           |                                                            |
++------------------------+-------------------------+------------------------------------------------------------+
+| **usampler2D**         | **Texture2D**           |                                                            |
++------------------------+-------------------------+------------------------------------------------------------+
+| **sampler2DArray**     | **Texture2DArray**      |                                                            |
++------------------------+-------------------------+------------------------------------------------------------+
+| **isampler2DArray**    | **Texture2DArray**      |                                                            |
++------------------------+-------------------------+------------------------------------------------------------+
+| **usampler2DArray**    | **Texture2DArray**      |                                                            |
++------------------------+-------------------------+------------------------------------------------------------+
+| **sampler3D**          | **Texture3D**           |                                                            |
++------------------------+-------------------------+------------------------------------------------------------+
+| **isampler3D**         | **Texture3D**           |                                                            |
++------------------------+-------------------------+------------------------------------------------------------+
+| **usampler3D**         | **Texture3D**           |                                                            |
++------------------------+-------------------------+------------------------------------------------------------+
+| **samplerCube**        | **Cubemap**             | See :ref:`doc_importing_images_changing_import_type` for   |
+|                        |                         | instructions on importing cubemaps for use in Godot.       |
++------------------------+-------------------------+------------------------------------------------------------+
+| **samplerCubeArray**   | **CubemapArray**        | Only supported in Forward+ and Mobile, not Compatibility.  |
++------------------------+-------------------------+------------------------------------------------------------+
+| **samplerExternalOES** | **ExternalTexture**     | Only supported in Compatibility/Android platform.          |
++------------------------+-------------------------+------------------------------------------------------------+
+
+.. note:: Be careful when setting shader uniforms from GDScript, no error will
+          be thrown if the type does not match. Your shader will just exhibit
+          undefined behavior.
+
+.. warning::
+    As with the last note, no error will be thrown if the typing does not match while setting a shader uniform, this unintuitively includes setting a (GDscript) 64 bit int/float into a Godot shader language int/float (32 bit). This may lead to unintentional consequences in cases where high precision is required.
+
+
+Uniform limits
+~~~~~~~~~~~~~~
+
+There is a limit to the total size of shader uniforms that you can use
+in a single shader. On most desktop platforms, this limit is ``65536``
+bytes, or 4096 ``vec4`` uniforms. On mobile platforms, the limit is
+typically ``16384`` bytes, or 1024 ``vec4`` uniforms. Vector uniforms
+smaller than a ``vec4``, such as ``vec2`` or ``vec3``, are padded to
+the size of a ``vec4``. Scalar uniforms such as ``int`` or ``float``
+are not padded, and ``bool`` is padded to the size of an ``int``.
+
+Arrays count as the total size of their contents. If you need a uniform
+array that is larger than this limit, consider packing the data into a
+texture instead, since the *contents* of a texture do not count towards
+this limit, only the size of the sampler uniform.
+
 Built-in variables
 ------------------