Pārlūkot izejas kodu

Edit shading language page

Fill columns, fix a list, move explanations about floating-point
comparisons outside code blocks so they can be translated.
Nathan Lovato 4 gadi atpakaļ
vecāks
revīzija
5ab8841c25
1 mainītis faili ar 127 papildinājumiem un 76 dzēšanām
  1. 127 76
      tutorials/shaders/shader_reference/shading_language.rst

+ 127 - 76
tutorials/shaders/shader_reference/shading_language.rst

@@ -6,11 +6,13 @@ Shading language
 Introduction
 ------------
 
-Godot uses a shading language similar to GLSL ES 3.0. Most datatypes and functions are supported,
-and the few remaining ones will likely be added over time.
+Godot uses a shading language similar to GLSL ES 3.0. Most datatypes and
+functions are supported, and the few remaining ones will likely be added over
+time.
 
-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.
+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.
 
 Data types
 ----------
@@ -84,8 +86,9 @@ Most GLSL ES 3.0 datatypes are supported:
 Casting
 ~~~~~~~
 
-Just like GLSL ES 3.0, implicit casting between scalars and vectors of the same size but different type is not allowed.
-Casting of types of different size is also not allowed. Conversion must be done explicitly via constructors.
+Just like GLSL ES 3.0, implicit casting between scalars and vectors of the same
+size but different type is not allowed. Casting of types of different size is
+also not allowed. Conversion must be done explicitly via constructors.
 
 Example:
 
@@ -95,7 +98,8 @@ Example:
     float a = 2.0; // valid
     float a = float(2); // valid
 
-Default integer constants are signed, so casting is always needed to convert to unsigned:
+Default integer constants are signed, so casting is always needed to convert to
+unsigned:
 
 .. code-block:: glsl
 
@@ -106,13 +110,13 @@ Default integer constants are signed, so casting is always needed to convert to
 Members
 ~~~~~~~
 
-Individual scalar members of vector types are accessed via the "x", "y", "z" and "w" members.
-Alternatively, using "r", "g", "b" and "a" also works and is equivalent. Use whatever fits
-best for your needs.
+Individual scalar members of vector types are accessed via the "x", "y", "z" and
+"w" members. Alternatively, using "r", "g", "b" and "a" also works and is
+equivalent. Use whatever fits best for your needs.
 
-For matrices, use the ``m[row][column]`` indexing syntax to access each scalar, or ``m[idx]`` to access
-a vector by row index. For example, for accessing the y position of an object in a mat4 you  use
-``m[3][1]``.
+For matrices, use the ``m[row][column]`` indexing syntax to access each scalar,
+or ``m[idx]`` to access a vector by row index. For example, for accessing the y
+position of an object in a mat4 you use ``m[3][1]``.
 
 Constructing
 ~~~~~~~~~~~~
@@ -129,9 +133,9 @@ Construction of vector types must always pass:
     // A single scalar for the whole vector
     vec4 a = vec4(0.0);
 
-Construction of matrix types requires vectors of the same dimension as the matrix. You can
-also build a diagonal matrix using ``matx(float)`` syntax. Accordingly, ``mat4(1.0)`` is
-an identity matrix.
+Construction of matrix types requires vectors of the same dimension as the
+matrix. You can also build a diagonal matrix using ``matx(float)`` syntax.
+Accordingly, ``mat4(1.0)`` is an identity matrix.
 
 .. code-block:: glsl
 
@@ -139,11 +143,13 @@ an identity matrix.
     mat3 m3 = mat3(vec3(1.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0), vec3(0.0, 0.0, 1.0));
     mat4 identity = mat4(1.0);
 
-Matrices can also be built from a matrix of another dimension.
-There are two rules :
-If a larger matrix is constructed from a smaller matrix, the additional rows and columns are
-set to the values they would have in an identity matrix. If a smaller matrix is constructed
-from a larger matrix, the top, left submatrix of the larger matrix is used.
+Matrices can also be built from a matrix of another dimension. There are two
+rules:
+
+1. If a larger matrix is constructed from a smaller matrix, the additional rows
+and columns are set to the values they would have in an identity matrix.
+2. If a smaller matrix is constructed from a larger matrix, the top, left
+submatrix of the larger matrix is used.
 
 .. code-block:: glsl
 
@@ -154,8 +160,9 @@ from a larger matrix, the top, left submatrix of the larger matrix is used.
 Swizzling
 ~~~~~~~~~
 
