your_first_2d_shader.rst 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. .. _doc_your_first_canvasitem_shader:
  2. Your first 2D shader
  3. ====================
  4. Introduction
  5. ------------
  6. Shaders are special programs that execute on the GPU and are used for rendering
  7. graphics. All modern rendering is done with shaders. For a more detailed
  8. description of what shaders are please see :ref:`What are shaders
  9. <doc_introduction_to_shaders>`.
  10. This tutorial will focus on the practical aspects of writing shader programs by
  11. walking you through the process of writing a shader with both vertex and
  12. fragment functions. This tutorial targets absolute beginners to shaders.
  13. .. note:: If you have experience writing shaders and are just looking for an
  14. overview of how shaders work in Godot, see the :ref:`Shading Reference
  15. <toc-shading-reference>`.
  16. Setup
  17. -----
  18. :ref:`CanvasItem shaders <doc_canvas_item_shader>` are used to draw all 2D
  19. objects in Godot, while :ref:`Spatial <doc_spatial_shader>` shaders are used
  20. to draw all 3D objects.
  21. In order to use a shader it must be attached inside a :ref:`Material
  22. <class_Material>` which must be attached to an object. Materials are a type of
  23. :ref:`Resource <doc_resources>`. To draw multiple objects with the same
  24. material, the material must be attached to each object.
  25. All objects derived from a :ref:`CanvasItem <class_CanvasItem>` have a material
  26. property. This includes all :ref:`GUI elements <class_Control>`, :ref:`Sprite2Ds
  27. <class_Sprite2D>`, :ref:`TileMapLayers <class_TileMapLayer>`, :ref:`MeshInstance2Ds
  28. <class_MeshInstance2D>` etc. They also have an option to inherit their parent's
  29. material. This can be useful if you have a large number of nodes that you want
  30. to use the same material.
  31. To begin, create a Sprite2D node. :ref:`You can use any CanvasItem <doc_custom_drawing_in_2d>`,
  32. so long as it is drawing to the canvas, so for this tutorial we will use a Sprite2D,
  33. as it is the easiest CanvasItem to start drawing with.
  34. In the Inspector, click beside "Texture" where it says "[empty]" and select
  35. "Load", then select "icon.svg". For new projects, this is the Godot icon. You
  36. should now see the icon in the viewport.
  37. Next, look down in the Inspector, under the CanvasItem section, click beside
  38. "Material" and select "New ShaderMaterial". This creates a new Material
  39. resource. Click on the sphere that appears. Godot currently doesn't know whether
  40. you are writing a CanvasItem Shader or a Spatial Shader and it previews the
  41. output of spatial shaders. So what you are seeing is the output of the default
  42. Spatial Shader.
  43. .. note::
  44. Materials that inherit from the :ref:`class_Material` resource, such as :ref:`class_StandardMaterial3D`
  45. and :ref:`class_ParticleProcessMaterial`, can be converted to a :ref:`class_ShaderMaterial`
  46. and their existing properties will be converted to an accompanying text shader.
  47. To do so, right-click on the material in the FileSystem dock and choose
  48. **Convert to ShaderMaterial**. You can also do so by right-clicking on any
  49. property holding a reference to the material in the inspector.
  50. Click beside "Shader" and select "New Shader". Finally, click on the shader
  51. you just created and the shader editor will open. You are now ready to begin writing
  52. your first shader.
  53. Your first CanvasItem shader
  54. ----------------------------
  55. In Godot, all shaders start with a line specifying what type of shader they are.
  56. It uses the following format:
  57. .. code-block:: glsl
  58. shader_type canvas_item;
  59. Because we are writing a CanvasItem shader, we specify ``canvas_item`` in the
  60. first line. All our code will go beneath this declaration.
  61. This line tells the engine which built-in variables and functionality to supply
  62. you with.
  63. In Godot you can override three functions to control how the shader operates;
  64. ``vertex``, ``fragment``, and ``light``. This tutorial will walk you through
  65. writing a shader with both vertex and fragment functions. Light functions are
  66. significantly more complex than vertex and fragment functions and so will not be
  67. covered here.
  68. Your first fragment function
  69. ----------------------------
  70. The fragment function runs for every pixel in a Sprite2D and determines what color
  71. that pixel should be.
  72. They are restricted to the pixels covered by the Sprite2D, that means you cannot
  73. use one to, for example, create an outline around a Sprite2D.
  74. The most basic fragment function does nothing except assign a single color to
  75. every pixel.
  76. We do so by writing a ``vec4`` to the built-in variable ``COLOR``. ``vec4`` is
  77. shorthand for constructing a vector with 4 numbers. For more information about
  78. vectors see the :ref:`Vector math tutorial <doc_vector_math>`. ``COLOR`` is both
  79. an input variable to the fragment function and the final output from it.
  80. .. code-block:: glsl
  81. void fragment(){
  82. COLOR = vec4(0.4, 0.6, 0.9, 1.0);
  83. }
  84. .. image:: img/blue-box.png
  85. Congratulations! You're done. You have successfully written your first shader in
  86. Godot.
  87. Now let's make things more complex.
  88. There are many inputs to the fragment function that you can use for calculating
  89. ``COLOR``. ``UV`` is one of them. UV coordinates are specified in your Sprite2D
  90. (without you knowing it!) and they tell the shader where to read from textures
  91. for each part of the mesh.
  92. In the fragment function you can only read from ``UV``, but you can use it in
  93. other functions or to assign values to ``COLOR`` directly.
  94. ``UV`` varies between 0-1 from left-right and from top-bottom.
  95. .. image:: img/iconuv.png
  96. .. code-block:: glsl
  97. void fragment() {
  98. COLOR = vec4(UV, 0.5, 1.0);
  99. }
  100. .. image:: img/UV.png
  101. Using ``TEXTURE`` built-in
  102. ~~~~~~~~~~~~~~~~~~~~~~~~~~
  103. The default fragment function reads from the set Sprite2D texture and displays it.
  104. When you want to adjust a color in a Sprite2D you can adjust the color
  105. from the texture manually like in the code below.
  106. .. code-block:: glsl
  107. void fragment(){
  108. // This shader will result in a blue-tinted icon
  109. COLOR.b = 1.0;
  110. }
  111. Certain nodes, like Sprite2Ds, have a dedicated texture variable that can be accessed
  112. in the shader using ``TEXTURE``. If you want to use the Sprite2D texture to combine
  113. with other colors, you can use the ``UV`` with the ``texture`` function to access
  114. this variable. Use them to redraw the Sprite2D with the texture.
  115. .. code-block:: glsl
  116. void fragment(){
  117. COLOR = texture(TEXTURE, UV); // Read from texture again.
  118. COLOR.b = 1.0; //set blue channel to 1.0
  119. }
  120. .. image:: img/blue-tex.png
  121. Uniform input
  122. ~~~~~~~~~~~~~
  123. Uniform input is used to pass data into a shader that will be the same across
  124. the entire shader.
  125. You can use uniforms by defining them at the top of your shader like so:
  126. .. code-block:: glsl
  127. uniform float size;
  128. For more information about usage see the :ref:`Shading Language doc
  129. <doc_shading_language>`.
  130. Add a uniform to change the amount of blue in our Sprite2D.
  131. .. code-block:: glsl
  132. uniform float blue = 1.0; // you can assign a default value to uniforms
  133. void fragment(){
  134. COLOR = texture(TEXTURE, UV); // Read from texture
  135. COLOR.b = blue;
  136. }
  137. Now you can change the amount of blue in the Sprite2D from the editor. Look back
  138. at the Inspector under where you created your shader. You should see a section
  139. called "Shader Param". Unfold that section and you will see the uniform you just
  140. declared. If you change the value in the editor, it will overwrite the default
  141. value you provided in the shader.
  142. Interacting with shaders from code
  143. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  144. You can change uniforms from code using the function ``set_shader_parameter()``
  145. which is called on the node's material resource. With a Sprite2D node, the
  146. following code can be used to set the ``blue`` uniform.
  147. .. tabs::
  148. .. code-tab:: gdscript
  149. var blue_value = 1.0
  150. material.set_shader_parameter("blue", blue_value)
  151. .. code-tab:: csharp
  152. var blueValue = 1.0;
  153. ((ShaderMaterial)Material).SetShaderParameter("blue", blueValue);
  154. Note that the name of the uniform is a string. The string must match exactly
  155. with how it is written in the shader, including spelling and case.
  156. Your first vertex function
  157. --------------------------
  158. Now that we have a fragment function, let's write a vertex function.
  159. Use the vertex function to calculate where on the screen each vertex should end
  160. up.
  161. The most important variable in the vertex function is ``VERTEX``. Initially, it
  162. specifies the vertex coordinates in your model, but you also write to it to
  163. determine where to actually draw those vertices. ``VERTEX`` is a ``vec2`` that
  164. is initially presented in local-space (i.e. not relative to the camera,
  165. viewport, or parent nodes).
  166. You can offset the vertices by directly adding to ``VERTEX``.
  167. .. code-block:: glsl
  168. void vertex() {
  169. VERTEX += vec2(10.0, 0.0);
  170. }
  171. Combined with the ``TIME`` built-in variable, this can be used for basic
  172. animation.
  173. .. code-block:: glsl
  174. void vertex() {
  175. // Animate Sprite2D moving in big circle around its location
  176. VERTEX += vec2(cos(TIME)*100.0, sin(TIME)*100.0);
  177. }
  178. Conclusion
  179. ----------
  180. At their core, shaders do what you have seen so far, they compute ``VERTEX`` and
  181. ``COLOR``. It is up to you to dream up more complex mathematical strategies for
  182. assigning values to those variables.
  183. For inspiration, take a look at some of the more advanced shader tutorials, and
  184. look at other sites like `Shadertoy
  185. <https://www.shadertoy.com/results?query=&sort=popular&from=10&num=4>`_ and `The
  186. Book of Shaders <https://thebookofshaders.com>`_.