瀏覽代碼

added your first spatial shader

clayjohn 6 年之前
父節點
當前提交
ef013f577c
共有 63 個文件被更改,包括 750 次插入427 次删除
  1. 二進制
      tutorials/shading/img/vertex_displacement_cos.png
  2. 二進制
      tutorials/shading/img/vertex_displacement_cos_amplitude.png
  3. 二進制
      tutorials/shading/img/vertex_displacement_cos_scaled.png
  4. 二進制
      tutorials/shading/img/vertex_displacement_light1.png
  5. 二進制
      tutorials/shading/img/vertex_displacement_light2.png
  6. 二進制
      tutorials/shading/img/vertex_displacement_new_mesh.png
  7. 二進制
      tutorials/shading/img/vertex_displacement_new_shader.png
  8. 二進制
      tutorials/shading/img/vertex_displacement_new_shader_material.png
  9. 二進制
      tutorials/shading/img/vertex_displacement_noise1.png
  10. 二進制
      tutorials/shading/img/vertex_displacement_noise2.png
  11. 二進制
      tutorials/shading/img/vertex_displacement_noise3.png
  12. 二進制
      tutorials/shading/img/vertex_displacement_normal.png
  13. 二進制
      tutorials/shading/img/vertex_displacement_normal_detailed1.png
  14. 二進制
      tutorials/shading/img/vertex_displacement_normal_detailed2.png
  15. 二進制
      tutorials/shading/img/vertex_displacement_normal_detailed3.png
  16. 二進制
      tutorials/shading/img/vertex_displacement_planemesh.png
  17. 二進制
      tutorials/shading/img/vertex_displacement_shader_editor.png
  18. 二進制
      tutorials/shading/img/vertex_displacement_subdivided_mesh.png
  19. 二進制
      tutorials/shading/img/vertex_displacement_terrain.png
  20. 二進制
      tutorials/shading/img/vertex_displacement_uniform1.png
  21. 二進制
      tutorials/shading/img/vertex_displacement_uniform2.png
  22. 二進制
      tutorials/shading/img/vertex_displacement_viewport_settings.png
  23. 二進制
      tutorials/shading/img/vertex_displacement_wireframe1.png
  24. 二進制
      tutorials/shading/img/vertex_displacement_wireframe2.png
  25. 0 1
      tutorials/shading/index.rst
  26. 0 368
      tutorials/shading/vertex_displacement_with_shaders.rst
  27. 二進制
      tutorials/shading/your_first_shader/img/PBR.png
  28. 二進制
      tutorials/shading/your_first_shader/img/albedo.png
  29. 二進制
      tutorials/shading/your_first_shader/img/cos.png
  30. 二進制
      tutorials/shading/your_first_shader/img/cos4.png
  31. 二進制
      tutorials/shading/your_first_shader/img/dark-water.png
  32. 二進制
      tutorials/shading/your_first_shader/img/fresnel.png
  33. 二進制
      tutorials/shading/your_first_shader/img/iconuv.png
  34. 二進制
      tutorials/shading/your_first_shader/img/light.png
  35. 二進制
      tutorials/shading/your_first_shader/img/noise-flat.png
  36. 二進制
      tutorials/shading/your_first_shader/img/noise-low.png
  37. 二進制
      tutorials/shading/your_first_shader/img/noise-mesh.png
  38. 二進制
      tutorials/shading/your_first_shader/img/noise-normal-light.png
  39. 二進制
      tutorials/shading/your_first_shader/img/noise-normal-sub.png
  40. 二進制
      tutorials/shading/your_first_shader/img/noise-normal.png
  41. 二進制
      tutorials/shading/your_first_shader/img/noise-set.png
  42. 二進制
      tutorials/shading/your_first_shader/img/noise.png
  43. 二進制
      tutorials/shading/your_first_shader/img/normal-set.png
  44. 二進制
      tutorials/shading/your_first_shader/img/normal.png
  45. 二進制
      tutorials/shading/your_first_shader/img/normalmap.png
  46. 二進制
      tutorials/shading/your_first_shader/img/normalmap2.png
  47. 二進制
      tutorials/shading/your_first_shader/img/plane-sub-set.png
  48. 二進制
      tutorials/shading/your_first_shader/img/plane-sub.png
  49. 二進制
      tutorials/shading/your_first_shader/img/plane.png
  50. 二進制
      tutorials/shading/your_first_shader/img/plastic.png
  51. 二進制
      tutorials/shading/your_first_shader/img/rim.png
  52. 二進制
      tutorials/shading/your_first_shader/img/shader-error.png
  53. 二進制
      tutorials/shading/your_first_shader/img/specular-toon.png
  54. 二進制
      tutorials/shading/your_first_shader/img/wave1.png
  55. 二進制
      tutorials/shading/your_first_shader/img/wave2.png
  56. 二進制
      tutorials/shading/your_first_shader/img/wave3.png
  57. 4 5
      tutorials/shading/your_first_shader/index.rst
  58. 66 14
      tutorials/shading/your_first_shader/what_are_shaders.rst
  59. 28 20
      tutorials/shading/your_first_shader/your_first_canvasitem_shader.rst
  60. 0 9
      tutorials/shading/your_first_shader/your_first_particles_shader.rst
  61. 332 1
      tutorials/shading/your_first_shader/your_first_spatial_shader.rst
  62. 0 9
      tutorials/shading/your_first_shader/your_first_visual_shader.rst
  63. 320 0
      tutorials/shading/your_first_shader/your_second_spatial_shader.rst

二進制
tutorials/shading/img/vertex_displacement_cos.png


二進制
tutorials/shading/img/vertex_displacement_cos_amplitude.png


二進制
tutorials/shading/img/vertex_displacement_cos_scaled.png


二進制
tutorials/shading/img/vertex_displacement_light1.png


二進制
tutorials/shading/img/vertex_displacement_light2.png


二進制
tutorials/shading/img/vertex_displacement_new_mesh.png


二進制
tutorials/shading/img/vertex_displacement_new_shader.png


二進制
tutorials/shading/img/vertex_displacement_new_shader_material.png


二進制
tutorials/shading/img/vertex_displacement_noise1.png


二進制
tutorials/shading/img/vertex_displacement_noise2.png


二進制
tutorials/shading/img/vertex_displacement_noise3.png


二進制
tutorials/shading/img/vertex_displacement_normal.png


二進制
tutorials/shading/img/vertex_displacement_normal_detailed1.png


二進制
tutorials/shading/img/vertex_displacement_normal_detailed2.png


二進制
tutorials/shading/img/vertex_displacement_normal_detailed3.png


二進制
tutorials/shading/img/vertex_displacement_planemesh.png


二進制
tutorials/shading/img/vertex_displacement_shader_editor.png


二進制
tutorials/shading/img/vertex_displacement_subdivided_mesh.png


二進制
tutorials/shading/img/vertex_displacement_terrain.png


二進制
tutorials/shading/img/vertex_displacement_uniform1.png


二進制
tutorials/shading/img/vertex_displacement_uniform2.png


二進制
tutorials/shading/img/vertex_displacement_viewport_settings.png


二進制
tutorials/shading/img/vertex_displacement_wireframe1.png


二進制
tutorials/shading/img/vertex_displacement_wireframe2.png


+ 0 - 1
tutorials/shading/index.rst

@@ -11,5 +11,4 @@ Shading
    intro_to_shaders_water_workshop
    screen-reading_shaders
    migrating_to_godot_shader_language
-   vertex_displacement_with_shaders
    advanced_postprocessing

+ 0 - 368
tutorials/shading/vertex_displacement_with_shaders.rst