-It is possible to obtain any combination of components in any order, as long as the result
-is another vector type (or scalar). This is easier shown than explained:
+It is possible to obtain any combination of components in any order, as long as
+the result is another vector type (or scalar). This is easier shown than
+explained:
 
 .. code-block:: glsl
 
@@ -173,7 +180,8 @@ is another vector type (or scalar). This is easier shown than explained:
 Precision
 ~~~~~~~~~
 
-It is possible to add precision modifiers to datatypes; use them for uniforms, variables, arguments and varyings:
+It is possible to add precision modifiers to datatypes; use them for uniforms,
+variables, arguments and varyings:
 
 .. code-block:: glsl
 
@@ -182,9 +190,10 @@ It is possible to add precision modifiers to datatypes; use them for uniforms, v
     highp vec4 a = vec4(0.0, 1.0, 2.0, 3.0); // high precision, uses full float or integer range (default)
 
 
-Using lower precision for some operations can speed up the math involved (at the cost of less precision).
-This is rarely needed in the vertex processor function (where full precision is needed most of the time),
-but is often useful in the fragment processor.
+Using lower precision for some operations can speed up the math involved (at the
+cost of less precision). This is rarely needed in the vertex processor function
+(where full precision is needed most of the time), but is often useful in the
+fragment processor.
 
 Some architectures (mainly mobile) can benefit significantly from this, but
 there are downsides such as the additional overhead of conversion between
@@ -200,8 +209,9 @@ Arrays are containers for multiple variables of a similar type.
 Local arrays
 ~~~~~~~~~~~~
 
-Local arrays are declared in functions. They can use all of the allowed datatypes, except samplers.
-The array declaration follows a C-style syntax: ``[const] + [precision] + typename + identifier + [array size]``.
+Local arrays are declared in functions. They can use all of the allowed
+datatypes, except samplers. The array declaration follows a C-style syntax:
+``[const] + [precision] + typename + identifier + [array size]``.
 
 .. code-block:: glsl
 
@@ -241,7 +251,9 @@ To access an array element, use the indexing syntax:
 
     COLOR.r = arr[0]; // getter
 
-Arrays also have a built-in function ``.length()`` (not to be confused with the built-in ``length()`` function). It doesn't accept any parameters and will return the array's size.
+Arrays also have a built-in function ``.length()`` (not to be confused with the
+built-in ``length()`` function). It doesn't accept any parameters and will
+return the array's size.
 
 .. code-block:: glsl
 
@@ -252,7 +264,12 @@ Arrays also have a built-in function ``.length()`` (not to be confused with the
 
 .. note::
 
-    If you use an index below 0 or greater than array size - the shader will crash and break rendering. To prevent this, use ``length()``, ``if``, or ``clamp()`` functions to ensure the index is between 0 and the array's length. Always carefully test and check your code. If you pass a constant expression or a simple number, the editor will check its bounds to prevent this crash.
+    If you use an index below 0 or greater than array size - the shader will
+    crash and break rendering. To prevent this, use ``length()``, ``if``, or
+    ``clamp()`` functions to ensure the index is between 0 and the array's
+    length. Always carefully test and check your code. If you pass a constant
+    expression or a simple number, the editor will check its bounds to prevent
+    this crash.
 
 Global arrays
 ~~~~~~~~~~~~~
@@ -271,12 +288,17 @@ You can declare arrays at global space like:
 
 .. note::
 
-    Global arrays have to be declared as global constants, otherwise they can be declared the same as local arrays.
+    Global arrays have to be declared as global constants, otherwise they can be
+    declared the same as local arrays.
 
 Constants
 ---------
 
-Use the ``const`` keyword before the variable declaration to make that variable immutable, which means that it cannot be modified. All basic types, except samplers can be declared as constants. Accessing and using a constant value is slightly faster than using a uniform. Constants must be initialized at their declaration.
+Use the ``const`` keyword before the variable declaration to make that variable
+immutable, which means that it cannot be modified. All basic types, except
+samplers can be declared as constants. Accessing and using a constant value is
+slightly faster than using a uniform. Constants must be initialized at their
+declaration.
 
 .. code-block:: glsl
 
@@ -286,7 +308,8 @@ Use the ``const`` keyword before the variable declaration to make that variable
     a = b; // invalid
     b = a; // valid
 
-Constants cannot be modified and additionally cannot have hints, but multiple of them (if they have the same type) can be declared in a single expression e.g
+Constants cannot be modified and additionally cannot have hints, but multiple of
+them (if they have the same type) can be declared in a single expression e.g
 
 .. code-block:: glsl
 
@@ -302,8 +325,11 @@ Similar to variables, arrays can also be declared with ``const``.
 
     COLOR.r = arr[0]; // valid
 
-Constants can be declared both globally (outside of any function) or locally (inside a function).
-Global constants are useful when you want to have access to a value throughout your shader that does not need to be modified. Like uniforms, global constants are shared between all shader stages, but they are not accessible outside of the shader.
+Constants can be declared both globally (outside of any function) or locally
+(inside a function). Global constants are useful when you want to have access to
+a value throughout your shader that does not need to be modified. Like uniforms,
+global constants are shared between all shader stages, but they are not
+accessible outside of the shader.
 
 .. code-block:: glsl
 
@@ -315,7 +341,8 @@ Global constants are useful when you want to have access to a value throughout y
 Structs
 -------
 
-Structs are compound types which can be used for better abstraction of shader code. You can declare them at the global scope like:
+Structs are compound types which can be used for better abstraction of shader
+code. You can declare them at the global scope like:
 
 .. code-block:: glsl
 
@@ -343,7 +370,8 @@ Or use struct constructor for same purpose:
 
     PointLight light = PointLight(vec3(0.0), vec3(1.0, 0.0, 0.0), 0.5);
 
-Structs may contain other struct or array, you can also instance them as global constant:
+Structs may contain other struct or array, you can also instance them as global
+constant:
 
 .. code-block:: glsl
 
@@ -382,7 +410,8 @@ You can also pass them to functions:
 Operators
 ---------
 
-Godot shading language supports the same set of operators as GLSL ES 3.0. Below is the list of them in precedence order:
+Godot shading language supports the same set of operators as GLSL ES 3.0. Below
+is the list of them in precedence order:
 
 +-------------+------------------------+------------------+
 | Precedence  | Class                  | Operator         |
@@ -456,32 +485,41 @@ Godot Shading language supports the most common types of flow control:
 
     } while (true);
 
