godot_shader_language_style_guide.rst 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. .. _doc_godot_shader_language_style_guide:
  2. Godot shader language style guide
  3. =================================
  4. This style guide lists conventions to write elegant shaders. The goal is to
  5. encourage writing clean, readable code and promote consistency across projects,
  6. discussions, and tutorials. Hopefully, this will also support the development of
  7. auto-formatting tools.
  8. Since the Godot shader language is close to C-style languages and GLSL, this
  9. guide is inspired by Godot's own GLSL formatting. You can view an example of a
  10. GLSL file in Godot's source code
  11. `here <https://github.com/godotengine/godot/blob/master/drivers/gles2/shaders/copy.glsl>`__.
  12. Style guides aren't meant as hard rulebooks. At times, you may not be able to
  13. apply some of the guidelines below. When that happens, use your best judgment,
  14. and ask fellow developers for insights.
  15. In general, keeping your code consistent in your projects and within your team is
  16. more important than following this guide to a tee.
  17. .. note:: Godot's built-in shader editor uses a lot of these conventions
  18. by default. Let it help you.
  19. Here is a complete shader example based on these guidelines:
  20. .. code-block:: glsl
  21. shader_type canvas_item;
  22. // Screen-space shader to adjust a 2D scene's brightness, contrast
  23. // and saturation. Taken from
  24. // https://github.com/godotengine/godot-demo-projects/blob/master/2d/screen_space_shaders/shaders/BCS.shader
  25. uniform float brightness = 0.8;
  26. uniform float contrast = 1.5;
  27. uniform float saturation = 1.8;
  28. void fragment() {
  29. vec3 c = textureLod(SCREEN_TEXTURE, SCREEN_UV, 0.0).rgb;
  30. c.rgb = mix(vec3(0.0), c.rgb, brightness);
  31. c.rgb = mix(vec3(0.5), c.rgb, contrast);
  32. c.rgb = mix(vec3(dot(vec3(1.0), c.rgb) * 0.33333), c.rgb, saturation);
  33. COLOR.rgb = c;
  34. }
  35. Formatting
  36. ----------
  37. Encoding and special characters
  38. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  39. * Use line feed (**LF**) characters to break lines, not CRLF or CR. *(editor default)*
  40. * Use one line feed character at the end of each file. *(editor default)*
  41. * Use **UTF-8** encoding without a `byte order mark <https://en.wikipedia.org/wiki/Byte_order_mark>`_. *(editor default)*
  42. * Use **Tabs** instead of spaces for indentation. *(editor default)*
  43. Indentation
  44. ~~~~~~~~~~~
  45. Each indent level should be one tab greater than the block containing it.
  46. **Good**:
  47. .. code-block:: glsl
  48. void fragment() {
  49. COLOR = vec3(1.0, 1.0, 1.0);
  50. }
  51. **Bad**:
  52. .. code-block:: glsl
  53. void fragment() {
  54. COLOR = vec3(1.0, 1.0, 1.0);
  55. }
  56. Use 2 indent levels to distinguish continuation lines from
  57. regular code blocks.
  58. **Good**:
  59. .. code-block:: glsl
  60. vec2 st = vec2(
  61. atan(NORMAL.x, NORMAL.z),
  62. acos(NORMAL.y));
  63. **Bad**:
  64. .. code-block:: glsl
  65. vec2 st = vec2(
  66. atan(NORMAL.x, NORMAL.z),
  67. acos(NORMAL.y));
  68. Line breaks and blank lines
  69. ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  70. For a general indentation rule, follow
  71. `the "1TBS Style" <https://en.wikipedia.org/wiki/Indentation_style#Variant:_1TBS_(OTBS)>`_
  72. which recommends placing the brace associated with a control statement on the
  73. same line. Always use braces for statements, even if they only span one line.
  74. This makes them easier to refactor and avoids mistakes when adding more lines to
  75. an ``if`` statement or similar.
  76. **Good**:
  77. .. code-block:: glsl
  78. void fragment() {
  79. if (true) {
  80. // ...
  81. }
  82. }
  83. **Bad**:
  84. .. code-block:: glsl
  85. void fragment()
  86. {
  87. if (true)
  88. // ...
  89. }
  90. Blank lines
  91. ~~~~~~~~~~~
  92. Surround function definitions with one (and only one) blank line:
  93. .. code-block:: glsl
  94. void do_something() {
  95. // ...
  96. }
  97. void fragment() {
  98. // ...
  99. }
  100. Use one (and only one) blank line inside functions to separate logical sections.
  101. Line length
  102. ~~~~~~~~~~~
  103. Keep individual lines of code under 100 characters.
  104. If you can, try to keep lines under 80 characters. This helps to read the code
  105. on small displays and with two shaders opened side-by-side in an external text
  106. editor. For example, when looking at a differential revision.
  107. One statement per line
  108. ~~~~~~~~~~~~~~~~~~~~~~
  109. Never combine multiple statements on a single line.
  110. **Good**:
  111. .. code-block:: glsl
  112. void fragment() {
  113. ALBEDO = vec3(1.0);
  114. EMISSION = vec3(1.0);
  115. }
  116. **Bad**:
  117. .. code-block:: glsl
  118. void fragment() {
  119. ALBEDO = vec3(1.0); EMISSION = vec3(1.0);
  120. }
  121. The only exception to that rule is the ternary operator:
  122. .. code-block:: glsl
  123. void fragment() {
  124. bool should_be_white = true;
  125. ALBEDO = should_be_white ? vec3(1.0) : vec3(0.0);
  126. }
  127. Comment spacing
  128. ~~~~~~~~~~~~~~~
  129. Regular comments should start with a space, but not code that you comment out.
  130. This helps differentiate text comments from disabled code.
  131. **Good**:
  132. .. code-block:: glsl
  133. // This is a comment.
  134. //return;
  135. **Bad**:
  136. .. code-block:: glsl
  137. //This is a comment.
  138. // return;
  139. Don't use multiline comment syntax if your comment can fit on a single line:
  140. .. code-block:: glsl
  141. /* This is another comment. */
  142. .. note::
  143. In the shader editor, to make the selected code a comment (or uncomment it),
  144. press :kbd:`Ctrl + K`. This feature adds or removes ``//`` at the start of
  145. the selected lines.
  146. Whitespace
  147. ~~~~~~~~~~
  148. Always use one space around operators and after commas. Also, avoid extraneous spaces
  149. in function calls.
  150. **Good**:
  151. .. code-block:: glsl
  152. COLOR.r = 5.0;
  153. COLOR.r = COLOR.g + 0.1;
  154. COLOR.b = some_function(1.0, 2.0);
  155. **Bad**:
  156. .. code-block:: glsl
  157. COLOR.r=5.0;
  158. COLOR.r = COLOR.g+0.1;
  159. COLOR.b = some_function (1.0,2.0);
  160. Don't use spaces to align expressions vertically:
  161. .. code-block:: glsl
  162. ALBEDO.r = 1.0;
  163. EMISSION.r = 1.0;
  164. Floating-point numbers
  165. ~~~~~~~~~~~~~~~~~~~~~~
  166. Always specify at least one digit for both the integer and fractional part. This
  167. makes it easier to distinguish floating-point numbers from integers, as well as
  168. distinguishing numbers greater than 1 from those lower than 1.
  169. **Good**:
  170. .. code-block:: glsl
  171. void fragment() {
  172. ALBEDO.rgb = vec3(5.0, 0.1, 0.2);
  173. }
  174. **Bad**:
  175. .. code-block:: glsl
  176. void fragment() {
  177. ALBEDO.rgb = vec3(5., .1, .2);
  178. }
  179. Accessing vector members
  180. ------------------------
  181. Use ``r``, ``g``, ``b``, and ``a`` when accessing a vector's members if it
  182. contains a color. If the vector contains anything else than a color, use ``x``,
  183. ``y``, ``z``, and ``w``. This allows those reading your code to better
  184. understand what the underlying data represents.
  185. **Good**:
  186. .. code-block:: glsl
  187. COLOR.rgb = vec3(5.0, 0.1, 0.2);
  188. **Bad**:
  189. .. code-block:: glsl
  190. COLOR.xyz = vec3(5.0, 0.1, 0.2);
  191. Naming conventions
  192. ------------------
  193. These naming conventions follow the Godot Engine style. Breaking these will make
  194. your code clash with the built-in naming conventions, leading to inconsistent
  195. code.
  196. Functions and variables
  197. ~~~~~~~~~~~~~~~~~~~~~~~
  198. Use snake\_case to name functions and variables:
  199. .. code-block:: glsl
  200. void some_function() {
  201. float some_variable = 0.5;
  202. }
  203. Constants
  204. ~~~~~~~~~
  205. Write constants with CONSTANT\_CASE, that is to say in all caps with an
  206. underscore (\_) to separate words:
  207. .. code-block:: glsl
  208. const float GOLDEN_RATIO = 1.618;
  209. Code order
  210. ----------
  211. We suggest to organize shader code this way:
  212. .. code-block:: glsl
  213. 01. shader type declaration
  214. 02. render mode declaration
  215. 03. // docstring
  216. 04. uniforms
  217. 05. constants
  218. 06. varyings
  219. 07. other functions
  220. 08. vertex() function
  221. 09. fragment() function
  222. 10. light() function
  223. We optimized the order to make it easy to read the code from top to bottom, to
  224. help developers reading the code for the first time understand how it works, and
  225. to avoid errors linked to the order of variable declarations.
  226. This code order follows two rules of thumb:
  227. 1. Metadata and properties first, followed by methods.
  228. 2. "Public" comes before "private". In a shader language's context, "public"
  229. refers to what's easily adjustable by the user (uniforms).
  230. Local variables
  231. ~~~~~~~~~~~~~~~
  232. Declare local variables as close as possible to their first use. This makes it
  233. easier to follow the code, without having to scroll too much to find where the
  234. variable was declared.