@@ -1,368 +0,0 @@
-.. _doc_vertex_displacement_with_shaders:
-
-Vertex displacement with shaders
-================================
-
-Introduction
-------------
-
-This tutorial will teach you how to displace the vertices of
-a :ref:`Plane Mesh<class_PlaneMesh>` inside a shader. Vertex displacement can be used
-for a wide variety of effects, but most commonly it is used
-as a quick way to turn a flat plane into a simple terrain. Typically
-this is done using a heightmap, but in order to keep everything self
-contained, in this tutorial, we will use noise in a shader. At the end
-of this tutorial, we will have a deformed plane that looks like a
-miniature terrain complete with dynamic lighting.
-
-By reading this tutorial, you should gain a basic understanding of:
-
-* How to create and subdivide a :ref:`Plane Mesh<class_PlaneMesh>`
-* How to create and assign a material to a :ref:`Mesh<class_MeshInstance>`
-* How to write a :ref:`Shader<class_Shader>` that displaces the vertices of a :ref:`Mesh<class_MeshInstance>`
-* How to pass values (Uniforms) into a :ref:`Shader<class_Shader>` to update the :ref:`Mesh<class_MeshInstance>` in realtime
-* How to approximate normals from a height function
-* How to use a light with a custom material
-
-The plane mesh
---------------
-
-First, add a :ref:`Spatial<class_Spatial>` node to the scene to act as the root. Next, add a :ref:`MeshInstance<class_MeshInstance>`
-as a child.
-
-.. image:: img/vertex_displacement_new_mesh.png
-
-Select the newly created :ref:`MeshInstance<class_MeshInstance>`. Then click on the button that says "null"
-next to the :ref:`Mesh<class_MeshInstance>` in the Inspector. This will bring up a list of :ref:`PrimitiveMeshes<class_PrimitiveMesh>`.
-Select "New PlaneMesh".
-
-.. image:: img/vertex_displacement_planemesh.png
-
-The button will change into a small image of a plane. Click on it to enter into
-the Inspector for the :ref:`Plane Mesh<class_MeshInstance>`.
-
-Then, in the viewport, click in the upper left corner where it says [Perspective].
-A menu will appear. In the middle of the menu are options for how to display the scene.
-Select 'Display Wireframe'.
-
-.. image:: img/vertex_displacement_viewport_settings.png
-
-This will allow you to see the triangles making up the plane.
-
-.. image:: img/vertex_displacement_wireframe1.png
-
-Now set the ``Subdivide Width`` and ``Subdivide Height`` to ``32``.
-
-.. image:: img/vertex_displacement_subdivided_mesh.png
-
-You can see that there are now many more triangles in the :ref:`Mesh<class_MeshInstance>`. This will give
-us more vertices to work with and thus allow us to add more detail.
-
-.. image:: img/vertex_displacement_wireframe2.png
-
-
-Shader magic
-------------
-
-Now that we have a :ref:`Plane Mesh<class_MeshInstance>` to draw, let's set up the material that will deform the :ref:`Mesh<class_MeshInstance>`.
-
-Click beside material in the :ref:`Plane Mesh<class_MeshInstance>` Menu and create a new :ref:`ShaderMaterial<class_ShaderMaterial>`.
-
-.. image:: img/vertex_displacement_new_shader_material.png
-
-Then click on the created :ref:`ShaderMaterial<class_ShaderMaterial>`.
-
-Then click beside 'shader' and create a new :ref:`Shader<class_Shader>`.
-
-.. image:: img/vertex_displacement_new_shader.png
-
-Click into the newly created :ref:`Shader<class_Shader>`. You should now see Godot's Shader editor.
-
-.. image:: img/vertex_displacement_shader_editor.png
-
-Notice how it is throwing an error? This is because the shader editor reloads shaders on
-the fly automatically. The first thing Godot shaders need is a declaration of what type of
-shader they are. Accordingly, we set the variable ``shader_type`` to ``spatial``. One more
-thing we will add is the ``render_mode``, we will set it to ``unshaded``. This means that
-Godot won't run the light shader on this object.
-
-::
-
-  shader_type spatial;
-  render_mode unshaded;
-
-This should remove the errors and your :ref:`Mesh<class_MeshInstance>` should turn white. If you were to comment out
-the ``render_mode``, the plane would appear blue because it would pick up the sky colors.
-
-Next we will define a vertex shader. The vertex shader determines where the vertices of your
-:ref:`Mesh<class_MeshInstance>` appear in the final scene. We will be using it to offset the height of each vertex and
-make our flat plane appear like a little terrain.
-
-We define the vertex shader like so:
-
-::
-
-  void vertex() {
-
-  }
-
-With nothing in the ``vertex`` function, Godot will use its default vertex shader. We can easily
-start to make changes by adding a single line:
-
-::
-
-  void vertex() {
-    VERTEX.y += cos(VERTEX.x) * sin(VERTEX.z);
-  }
-
-Adding this line, you should get an image like the one below.
-
-.. image:: img/vertex_displacement_cos.png
-
-Okay, let's unpack this. The ``y`` value of the ``VERTEX`` is being increased. And we are passing
-the ``x`` and ``z`` components of the ``VERTEX`` as arguments to ``cos`` and ``sin``; that gives us
-a wave-like appearance across the ``x`` and ``z`` axes.
-
-What we want to achieve is the look of little hills; after all. ``cos`` and ``sin`` already look kind of like
-hills. We do so by scaling the inputs to the ``cos`` and ``sin`` functions.
-
-::
-
-  void vertex() {
-    VERTEX.y += cos(VERTEX.x * 4.0) * sin(VERTEX.z * 4.0);
-  }
-
-.. image:: img/vertex_displacement_cos_scaled.png
-
-This looks better, but it is still too spiky. This is because ``cos`` and ``sin`` output values between ``-1`` and ``1``,
-so the range of the output is much too high. We correct this by multiplying the result by ``0.5`` to reduce the size.
-
-::
-
-  void vertex() {
-    VERTEX.y += cos(VERTEX.x * 4.0) * sin(VERTEX.z * 4.0) * 0.5;
-  }
-
-.. image:: img/vertex_displacement_cos_amplitude.png
-
-Looks much more hilly now. But ``cos`` and ``sin`` are boring. Let's move onto something more interesting.
-
-Noise
------
-
-Noise is a very popular tool for procedural generation. Think of it as similar to the cosine function
-where you have repeating hills except, with noise, each hill has a different height. Understanding
-noise is not necessary for this tutorial. There is nothing wrong with simply copying and pasting
-the code below.
-
-The first function we use to generate the noise is the ``hash`` function. It gives the random height
-for each of the hill tops.
-
-::
-
-  float hash(vec2 p) {
-    return fract(sin(dot(p * 17.17, vec2(14.91, 67.31))) * 4791.9511);
-  }
-
-You will find similar functions to this all over the internet. It is lovingly referred to as the
-'one-liner hash function'. It works well for simple noise, but there are many better alternatives
-floating around as well. For this tutorial, it will work fine.
-
-Next we define the ``noise`` function. It smoothly interpolates between the random heights.
-Again, if this code seems daunting, do not worry; just copy, paste and move on with the tutorial.
-
-::
-
-  float noise(vec2 x) {
-    vec2 p = floor(x);
-    vec2 f = fract(x);
-    f = f * f * (3.0 - 2.0 * f);
-    vec2 a = vec2(1.0, 0.0);
-    return mix(mix(hash(p + a.yy), hash(p + a.xy), f.x),
-           mix(hash(p + a.yx), hash(p + a.xx), f.x), f.y);
-  }
-
-Lastly, to add detail, we combine successive layers of noise using something called fractal
-brownian motion or FBM. Scary name aside, FBM noise just adds together layers of noise with
-increasing frequency and decreasing amplitude. To implement it, we run over a for loop where
-we increase the frequency each level, decrease the amplitude, and calculate a new layer of noise.
-
-::
-
-  float fbm(vec2 x) {
-    float height = 0.0;
-    float amplitude = 0.5;
-    float frequency = 3.0;
-    for (int i = 0; i < 6; i++){
-      height += noise(x * frequency) * amplitude;
-      amplitude *= 0.5;
-      frequency *= 2.0;
-    }
-    return height;
-  }
-
-We can now use this noise function in place of ``cos`` and ``sin`` in the previous section.
-
-::
-
-  float height = fbm(VERTEX.xz * 4.0);
-  VERTEX.y += height * 0.5;
-
-.. image:: img/vertex_displacement_noise1.png
-
-With the noise function in place, we already have something that looks kind of cool.
-There is a lot of detail, it kind of looks hilly or mountainous.
-
-Fragment shader
----------------
-
-The difference between a vertex shader and a fragment shader is that the vertex shader
-runs per vertex and sets properties such as ``VERTEX`` (position) and ``NORMAL``, while
-the fragment shader runs per pixel and, most importantly, sets the ``ALBEDO`` color of the :ref:`Mesh<class_MeshInstance>`.
-
-Now let's look at the :ref:`Mesh<class_MeshInstance>` with a regular shader instead of the wireframe. Set the
-viewport back to 'Display Normal'.
-
-.. image:: img/vertex_displacement_noise2.png
-
-The :ref:`Mesh<class_MeshInstance>` appears completely white because the fragment shader is coloring each pixel white;
-but if every pixel is white, we lose detail on the :ref:`Mesh<class_MeshInstance>`. So let's color each pixel based
-on the height calculated in the vertex shader. We do so by setting the ``COLOR`` variable
-in the vertex shader. And by setting the ``ALBEDO`` in the fragment shader to the calculated
-``COLOR`` variable.
-
-::
-
-  void vertex() {
-    ...
-    COLOR.xyz = vec3(height);
-  }
-
-  void fragment(){
-    ALBEDO = COLOR.xyz;
-  }
-
-With this change, we can see the detail of the :ref:`Mesh<class_MeshInstance>`, even without displaying the :ref:`Mesh<class_MeshInstance>`'s wireframe.
-
-.. image:: img/vertex_displacement_noise3.png
-
-Uniforms
---------
-
-Uniform variables allow you to pass data from the game into the shader. They can
-be very useful for controlling shader effects. Uniforms can be almost any
-datatype that can be used in the shader. To use a uniform, you declare it in
-your :ref:`Shader<class_Shader>` using the keyword ``uniform``.
-
-Let's make a uniform that changes the height of the terrain.
-
-::
-
-  uniform float height_scale = 0.5;
-
-
-Godot lets you initialize a uniform with a value; here, ``height_scale`` is set to
-``0.5``. You can set uniforms from GDScript by calling the function ``set_shader_param``
-on the material corresponding to the shader. The value passed from GDScript takes
-precedence over the value used to initialize it in the shader.
-
-::
-
-  material.set_shader_param("height_scale", 0.5)
-
-Remember that the string passed into ``set_shader_param`` must match the name
-of the uniform variable in the :ref:`Shader<class_Shader>`. You can use the uniform variable anywhere
-inside your :ref:`Shader<class_Shader>`. Here, we will use it to set the height value instead
-of arbitrarily multiplying by ``0.5``.
-
-::
-
-  VERTEX.y += height * height_scale;
-
-The terrain should look exactly the same, but now we have control over the height easily.
-Here is the same terrain with ``height_scale`` set to ``1``:
-
-.. image:: img/vertex_displacement_uniform1.png
-
-And here it is with ``height_scale`` set to ``0.2``:
-
-.. image:: img/vertex_displacement_uniform2.png
-
-Using uniforms, we can even change the value every frame to animate the height of the terrain.
-Combined with :ref:`Tweens<class_Tween>`, this can be especially useful for simple animations.
-
-Interacting with light
-----------------------
-
-As a final part of this tutorial, let's try to set up the terrain to interact with light.
-First, we will add an :ref:`OmniLight<class_OmniLight>` to the scene.
-
-
-.. image:: img/vertex_displacement_light1.png
-
-You should notice that nothing changes. That is because we set the ``render_mode`` to ``unshaded``
-at the beginning of this tutorial; let's remove that.
-
-::
-
-  shader_type spatial;
-  //render_mode unshaded;
-
-.. image:: img/vertex_displacement_light2.png
-
-It looks slightly better now; you can see the light affecting the terrain, and it has
-turned blue as a result of the sky. The problem is the light is affecting the terrain
-as if it were a flat plane. This is because the light shader uses the normals of the
-:ref:`Mesh<class_MeshInstance>` to calculate light. The normals are stored in the :ref:`Mesh<class_MeshInstance>`, but we are changing
-the shape of the :ref:`Mesh<class_MeshInstance>` in the shader, so the normals are no longer correct. To fix this,
-we need to recalculate the normals in the shader. Godot makes this easy for us; all we
-have to do is calculate the new normal and set ``NORMAL`` to that value in the vertex shader.
-With ``NORMAL`` set, Godot will do all the difficult lighting calculations for us.
-
-To calculate the normal from noise, we are going to use a technique called 'central differences'.
-This is used a lot, especially in places like Shadertoy, to calculate normals in shaders.
-What we will do is calculate the noise at four points surrounding the vertex in the ``x`` and ``z`` directions and then calculate
-the slope at the vertex from that. After all, a normal is just an indicator of the slope of the
-noise.
-
-We calculate the normal with one line in the vertex shader.
-
-::
-
-  vec2 e = vec2(0.01, 0.0);
-  vec3 normal = normalize(vec3(fbm(VERTEX.xz - e) - fbm(VERTEX.xz + e), 2.0 * e.x, fbm(VERTEX.xz - e.yx) - fbm(VERTEX.xz + e.yx)));
-  NORMAL = normal;
-
-The variable ``e`` just makes it easier to add and subtract the right value from the ``VERTEX``.
-Setting ``e`` to a lower number will increase the level of detail of the normal.
-
-With ``NORMAL`` calculated, the terrain now looks like:
-
-.. image:: img/vertex_displacement_normal.png
-
-This still does not look how we want it to. The issue here is that the noise changes
-faster than the vertices do. So when we calculate the normal at the point of the
-``VERTEX``, it does not align with what we see in the final :ref:`Mesh<class_MeshInstance>`. In order to fix
-this, we add more vertices. The below image is made with a :ref:`Mesh<class_MeshInstance>` with ``subdivision`` set
-to ``100``.
-
-.. image:: img/vertex_displacement_normal_detailed1.png
-
-Now, we can drag the light around and the lighting will update automatically.
-
-.. image:: img/vertex_displacement_normal_detailed2.png
-
-.. image:: img/vertex_displacement_normal_detailed3.png
-
-If you zoom the camera out, you can see that the :ref:`Mesh<class_MeshInstance>` now looks like a small terrain.
-
-.. image:: img/vertex_displacement_terrain.png
-
-That is everything for this tutorial. Hopefully, you now understand the basics of vertex
-shaders in Godot. As a further exercise, try changing the ``height_scale`` from gdscript,
-try using different :ref:`Primitive Meshes<class_PrimitiveMesh>`, and try making your
-own functions to calculate ``height``.
-
-For further information on how to use shaders in Godot,
-you should check out the :ref:`doc_shading_language` page.
-