-Keep in mind that, in modern GPUs, an infinite loop can exist and can freeze your application (including editor).
-Godot can't protect you from this, so be careful not to make this mistake!
+Keep in mind that, in modern GPUs, an infinite loop can exist and can freeze
+your application (including editor). Godot can't protect you from this, so be
+careful not to make this mistake!
+
+Also, when comparing floating-point values against a number, make sure to
+compare them against a *range* instead of an exact number.
+
+A comparison like ``if (value == 0.3)`` may not evaluate to ``true``.
+Floating-point math is often approximate and can defy expectations. It can also
+behave differently depending on the hardware.
 
-Also, when comparing floating-point values against a number, make sure
-to compare them against a *range* instead of an exact number:
+**Don't** do this.
 
 .. code-block:: glsl
 
     float value = 0.1 + 0.2;
 
-    // No guarantee that this evalutes to `true`!
-    // Floating-point math is often approximate and can defy expectations.
-    // It can also behave differently depending on the hardware.
+    // May not evaluate to `true`!
     if (value == 0.3) {
         // ...
     }
 
-    // Instead, always perform a range comparison with an epsilon value.
-    // The larger the floating-point number (and the less precise the floating-point number),
-    // the larger the epsilon value should be.
+Instead, always perform a range comparison with an epsilon value. The larger the
+floating-point number (and the less precise the floating-point number, the
+larger the epsilon value should be.
+
+.. code-block:: glsl
+
     const float EPSILON = 0.0001;
     if (value >= 0.3 - EPSILON && value <= 0.3 + EPSILON) {
         // ...
     }
 
-See `floating-point-gui.de <https://floating-point-gui.de/>`__ for more information.
+See `floating-point-gui.de <https://floating-point-gui.de/>`__ for more
+information.
 
 .. warning::
 
@@ -491,12 +529,14 @@ See `floating-point-gui.de <https://floating-point-gui.de/>`__ for more informat
 Discarding
 ----------
 
-Fragment and light functions can use the **discard** keyword. If used, the fragment is discarded and nothing is written.
+Fragment and light functions can use the **discard** keyword. If used, the
+fragment is discarded and nothing is written.
 
 Functions
 ---------
 
-It is possible to define functions in a Godot shader. They use the following syntax:
+It is possible to define functions in a Godot shader. They use the following
+syntax:
 
 .. code-block:: glsl
 
@@ -511,15 +551,16 @@ It is possible to define functions in a Godot shader. They use the following syn
     }
 
 
