Skip to content

Commit

Permalink
Merge pull request #10356 from tetrapod00/cherrypick-shader
Browse files Browse the repository at this point in the history
4.3 Cherrypicks: shaders
  • Loading branch information
tetrapod00 authored Nov 30, 2024
2 parents 522bc83 + 4fd1d23 commit 95a3d64
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 10 deletions.
59 changes: 50 additions & 9 deletions tutorials/shaders/shader_reference/canvas_item_shader.rst
Original file line number Diff line number Diff line change
Expand Up @@ -142,15 +142,56 @@ is usually:
Fragment built-ins
^^^^^^^^^^^^^^^^^^

Certain Nodes (for example, :ref:`Sprite2Ds <class_Sprite2D>`) display a texture
by default. However, when a custom fragment function is attached to these nodes,
the texture lookup needs to be done manually. Godot provides the texture color
in the ``COLOR`` built-in variable multiplied by the node's color. To read the
texture color by itself, you can use:
COLOR and TEXTURE
~~~~~~~~~~~~~~~~~

The built-in variable ``COLOR`` is used for a few things:

- In the ``vertex()`` function, ``COLOR`` contains the color from the vertex
primitive multiplied by the CanvasItem's
:ref:`modulate<class_CanvasItem_property_modulate>` multiplied by the
CanvasItem's :ref:`self_modulate<class_CanvasItem_property_self_modulate>`.
- In the ``fragment()`` function, the input value ``COLOR`` is that same value
multiplied by the color from the default ``TEXTURE`` (if present).
- In the ``fragment()`` function, ``COLOR`` is also the final output.

Certain nodes (for example, :ref:`Sprite2D <class_Sprite2D>`) display a texture
by default, for example :ref:`texture <class_Sprite2D_property_texture>`. When
using a custom ``fragment()`` function, you have a few options on how to sample
this texture.

To read only the contents of the default texture, ignoring the vertex ``COLOR``:

.. code-block:: glsl
void fragment() {
COLOR = texture(TEXTURE, UV);
}
To read the contents of the default texture multiplied by vertex ``COLOR``:

.. code-block:: glsl
COLOR = texture(TEXTURE, UV);
void fragment() {
// Equivalent to an empty fragment() function, since COLOR is also the output variable.
COLOR = COLOR;
}
To read only the vertex ``COLOR`` in ``fragment()``, ignoring the main texture,
you must pass ``COLOR`` as a varying, then read it in ``fragment()``:

.. code-block:: glsl
varying vec4 vertex_color;
void vertex() {
vertex_color = COLOR;
}
void fragment() {
COLOR = vertex_color;
}
NORMAL
~~~~~~

Similarly, if a normal map is used in the :ref:`CanvasTexture <class_CanvasTexture>`, Godot uses
it by default and assigns its value to the built-in ``NORMAL`` variable. If you are using a normal
Expand All @@ -175,7 +216,7 @@ it to the ``NORMALMAP`` property. Godot will handle converting it for use in 2D
+---------------------------------------------+---------------------------------------------------------------+
| in vec2 **TEXTURE_PIXEL_SIZE** | Normalized pixel size of default 2D texture. |
| | For a Sprite2D with a texture of size 64x32px, |
| | **TEXTURE_PIXEL_SIZE** = ``vec2(1/64, 1/32)`` |
| | ``TEXTURE_PIXEL_SIZE`` = ``vec2(1/64, 1/32)`` |
+---------------------------------------------+---------------------------------------------------------------+
| in bool **AT_LIGHT_PASS** | Always ``false``. |
+---------------------------------------------+---------------------------------------------------------------+
Expand Down Expand Up @@ -206,8 +247,8 @@ it to the ``NORMALMAP`` property. Godot will handle converting it for use in 2D
| inout vec3 **LIGHT_VERTEX** | Same as ``VERTEX`` but can be written to alter lighting. |
| | Z component represents height. |
+---------------------------------------------+---------------------------------------------------------------+
| inout vec4 **COLOR** | Color from vertex function multiplied by the **TEXTURE** |
| | color. Also output color value. |
| inout vec4 **COLOR** | ``COLOR`` from the ``vertex()`` function multiplied by the |
| | ``TEXTURE`` color. Also output color value. |
+---------------------------------------------+---------------------------------------------------------------+

Light built-ins
Expand Down
15 changes: 14 additions & 1 deletion tutorials/shaders/shader_reference/shading_language.rst
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ accessible outside of the shader.
shader_type spatial;
const float PI = 3.14159265358979323846;
const float GOLDEN_RATIO = 1.618033988749894;
Constants of the ``float`` type must be initialized using ``.`` notation after the
decimal part or by using the scientific notation. The optional ``f`` post-suffix is
Expand Down Expand Up @@ -793,6 +793,19 @@ GDScript:
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.

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, and how the editor should allow users to modify it.
Expand Down

0 comments on commit 95a3d64

Please sign in to comment.