二進制
tutorials/shading/your_first_shader/img/PBR.png


二進制
tutorials/shading/your_first_shader/img/albedo.png


二進制
tutorials/shading/your_first_shader/img/cos.png


二進制
tutorials/shading/your_first_shader/img/cos4.png


二進制
tutorials/shading/your_first_shader/img/dark-water.png


二進制
tutorials/shading/your_first_shader/img/fresnel.png


二進制
tutorials/shading/your_first_shader/img/iconuv.png


二進制
tutorials/shading/your_first_shader/img/light.png


二進制
tutorials/shading/your_first_shader/img/noise-flat.png


二進制
tutorials/shading/your_first_shader/img/noise-low.png


二進制
tutorials/shading/your_first_shader/img/noise-mesh.png


二進制
tutorials/shading/your_first_shader/img/noise-normal-light.png


二進制
tutorials/shading/your_first_shader/img/noise-normal-sub.png


二進制
tutorials/shading/your_first_shader/img/noise-normal.png


二進制
tutorials/shading/your_first_shader/img/noise-set.png


二進制
tutorials/shading/your_first_shader/img/noise.png


二進制
tutorials/shading/your_first_shader/img/normal-set.png


二進制
tutorials/shading/your_first_shader/img/normal.png


二進制
tutorials/shading/your_first_shader/img/normalmap.png


二進制
tutorials/shading/your_first_shader/img/normalmap2.png