-You can only use functions that have been defined above (higher in the editor) the function from which you are calling
-them.
+You can only use functions that have been defined above (higher in the editor)
+the function from which you are calling them.
 
 Function arguments can have special qualifiers:
 
 * **in**: Means the argument is only for reading (default).
 * **out**: Means the argument is only for writing.
 * **inout**: Means the argument is fully passed via reference.
-* **const**: Means the argument is a constant and cannot be changed, may be combined with **in** qualifier.
+* **const**: Means the argument is a constant and cannot be changed, may be
+  combined with **in** qualifier.
 
 Example below:
 
@@ -532,9 +573,9 @@ Example below:
 Varyings
 ~~~~~~~~
 
-To send data from the vertex to the fragment processor function, *varyings* are used. They are set
-for every primitive vertex in the *vertex processor*, and the value is interpolated for every
-pixel in the fragment processor.
+To send data from the vertex to the fragment processor function, *varyings* are
+used. They are set for every primitive vertex in the *vertex processor*, and the
+value is interpolated for every pixel in the fragment processor.
 
 .. code-block:: glsl
 
@@ -568,8 +609,8 @@ Varying can also be an array:
 Interpolation qualifiers
 ~~~~~~~~~~~~~~~~~~~~~~~~
 
-Certain values are interpolated during the shading pipeline. You can modify how these interpolations
-are done by using *interpolation qualifiers*.
+Certain values are interpolated during the shading pipeline. You can modify how
+these interpolations are done by using *interpolation qualifiers*.
 
 .. code-block:: glsl
 
@@ -599,9 +640,10 @@ 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.
+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.
 
 .. note::
     Uniform arrays are not implemented yet.
@@ -612,17 +654,20 @@ Uniforms can't be written from within the shader.
 
     uniform float some_value;
 
-You can set uniforms in the editor in the material. Or you can set them through GDScript:
+You can set uniforms in the editor in the material. Or you can set them through
+GDScript:
 
 ::
 
   material.set_shader_param("some_value", some_value)
 
-.. note:: The first argument to ``set_shader_param`` 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:: The first argument to ``set_shader_param`` 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.
 
-Any GLSL type except for *void* can be a uniform. Additionally, Godot provides optional shader hints
-to make the compiler understand for what the uniform is used.
+Any GLSL type except for *void* can be a uniform. Additionally, Godot provides
+optional shader hints to make the compiler understand for what the uniform is
+used.
 
 .. code-block:: glsl
 
@@ -632,7 +677,9 @@ to make the compiler understand for what the uniform is used.
     uniform float amount : hint_range(0, 1);
     uniform vec4 other_color : hint_color = vec4(1.0);
 
-It's important to understand that textures that are supplied as color require hints for proper sRGB->linear conversion (i.e. ``hint_albedo``), as Godot's 3D engine renders in linear color space.
+It's important to understand that textures that are supplied as color require
+hints for proper sRGB->linear conversion (i.e. ``hint_albedo``), as Godot's 3D
+engine renders in linear color space.
 
 Full list of hints below:
 
@@ -656,8 +703,9 @@ Full list of hints below:
 | **sampler2D**  | hint_aniso                   | As flowmap, default to right.       |
 +----------------+------------------------------+-------------------------------------+
 
-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:
+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:
 
 +-----------------+-----------+
 | GDScript type   | GLSL type |
@@ -679,8 +727,9 @@ to shaders, Godot converts the type automatically. Below is a table of the corre
 | **Transform2D** | **mat4**  |
 +-----------------+-----------+
 
-.. 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.
+.. 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.
 
 Uniforms can also be assigned default values:
 
@@ -695,10 +744,12 @@ Built-in functions
 ------------------
 
 A large number of built-in functions are supported, conforming to GLSL ES 3.0.
-When vec_type (float), vec_int_type, vec_uint_type, vec_bool_type nomenclature is used, it can be scalar or vector.
+When vec_type (float), vec_int_type, vec_uint_type, vec_bool_type nomenclature
+is used, it can be scalar or vector.
 
-.. note:: For a list of the functions that are not available in the GLES2 backend, please see the
-          :ref:`Differences between GLES2 and GLES3 doc <doc_gles2_gles3_differences>`.
+.. note:: For a list of the functions that are not available in the GLES2
+          backend, please see the :ref:`Differences between GLES2 and GLES3 doc
+          <doc_gles2_gles3_differences>`.
 
 +------------------------------------------------------------------------+---------------------------------------------------------------+
 | Function                                                               | Description / Return value                                    |