二進制
tutorials/shading/your_first_shader/img/plane-sub-set.png


二進制
tutorials/shading/your_first_shader/img/plane-sub.png


二進制
tutorials/shading/your_first_shader/img/plane.png


二進制
tutorials/shading/your_first_shader/img/plastic.png


二進制
tutorials/shading/your_first_shader/img/rim.png


二進制
tutorials/shading/your_first_shader/img/shader-error.png


二進制
tutorials/shading/your_first_shader/img/specular-toon.png


二進制
tutorials/shading/your_first_shader/img/wave1.png


二進制
tutorials/shading/your_first_shader/img/wave2.png


二進制
tutorials/shading/your_first_shader/img/wave3.png


+ 4 - 5
tutorials/shading/your_first_shader/index.rst

@@ -4,13 +4,13 @@ Your first shader
 This tutorial series will walk you through writing your first shader. It is intended
 for people who have very little prior experience with shaders and want to get started
 with the basics. This tutorial will not cover advanced topics and it is not
-comprehensive. For a comprehensive and detailed overview of shaders in godot see the
+comprehensive. For a comprehensive and detailed overview of shaders in Godot see the
 :ref:`Shading Reference Page <toc-shading-reference>`.
 
-"What are shaders" gives a high-level overview of what shaders are and how they fit
+"What are shaders" gives you a high-level overview of what shaders are and how they fit
 into the rendering pipeline.
 
-The "your first shader" tutorials walks you through the process of writing a shader
+The "your first shader" tutorials walk you through the process of writing a shader
 step-by-step. 
 
 For a more general introduction into shaders and the OpenGL Shading Language, use
@@ -23,5 +23,4 @@ For a more general introduction into shaders and the OpenGL Shading Language, us
    what_are_shaders
    your_first_canvasitem_shader
    your_first_spatial_shader
-   your_first_particles_shader
-   your_first_visual_shader
+   your_second_spatial_shader

+ 66 - 14
tutorials/shading/your_first_shader/what_are_shaders.rst

@@ -1,7 +1,7 @@
 .. _doc_what_are_shaders:
 
-What are shaders
-================
+What are shaders?
+=================
 
 Introduction
 ------------
@@ -18,34 +18,86 @@ shaders a little easier by exposing many useful built-in features and handling s
 lower-level initialization work for you. However, GLSL (the OpenGL Shading Language, which Godot uses)
 is still unintuitive and restricting, especially for users who are used to GDScript.
 
-But what are they
------------------
+But what are they?
+------------------
+
+Shaders are a special kind of program that runs on Graphics Processing Units (GPUs). Most computers
+have some sort of GPU, either one integrated into their CPU or discrete (meaning it is a separate 
+hardware component, for example, the typical graphics card). GPUs are especially useful for 
+rendering because they are optimized for running thousands of instructions in parallel.
+
+The output of the shader is typically the colored pixels of the object drawn to the viewport. But some
+shaders allow for specialized outputs (this is especially true for APIs like Vulkan). Shaders operate
+inside the shader pipeline. The standard process is the vertex -> fragment shader pipeline. The vertex
+shader is used to decided where each vertex (point in a 3D model, or corner of a Sprite) goes and the 
+fragment shader decides what color individual pixels receive. 
+
+Suppose you want to update all the pixels in a texture to a given color, on the CPU you would write:
+
+:: 
+
+  for x in range(width):
+    for y in range(height):
+      set_color(x, y, some_color)
+
+In a shader you are given access only to the inside of the loop so what you write looks like this:
+
+.. code-block:: glsl
+
+  // function called for each pixel
+  void fragment() {
+    COLOR = some_color;
+  }
 
-Shaders are a special kind of program that runs on the GPU. 
+You have no control over how this function is called. So you have to design your shaders
+differently from how you would design programs on the CPU.
 
-Objects are drawn using an associated shader. The output of the shader is the pixel colors drawn
-to the viewport. Shaders do not save their results, nor can they be used to draw outside their
-corresponding mesh. The lack of flexibility allows shaders to be incredibly fast. 
+A consequence of the shader pipeline is that you cannot access the results from a previous 
+run of the shader, you cannot access other pixels from the pixel being drawn, and you cannot 
+write outside of the current pixel being drawn. This enables the GPU to execute the shader 
+for different pixels in parallel, as they do not depend on each other. This lack of 
+flexibility is designed to work with the GPU which allows shaders to be incredibly fast. 
 
 What can they do
-----------------
+^^^^^^^^^^^^^^^^
+
 - position vertices very fast
 - compute color very fast
 - compute lighting very fast
+- lots and lots of math
 
 What can't they do
-------------------
-- cant draw outside mesh
-- cant access other pixels from current pixel (or vertices)
-- cant store previous iterations
+^^^^^^^^^^^^^^^^^^
+
+- draw outside mesh
+- access other pixels from current pixel (or vertices)
+- store previous iterations
 - update on the fly (they can, but they need to be compiled)
  
+Structure of a shader
+---------------------
+
+In Godot, shaders are made up of 3 main functions: the ``vertex()`` function, the ``fragment()``
+function and the ``light()`` function. 
+
+The ``vertex()`` function runs over all the vertices in the mesh and sets their positions as well
+as some other per-vertex variables.
+
+The ``fragment()`` function runs for every pixel that is covered by the mesh. It uses the variables
+from the ``vertex()`` function to run. The variables from the ``vertex()`` function are interpolated 
+between the vertices to provide the values for the ``fragment()`` function.
+
+The ``light()`` function runs for every pixel and for every light. It takes variables from the 
+``fragment()`` function and from previous runs of itself. 
+
+For more information about how shaders operate specifically in Godot see the :ref:`Shaders <doc_shaders>` doc.
+
 Technical overview
 ------------------
 
 GPUs are able to render graphics much faster than CPUs for a few reasons, but most notably,
 because they are able to run calculations massively in parallel. A CPU typically has 4 or 8 cores
-while a GPU typically has hundreds. That means a GPU can do hundreds of tasks at once. GPU architects
+while a GPU typically has thousands. That means a GPU can do hundreds of tasks at once. GPU architects
 have exploited this in a way that allows for doing many calculations very quickly, but only when
 many or all cores are doing the same calculation at once, but with different data.
 

+ 28 - 20
tutorials/shading/your_first_shader/your_first_canvasitem_shader.rst

@@ -11,7 +11,7 @@ graphics. All modern rendering is done with shaders. For a more detailed descrip
 of what shaders are please see :ref:`What are shaders <doc_what_are_shaders>`.
 
 This tutorial will focus on the practical aspects of writing shader programs by walking
-readers through the process of writing a shader with both vertex and fragment functions.
+you through the process of writing a shader with both vertex and fragment functions.
 This tutorial targets absolute beginners to shaders.
 
 .. note:: If you have experience writing shaders and are just looking for 
@@ -24,11 +24,12 @@ Setup
 while :ref:`Spatial <doc_spatial_shader>` shaders are used to draw all 3D objects.
 
 In order to use a shader it must be attached inside a :ref:`Material <class_material>` 
-which must be attached to an object. To draw multiple objects with the same material, 
-the material must be attached to each object.
+which must be attached to an object. Materials are a type of :ref:`Resource <doc_resources>`.
+To draw multiple objects with the same material, the material must be attached to each object.
 
 All objects derived from a :ref:`CanvasItem <class_canvasitem>` have a material property.
-This includes all gui elements, sprites, TileMaps, MeshInstance2Ds etc.
+This includes all :ref:`GUI elements <class_Control>`, :ref:`Sprites <class_sprite>`, :ref:`TileMaps <class_tilemap>`,
+:ref:`MeshInstance2Ds <class_meshinstance2d>` etc.
 They also have an option to inherit their parent's material. This can be useful if you have
 a large number of nodes that you want to use the same material.
 
@@ -39,11 +40,11 @@ In the Inspector, click beside "Texture" where it says "[empty]" and select "Loa
 "Icon.png". For new projects, this is the Godot icon. You should now see the icon in the viewport.
 
 Next, look down in the Inspector, under the CanvasItem section, click beside "Material" and select
-"new ShaderMaterial". This creates a new Material. Click on the sphere that appears. Godot currently
+"New ShaderMaterial". This creates a new Material resource. Click on the sphere that appears. Godot currently
 doesn't know whether you are writing a CanvasItem Shader or a Spatial Shader and it previews the output
 of spatial shaders. So what you are seeing is the output of the default Spatial Shader.
 
-Click beside "Shader" and select "new Shader". Finally, click on the new shader resource and the shader
+Click beside "Shader" and select "New Shader". Finally, click on the new shader resource and the shader
 editor will open. You are now ready to begin writing your first shader.
 
 Your first CanvasItem shader
@@ -54,7 +55,7 @@ the following format:
 
 .. code-block:: glsl
   
-  shader_type canvas_item
+  shader_type canvas_item;
 
 Becuase we are writing a CanvasItem shader, we specify ``canvas_item`` in the first line. All our code will
 go beneath this declaration.
@@ -68,14 +69,17 @@ functions are significantly more complex than vertex and fragment functions and
 Your first fragment function
 ----------------------------
 
-The fragment function runs for every pixel covered by a triangle and determine what color that pixel should be
-based on information passed in from the vertex function.
+The fragment function runs for every pixel in a Sprite and determines what color that pixel should be.
 
-They are restricted to the pixels covered by the triangle, that means you cannot use one to, for example, 
-create an outline around a sprite. 
+They are restricted to the pixels covered by the Sprite, that means you cannot use one to, for example, 
+create an outline around a Sprite. 
 
 The most basic fragment function does nothing except assign a single color to every pixel. 
 
+We do so by writing a ``vec4`` to the built-in variable ``COLOR``. ``vec4`` is shorthand for constructing
+a vector with 4 numbers. For more information about vectors see the :ref:`Vector math tutorial <doc_vector_math>` 
+``COLOR`` is both an input variable to the fragment function and the final output from it. 
+
 .. code-block:: glsl
 
   void fragment(){
@@ -89,12 +93,16 @@ Congratulations! You're done. You have successfully written your first shader in
 Now let's make things more complex.
 
 There are many inputs to the fragment function that you can use for calculating ``COLOR``.
-``UV`` is one of them. Uv coordinates are specified in your mesh and they tell the shader
-where to read from textures for each part of the mesh.
+``UV`` is one of them. UV coordinates are specified in your Sprite (without you knowing it!)
+and they tell the shader where to read from textures for each part of the mesh.
 
 In the fragment function you can only read from ``UV``, but you can use it in other functions
 or to assign values to ``COLOR`` directly.
 
+``UV`` varies between 0-1 from left-right and from top-bottom.
+
+.. image:: img/iconuv.png
+
 .. code-block:: glsl
 
   void fragment() {
@@ -106,7 +114,7 @@ or to assign values to ``COLOR`` directly.
 Using ``TEXTURE`` built-in
 ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-When you want to adjust a color in a sprite you cannot just adjust the color from the texture
+When you want to adjust a color in a Sprite you cannot just adjust the color from the texture
 manually like in the code below.
 
 .. code-block:: glsl
@@ -119,7 +127,7 @@ manually like in the code below.
 The default fragment function reads from a texture and displays it. When you overwrite the default fragment function, 
 you lose that functionality, so you have to implement it yourself. You read from textures using the
 ``texture`` function. Certain nodes, like Sprites, have a dedicated texture variable that can be accessed in the shader
-using ``TEXTURE``. Use it together with ``UV`` and ``texture`` to draw the sprite.
+using ``TEXTURE``. Use it together with ``UV`` and ``texture`` to draw the Sprite.
 
 .. code-block:: glsl
 
@@ -143,7 +151,7 @@ You can use uniforms by defining them at the top of your shader like so:
 
 For more information about usage see the :ref:`Shading Language doc <doc_shading_language>`.
 
-Add a uniform to change the amount of blue in our sprite.
+Add a uniform to change the amount of blue in our Sprite.
 
 .. code-block:: glsl
 
@@ -154,7 +162,7 @@ Add a uniform to change the amount of blue in our sprite.
     COLOR.b = blue;
   }
 
-Now you can change the amount of blue in the sprite from the editor. Look back at the Inspector
+Now you can change the amount of blue in the Sprite from the editor. Look back at the Inspector
 under where you created your shader. You should see a section called "Shader Param". Unfold that 
 section and you will see the uniform you just declared. If you change the value in the editor, it
 will overwrite the default value you provided in the shader.
@@ -162,8 +170,8 @@ will overwrite the default value you provided in the shader.
 Interacting with shaders from code
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-You can change uniforms from code using the function ``set_shader_param`` which is called on the nodes
-material resource. With a sprite node, the following code can be used to set the ``blue`` uniform.
+You can change uniforms from code using the function ``set_shader_param()`` which is called on the node's
+material resource. With a Sprite node, the following code can be used to set the ``blue`` uniform.
 
 ::
 
@@ -198,7 +206,7 @@ Combined with the ``TIME`` built-in variable, this can be used for simple animat
 .. code-block:: glsl
 
   void vertex() {
-    // Animate sprite moving in big circle around its location
+    // Animate Sprite moving in big circle around its location
     VERTEX += vec2(cos(TIME)*100.0, sin(TIME)*100.0);
   }
 

+ 0 - 9
tutorials/shading/your_first_shader/your_first_particles_shader.rst

@@ -1,9 +0,0 @@
-.. _doc_your_first_particles_shader:
-
-Your first Particles shader
-===========================
-
-Introduction
-------------
-
-

+ 332 - 1
tutorials/shading/your_first_shader/your_first_spatial_shader.rst

@@ -3,7 +3,338 @@
 Your first Spatial shader
 ============================
 
-Introduction
+You have decided to start writing your own custom Spatial shader. Maybe you saw a cool trick 
+online that was done with shaders, or you have found that the 
+:ref:`SpatialMaterial <class_SpatialMaterial>` isn't quite meeting your needs. Either way, 
+you have decided to write your own and now you need figure out where to start.
+
+This tutorial will explain how to write a Spatial shader and will cover more topics than the
+:ref:`CanvasItem <doc_your_first_canvasitem_shader>` tutorial.
+
+Spatial shaders have more built-in functionality than CanvasItem shaders. The expectation with
+spatial shaders is that Godot has already provided the functionality for common use cases and all
+the user needs to do in the shader is set the proper parameters. This is especially true for a 
+PBR (physically based rendering) workflow.
+
+This is a two-part tutorial. In this first part we are going to go through how to make a simple terrain
+using vertex displacement from a heightmap in the vertex function. In the :ref:`second part <doc_your_second_spatial_shader>` 
+we are going to take the concepts from this tutorial and walk through how to set up custom materials 
+in a fragment shader by writing an ocean water shader.
+
+.. note:: This tutorial assumes some basic shader knowledge such as types (``vec2``, ``float``,
+          ``sampler2D``), and functions. If you are uncomfortable with these concepts it is 
+          best to get a gentle introduction from `The Book of Shaders 
+          <https://thebookofshaders.com>`_ before completing this tutorial.
+          
+Where to assign my material
+---------------------------
+
+In 3D, objects are drawn using :ref:`Meshes <class_Mesh>`. Meshes are a resource type that store geometry
+(the shape of your object) and materials (the color and how the object reacts to light) in units called
+"surfaces". A Mesh can have multiple surfaces, or just one. Typically, you would
+import a mesh from another program (e.g. Blender). But Godot also has a few :ref:`PrimitiveMeshes <class_primitivemesh>`
+that allow you to add basic geometry to a scene without importing Meshes. 
+
+There are multiple node types that you can use to draw a mesh. The main one is :ref:`MeshInstance <class_meshinstance>`,
+but you can also use :ref:`Particles <class_particles>`, :ref:`MultiMeshes <class_MultiMesh>` (with a
+:ref:`MultiMeshInstance <class_multimeshinstance>`), or others.
+
+Typically, a material is associated with a given surface in a mesh, but some nodes, like MeshInstance, allow
+you to override the material for a specific surface, or for all surfaces. 
+
+If you set a material on the surface or mesh itself, then all MeshInstances that share that mesh will share that material. 
+However, if you want to reuse the same mesh across multiple mesh instances, but have different materials for each 
+instance then you should set the material on the Meshinstance.
+
+For this tutorial we will set our material on the mesh itself rather than taking advantage of the MeshInstance's 
+ability to override materials. 
+
+Setting up
+----------
+
+Add a new :ref:`MeshInstance <class_meshinstance>` node to your scene. 
+
+In the inspector tab beside "Mesh" click "[empty]" and select "New PlaneMesh".
+Then click on the image of a plane that appears.
+
+This adds a :ref:`PlaneMesh <class_planemesh>` to our scene.
+
+Then, in the viewport, click in the upper left corner on the button that says "Perspective".
+A menu will appear. In the middle of the menu are options for how to display the scene.
+Select 'Display Wireframe'.
+
+This will allow you to see the triangles making up the plane.
+
+.. image:: img/plane.png
+
+Now set ``Subdivide Width`` and ``Subdivide Depth`` to ``32``.
+
+.. image:: img/plane-sub-set.png
+
+You can see that there are now many more triangles in the :ref:`Mesh<class_MeshInstance>`. This will give
+us more vertices to work with and thus allow us to add more detail.
+
+.. image:: img/plane-sub.png
+
+:ref:`PrimitiveMeshes <class_primitivemesh>`, like PlaneMesh, only have one surface, so instead of 
+an array of materials there is only one. Click beside "Material" where it says "[empty]" and 
+select "New ShaderMaterial". Then click the sphere that appears. 
+
+Now click beside "Shader" where it says "[empty]" and select "New Shader". 
+
+The shader editor should now pop up and you are ready to begin writing your first Spatial shader!
+
+Shader magic
 ------------
 
+.. image:: img/shader-error.png
+
+Notice how there is already error? This is because the shader editor reloads shaders on
+the fly. The first thing Godot shaders need is a declaration of what type of shader they are.
+We set the variable ``shader_type`` to ``spatial`` becuase this is a spatial shader.
+
+.. code-block:: glsl
+
+  shader_type spatial;
+
+Next we will define the ``vertex()`` function. The ``vertex()`` function determines where 
+the vertices of your :ref:`Mesh<class_MeshInstance>` appear in the final scene. We will be 
+using it to offset the height of each vertex and make our flat plane appear like a little terrain.
+
+We define the vertex shader like so:
+
+.. code-block:: glsl
+
+  void vertex() {
+
+  }
+
+With nothing in the ``vertex()`` function, Godot will use its default vertex shader. We can easily
+start to make changes by adding a single line:
+
+.. code-block:: glsl
+
+  void vertex() {
+    VERTEX.y += cos(VERTEX.x) * sin(VERTEX.z);
+  }
+
+Adding this line, you should get an image like the one below.
+
+.. image:: img/cos.png
+
+Okay, let's unpack this. The ``y`` value of the ``VERTEX`` is being increased. And we are passing
+the ``x`` and ``z`` components of the ``VERTEX`` as arguments to ``cos`` and ``sin``; that gives us
+a wave-like appearance across the ``x`` and ``z`` axes.
+
+What we want to achieve is the look of little hills; after all. ``cos`` and ``sin`` already look kind of like
+hills. We do so by scaling the inputs to the ``cos`` and ``sin`` functions.
+
+.. code-block:: glsl
+
+  void vertex() {
+    VERTEX.y += cos(VERTEX.x * 4.0) * sin(VERTEX.z * 4.0);
+  }
+
+.. image:: img/cos4.png
+
+This looks better, but it is still too spiky and repetitive, let's make it a little more interesting.
+
+Noise heightmap
+---------------
+
+Noise is a very popular tool for faking the look of terrain. Think of it as similar to the cosine function
+where you have repeating hills except, with noise, each hill has a different height.
+
+Godot provides the :ref:`NoiseTexture <class_noisetexture>` resource for generating a noise texture
+that can be accessed from a shader.
+
+To access a texture in a shader add the following code near the top of your shader, outside the
+``vertex()`` function.
+
+.. code-block:: glsl
+
+  uniform sampler2D noise;
+
+This will allow you to send a noise texture to the shader. Now look in the inspecter under your material.
+You should see a section called "Shader Params". If you open it up you will see a section called "noise".
+
+Click beside it where it says "[empty]" and select "New NoiseTexture". Then in your NoiseTexture click beside
+where it says "Noise" and select "New OpenSimplexNoise".
+
+:ref:`OpenSimplexNoise <class_opensimplexnoise>` is used by the NoiseTexture to generate a heightmap.
+
+Once you set it up and should look like this.
+
+.. image:: img/noise-set.png
+
+Now, access the noise texture using the ``texture()`` function. ``texture()`` takes the texture as a first
+argument and the position on the texture as the second. We use the ``x`` and ``z`` channels of ``VERTEX`` to 
+determine where on the texture to look up. 
+
+.. code-block:: glsl
+
+  float height = texture(noise, VERTEX.xz / 2.0 ); //divide by the size of the PlaneMesh
+  VERTEX.y += height;
+
+Using this code you can see the texture creates random looking hills.
+
+.. image:: img/noise.png
+
+Right now it is too spiky, we want to soften the hills a bit. To do that we will use a uniform.
+You already used a uniform above to pass in the noise texture, now let's learn how they work.
+
+Uniforms
+--------
+
+Uniform variables allow you to pass data from the game into the shader. They are
+very useful for controlling shader effects. Uniforms can be almost any
+datatype that can be used in the shader. To use a uniform, you declare it in
+your :ref:`Shader<class_Shader>` using the keyword ``uniform``.
+
+Let's make a uniform that changes the height of the terrain.
+
+.. code-block:: glsl
+
+  uniform float height_scale = 0.5;
+
+
+Godot lets you initialize a uniform with a value; here, ``height_scale`` is set to
+``0.5``. You can set uniforms from GDScript by calling the function ``set_shader_param()``
+on the material corresponding to the shader. The value passed from GDScript takes
+precedence over the value used to initialize it in the shader.
+
+::
+
+  # called from the MeshInstance
+  mesh.material.set_shader_param("height_scale", 0.5)
+
+.. note:: Changing uniforms from Spatial nodes is different than in CanvasItem nodes. Here, 
+          we set the material inside the PlaneMesh resource. In other mesh resources you may
+          need to first access the material by calling ``surface_get_material()``. While in
+          the MeshInstance you would access the material using ``get_surface_material()`` or
+          ``material_override``.
+
+Remember that the string passed into ``set_shader_param()`` must match the name
+of the uniform variable in the :ref:`Shader<class_Shader>`. You can use the uniform variable anywhere
+inside your :ref:`Shader<class_Shader>`. Here, we will use it to set the height value instead
+of arbitrarily multiplying by ``0.5``.
+
+.. code-block:: glsl
+
+  VERTEX.y += height * height_scale;
+
+Now it looks  much better.
+
+.. image:: img/noise-low.png
+
+Using uniforms, we can even change the value every frame to animate the height of the terrain.
+Combined with :ref:`Tweens <class_Tween>`, this can be especially useful for simple animations.
+
+Interacting with light
+----------------------
+
+First, turn wireframe off. To do so, click in the upper-left of the Viewport again, where it says
+"Perspective", and select "Display Normal".
+
+.. image:: img/normal.png
+
+Note how the mesh color goes flat. This is because the lighting on it is flat. Let's add a light!
+
+First, we will add an :ref:`OmniLight<class_OmniLight>` to the scene.
+
+.. image:: img/light.png
+
+You can see the light affecting the terrain, but it looks odd. The problem is the light
+is affecting the terrain as if it were a flat plane. This is because the light shader uses 
+the normals from the :ref:`Mesh <class_mesh>` to calculate light. 
+
+The normals are stored in the Mesh, but we are changing the shape of the Mesh in the 
+shader, so the normals are no longer correct. To fix this, we can recalculate the normals 
+in the shader or use a normal texture that corresponds to our noise. Godot makes both easy for us. 
+
+You can calculate the new normal manually in the vertex function and then just set ``NORMAL``.
+With ``NORMAL`` set, Godot will do all the difficult lighting calculations for us. We will cover 
+this method in the next part of this tutorial, for now we will read normals from a texture.
+
+Instead we will rely on the NoiseTexture again to calculate normals for us. We do that by passing in
+a second noise texture.
+
+.. code-block:: glsl
+
+  uniform sampler2D normalmap;
+
+Set this second uniform texture to another NoiseTexture with another OpenSimplexNoise. But this time, check
+off "As Normalmap".
+
+.. image:: img/normal-set.png
+
+Now, becuase this is a normalmap and not a per-vertex normal. We are going to assign it in the ``fragment()``
+function. The ``fragment()`` function will be explained in more detail in the next part of this tutorial.
+
+.. code-block:: glsl
+
+  void fragment() {
+  }
+
+When we have normals that correspond to a specific vertex we set ``NORMAL``, but if you have a normalmap
+that comes from a texture, set the normal using ``NORMALMAP``. This way Godot will handle the wrapping the
+texture around the mesh automatically. 
+
+Lastly, in order to ensure that we are reading from the same places on the noise texture and the normalmap
+texture, we are going to pass the ``VERTEX.xz`` position from the ``vertex()`` function to the ``fragment()``
+function. We do that with varyings. 
+
+Above the ``vertex()`` define a ``vec2`` called ``vertex_position``. And inside the ``vertex()`` function
+assign ``VERTEX.xz`` to ``vertex_position``.
+
+.. code-block:: glsl
+
+  varying vec2 vertex_position;
+
+  void vertex() {
+    ...
+    vertex_position = VERTEX.xz / 2.0;
+  }
+
+And now we can access ``vertex_position`` from the ``fragment()`` function.
+
+.. code-block:: glsl
+
+  void fragment() {
+    NORMALMAP = texture(normalmap, vertex_position).xyz;
+  }
+
+With the normals in place the light now reacts to the height of the mesh dynamically.
+
+.. image:: img/normalmap.png
+
+We can even drag the light around and the lighting will update automatically.
+
+.. image:: img/normalmap2.png
+
+Here is the full code for this tutorial. You can see it is not very long as Godot handles
+most of the difficult stuff for you. 
+
+.. code-block:: glsl
+
+  shader_type spatial;
+
+  uniform float height_scale = 0.5;
+  uniform sampler2D noise;
+  uniform sampler2D normalmap;
+
+  varying vec2 vertex_position;
+
+  void vertex() {
+    vertex_position = VERTEX.xz / 2.0;
+    float height = texture(noise, vertex_position).x * height_scale;
+  }
+
+  void fragment() {
+    NORMALMAP = texture(normalmap, vertex_position).xyz;
+  }
 
+That is everything for this part. Hopefully, you now understand the basics of vertex
+shaders in Godot. In the next part of this tutorial we will write a fragment function 
+to accompany this vertex function and we will cover a more advanced technique to turn
+this terrain into an ocean of moving waves. 

+ 0 - 9
tutorials/shading/your_first_shader/your_first_visual_shader.rst

@@ -1,9 +0,0 @@
-.. _doc_your_first_visual_shader:
-
-Your first visual shader
-========================
-
-Introduction
-------------
-
-

+ 320 - 0
tutorials/shading/your_first_shader/your_second_spatial_shader.rst

@@ -0,0 +1,320 @@
+.. _doc_your_second_spatial_shader:
+
+Your first Spatial shader: part 2
+=================================
+
+From a high-level, what Godot does is give the user a bunch of parameters that can be optionally set
+(``AO``, ``SSS_Strength``, ``RIM``, etc.). These parameters correspond to different complex effects
+(Ambient Occlusion, SubSurface Scattering, Rim Lighting, etc.). When not written to, the code is thrown
+out before it is compiled and so the shader does not incur the cost of the extra feature. This makes it
+easy for users to have complex PBR-correct shading, without writing complex shaders. Of course, Godot
+also allows you to ignore all these parameters and write a fully customized shader.
+
+For a full list of these parameters see the :ref:`spatial shader <doc_spatial_shader>` reference doc.
+
+A difference between the vertex function and a fragment function is that the vertex function
+runs per vertex and sets properties such as ``VERTEX`` (position) and ``NORMAL``, while
+the fragment shader runs per pixel and, most importantly, sets the ``ALBEDO`` color of the :ref:`Mesh<class_MeshInstance>`.
+
+Your first spatial fragment function
+------------------------------------
+
+As mentioned in the previous part of this tutorial. The standard use of the fragment function
+in Godot is to set up different material properties and let Godot handle the rest. In order
+to provide even more flexibility, Godot also provides things called render modes. Render
+modes are set at the top of the shader, directly below ``shader_type``, and they specify
+what sort of functionality you want the built-in aspects of the shader to have. 
+
+For example, if you do not want to have lights affect an object, set the render mode to 
+``unshaded``:
+
+.. code-block:: glsl
+
+  render_mode unshaded;
+
+You can also stack multiple render modes together. For example, if you want to use toon 
+shading instead of more-realistic PBR shading, set the diffuse mode and specular mode to toon:
+
+.. code-block:: glsl
+
+  render_mode diffuse_toon, specular_toon;
+
+This model of built-in functionality allows you to write complex custom shaders by changing
+only a few parameters.
+
+For a full list of render modes see the :ref:`Spatial shader reference <doc_spatial_shader>`.
+
+In this part of the tutorial, we will walk through how to take the bumpy terrain from the 
+previous part and turn it into an ocean.  
+
+First let's set the color of the water. We do that by setting ``ALBEDO``.
+
+``ALBEDO`` is a ``vec3`` that contains the color of the object.
+
+Let's set it to a nice shade of blue.
+
+.. code-block:: glsl
+
+  void fragment() {
+    ALBEDO = vec3(0.1, 0.3, 0.5);
+  }
+
+.. image:: img/albedo.png
+
+We set it to a very dark shade of blue because most of the blueness of the water will
+come from reflections from the sky.
+
+The PBR model that Godot uses relies on two main parameters: ``METALLIC`` and ``ROUGHNESS``.
+
+``ROUGHNESS`` specifies how smooth/rough the surface of a material is. A low ``ROUGHNESS`` will
+make a material appear like a shiny plastic, while a high roughness makes the material appear 
+more solid in color.
+
+``METALLIC`` specifies how much like a metal the object is. It is better set close to ``0`` or ``1``.
+Think of ``METALLIC`` as changing the balance between the reflection and the ``ALBEDO`` color. A 
+high ``METALLIC`` almost ignores ``ALBEDO`` altogether, and looks like a mirror of the sky. While
+a low ``METALLIC`` has a more equal representation of sky color and ``ALBEDO`` color. 
+
+``ROUGHNESS`` increases from ``0`` to ``1`` from left to right while ``METALLIC`` increase from
+``0`` to ``1`` from top to bottom.
+
+.. image:: img/PBR.png
+
+.. note:: ``METALLIC`` should be close to ``0`` or ``1`` for proper PBR shading. Only set it between
+          them for blending between materials.
+
+Water is not a metal, so we will set it's ``METALLIC`` property to ``0.0``. But, water is also highly
+reflective, so we will set it's ``ROUGHNESS`` property to by quite low as well.
+
+.. code-block:: glsl
+
+  void fragment() {
+    METALLIC = 0.0;
+    ROUGHNESS = 0.01;
+    ALBEDO = vec3(0.1, 0.3, 0.5);
+  }
+
+.. image:: img/plastic.png
+
+Now we have a smooth plastic looking surface. It is time to think about some particular properties of 
+water that we want to emulate. There are two main ones that will take this from a weird plastic surface 
+to nice stylized water. The first is specular reflections. Specular reflections are those bright spots
+you see from where the sun reflects directly into your eye. The second is fresnel reflectance.
+Fresnel reflectance is the property of objects to become more reflective at shallow angles. It is the 
+reason why you can see into water below you, but farther away it reflects the sky.
+
+In order to increase the specular reflections, we will do two things. First, we will change the render 
+mode for specular to toon because the toon render mode has larger specular highlights. 
+
+.. code-block:: glsl
+
+  render_mode specular_toon;
+
+.. image:: img/specular-toon.png
+
+Second we will
+add rim lighting. Rim lighting increases the effect of light at glancing angles. Usually it is used
+to emulate the way light passes through fabric on the edges of an object, but we will use it here to 
+help achieve a nice watery effect.
+
+.. code-block:: glsl
+
+  void fragment() {
+    RIM = 0.2;  
+    METALLIC = 0.0;
+    ROUGHNESS = 0.01;
+    ALBEDO = vec3(0.1, 0.3, 0.5);
+  }
+
+.. image:: img/rim.png
+
+In order to add fresnal reflectance we will compute a fresnel term in our fragment shader.
+We are not going to use a real fresnel term, instead we will approximate it using the dot
+product of the ``NORMAL`` and ``VIEW`` vectors. The ``NORMAL`` vector points away from a 
+surface of the, while the ``VIEW`` vector is the direction between your eye and that point
+on the surface. The dot product between them is a handy way to tell when you are looking
+at the surface head-on your at a glancing angle.
+
+.. code-block:: glsl
+
+  float fresnel = sqrt(1.0 - dot(NORMAL, VIEW));
+
+And mix it into both ``ROUGHNESS`` and ``ALBEDO``. This is the benefit of ShaderMaterials over 
+SpatialMaterials. With SpatialMaterials we could set these properties with a texture, or to a flat
+number. But with shaders we can set them based on any mathematical function that we can dream up.
+
+
+.. code-block:: glsl
+
+  void fragment() {
+    float fresnel = sqrt(1.0 - dot(NORMAL, VIEW));
+    RIM = 0.2;  
+    METALLIC = 0.0;
+    ROUGHNESS = 0.01 * (1.0 - fresnel);
+    ALBEDO = vec3(0.1, 0.3, 0.5) + (0.1 * fresnel);
+  }
+
+.. image:: img/fresnel.png
+
+And now, with only 5 lines of code, you can have complex looking water. Now that we have
+lighting, this water is looking too bright. Let's darken it. This is done easily by 
+decreasing the values of the ``vec3`` we pass into ``ALBEDO``. Let's set them to 
+``vec3(0.01, 0.03, 0.05)``.
+
+.. image:: img/dark-water.png
+
+Animating with ``TIME``
+-----------------------
+
+Going back to the vertex function, we can animated the waves using the built-in variable ``TIME``.
+
+``TIME`` is a built-in variable that is accessible from the vertex and fragment functions. 
+
+
+In the last tutorial we calculated height by reading from a heightmap. For this tutorial, 
+we will do the same. Put the heightmap code in a function called ``height()``.
+
+.. code-block:: glsl
+
+  float height(vec2 position) {
+    return texture(noise, position / 10.0).x; //scaling factor is based on mesh size (This PlanMesh is 10x10)
+  }
+
+In order to use ``TIME`` in the ``height()`` function we need to pass it in. 
+
+.. code-block:: glsl
+
+  float height(vec2 position, float time) {
+  }
+
+And make sure to correctly pass it in inside the vertex function.
+
+.. code-block:: glsl
+
+  void vertex() {
+    vec2 pos = VERTEX.xz;
+    float k = height(pos, TIME);
+    VERTEX.y = k;
+  }
+
+Instead of using a normalmap to calculate normals. We are going to compute them manually in the 
+``vertex()`` function. To do so use the following line of code.
+
+.. code-block:: glsl
+
+  NORMAL = normalize(vec3(k - height(pos + vec2(0.1, 0.0), TIME), 0.1, k - height(pos + vec2(0.0, 0.1), TIME)));
+
+We need to compute ``NORMAL`` manually because in the next section we will be using math to create
+complex-looking waves.
+
+Now, we are going to make the ``height()`` function a little more complicated by offsetting ``position``
+by the cosine of ``TIME``.
+
+.. code-block:: glsl
+
+  float height(vec2 position, float time) {
+    vec2 offset = 0.01 * cos(position + time);
+    return texture(noise, (position / 10.0) - offset).x;
+  }
+
+This results in waves that move slowly, but not in a very natural way. The next section will dig deeper
+into using shaders to create more complex effects, in this case realistic waves, by adding a few
+more mathematical functions.
+
+Advanced effects: waves
+-----------------------
+
+What makes shaders so powerful is that you can achieve complex effects by using math. To illustrate
+this, we are going to take our waves to the next level by modifying the ``height()`` function and
+by introducing a new function called ``wave()``.
+
+``wave()`` has one parameter, ``position``, which is the same as it is in ``height()``. 
+
+We are going to call ``wave()`` multiple times in ``height()`` in order to fake the way waves look.
+
+.. code-block:: glsl
+
+  float wave(vec2 position){
+    position += texture(noise, position / 10.0).x * 2.0 - 1.0;
+    vec2 wv = 1.0 - abs(sin(position));
+    return pow(1.0 - pow(wv.x * wv.y, 0.65), 4.0);
+  }
+
+At first this looks complicated. So let's go through it line-by-line.
+
+.. code-block:: glsl
+
+    position += texture(noise, position / 10.0).x * 2.0 - 1.0;
+
+Offset the position by the ``noise`` texture. This will make the waves curve so they are not straight lines
+completely aligned with the grid.
+
+.. code-block:: glsl
+
+    vec2 wv = 1.0 - abs(sin(position));
+
+Define a wave-like function using ``sin()`` and ``position``. Normally ``sin()`` waves are very round.
+We use ``abs()`` to absolute to give them a sharp ridge and constrain them to the 0-1 range. And then we
+subtract it from ``1.0`` to put the peak on top. 
+
+.. code-block:: glsl
+
+    return pow(1.0 - pow(wv.x * wv.y, 0.65), 4.0);
+
+Multiply the x-directional wave by the y-directional wave and raise it to a power to sharpen the peaks. 
+Then subtract that from ``1.0`` so that the ridges become peaks and raise that to a power to sharpen the 
+ridges. 
+
+We can now replace the contents of our ``height()`` function with ``wave()``. 
+
+.. code-block:: glsl
+
+  float height(vec2 position, float time) {
+    float h = wave(position);
+  }
+
+Using this you get:
+
+.. image:: img/wave1.png
+
+The shape of the sin wave is too obvious. So let's spread the waves out a bit. We do this by scaling ``position``.
+
+.. code-block:: glsl
+
+  float height(vec2 position, float time) {
+    float h = wave(position*0.4);
+  }
+  
+Now it looks much better.
+
+.. image:: img/wave2.png
+
+We can do even better if we layer multiple waves on top of each other at varying
+frequencies and amplitudes. What this means is that we are going to scale position for each one to make
+the waves thinner or wider (frequency). And we are going to multiply the output of the wave to make them shorter
+or taller (amplitude).
+
+Here is an example for how you could layer the four waves to achieve nicer looking waves.
+
+.. code-block:: glsl
+
+  float height(vec2 position, float time) {
+    float d = wave((position + time) * 0.4, 8.0) * 0.3;
+    d += wave((position - time) * 0.3, 8.0) * 0.3;
+    d += wave((position + time) * 0.5, 4.0) * 0.2;
+    d += wave((position - time) * 0.6, 4.0) * 0.2;
+    return d;
+  }
+
+Note that we add time to two and subtract it from the other two. This makes the waves move in different directions
+creating a complex effect. Also note that the amplitudes (the number the result is multiplied by) all 
+add up to ``1.0``. This keeps the wave in the 0-1 range.
+
+With this code you should end up with more complex looking waves and all you had to do was add a little bit
+of math! 
+
+.. image:: img/wave3.png
+
+For more information about Spatial shaders read the :ref:`Shading Language <doc_shading_language>` 
+doc and the :ref:`Spatial Shaders <doc_spatial_shader>` doc. Also look at more advanced tutorials 
+in the :ref:`Shading section <toc-learn-features-shading>` and the :ref:`3D <toc-learn-features-3d>` sections.