@@ -63,20 +63,21 @@ Setting up
6363
6464Add a new :ref: `MeshInstance3D <class_MeshInstance3D >` node to your scene.
6565
66- In the inspector tab beside "Mesh" click "<empty>" and select "New PlaneMesh".
67- Then click on the image of a plane that appears.
66+ In the inspector tab, set the MeshInstance3D's **Mesh ** property to a new
67+ :ref: `PlaneMesh <class_planemesh >` resource, by clicking on ``<empty> `` and
68+ choosing **New PlaneMesh **. Then expand the resource by clicking on the image of
69+ a plane that appears.
6870
69- This adds a :ref: ` PlaneMesh < class_planemesh >` to our scene.
71+ This adds a plane to our scene.
7072
71- Then, in the viewport, click in the upper left corner on the button that says
72- "Perspective". A menu will appear. In the middle of the menu are options for how
73- to display the scene. Select 'Display Wireframe'.
73+ Then, in the viewport, click in the upper left corner on the **Perspective ** button.
74+ In the menu that appears, select **Display Wireframe **.
7475
7576This will allow you to see the triangles making up the plane.
7677
7778.. image :: img/plane.webp
7879
79- Now set `` Subdivide Width `` and `` Subdivide Depth `` of the :ref: `PlaneMesh <class_planemesh >` to ``32 ``.
80+ Now set ** Subdivide Width ** and ** Subdivide Depth ** of the :ref: `PlaneMesh <class_planemesh >` to ``32 ``.
8081
8182.. image :: img/plane-sub-set.webp
8283
@@ -87,12 +88,13 @@ and thus allow us to add more detail.
8788.. image :: img/plane-sub.webp
8889
8990:ref: `PrimitiveMeshes <class_primitivemesh >`, like PlaneMesh, only have one
90- surface, so instead of an array of materials there is only one. Click
91- beside " Material" where it says "<empty>" and select "New ShaderMaterial".
92- Then click the sphere that appears.
91+ surface, so instead of an array of materials there is only one. Set the
92+ ** Material ** to a new ShaderMaterial, then expand the material by clicking on
93+ the sphere that appears.
9394
94- Now click beside "Shader" where it says "<empty>" and select "New Shader...". Leave
95- the default settings, give your shader a name and click "Create".
95+ Now set the material's **Shader ** to a new Shader by clicking ``<empty> `` and
96+ select **New Shader... **. Leave the default settings, give your shader a name,
97+ and click **Create **.
9698
9799Click on the shader in the inspector, and the shader editor should now pop up. You
98100are ready to begin writing your first Spatial shader!
@@ -116,7 +118,7 @@ appear in the final scene. We will be using it to offset the height of each vert
116118and make our flat plane appear like a little terrain.
117119
118120With nothing in the ``vertex() `` function, Godot will use its default vertex
119- shader. We can easily start to make changes by adding a single line:
121+ shader. We can start to make changes by adding a single line:
120122
121123.. code-block :: glsl
122124
@@ -130,12 +132,12 @@ Adding this line, you should get an image like the one below.
130132
131133Okay, let's unpack this. The ``y `` value of the ``VERTEX `` is being increased.
132134And we are passing the ``x `` and ``z `` components of the ``VERTEX `` as arguments
133- to `` cos `` and `` sin `` ; that gives us a wave-like appearance across the `` x ``
134- and ``z `` axes.
135+ to :ref: ` cos() < shader_func_cos >` and :ref: ` sin() < shader_func_sin >` ; that gives
136+ us a wave-like appearance across the `` x `` and ``z `` axes.
135137
136- What we want to achieve is the look of little hills; after all. ``cos `` and
137- ``sin `` already look kind of like hills. We do so by scaling the inputs to the
138- ``cos `` and ``sin `` functions.
138+ What we want to achieve is the look of little hills; after all. ``cos() `` and
139+ ``sin() `` already look kind of like hills. We do so by scaling the inputs to the
140+ ``cos() `` and ``sin() `` functions.
139141
140142.. code-block :: glsl
141143
@@ -166,30 +168,19 @@ shader, outside the ``vertex()`` function.
166168 uniform sampler2D noise;
167169
168170 This will allow you to send a noise texture to the shader. Now look in the
169- inspector under your material. You should see a section called " Shader Params" .
170- If you open it up, you'll see a section called "noise ".
171+ inspector under your material. You should see a section called ** Shader Parameters ** .
172+ If you open it up, you'll see a parameter called "Noise ".
171173
172- Click beside it where it says "<empty>" and select "New NoiseTexture2D". Then in
173- your :ref: `NoiseTexture2D <class_noisetexture2D >` click beside where it says "Noise" and select "New
174- FastNoiseLite".
175-
176- .. note :: :ref:`FastNoiseLite <class_fastnoiselite>` is used by the NoiseTexture2D to
177- generate a heightmap.
174+ Set this **Noise ** parameter to a new :ref: `NoiseTexture2D <class_noisetexture2D >`.
175+ Then in your NoiseTexture2D, set its **Noise ** property to a new
176+ :ref: `FastNoiseLite <class_fastnoiselite >`. The FastNoiseLite class is used by
177+ the NoiseTexture2D to generate a heightmap.
178178
179179Once you set it up and should look like this.
180180
181181.. image :: img/noise-set.webp
182182
183- Now, access the noise texture using the ``texture() `` function. ``texture() ``
184- takes a texture as the first argument and a ``vec2 `` for the position on the
185- texture as the second argument. We use the ``x `` and ``z `` channels of
186- ``VERTEX `` to determine where on the texture to look up. Note that the PlaneMesh
187- coordinates are within the [-1,1] range (for a size of 2), while the texture
188- coordinates are within [0,1], so to normalize we divide by the size of the
189- PlaneMesh by 2.0 and add 0.5. ``texture() `` returns a ``vec4 `` of the ``r, g, b,
190- a `` channels at the position. Since the noise texture is grayscale, all of the
191- values are the same, so we can use any one of the channels as the height. In
192- this case we'll use the ``r ``, or ``x `` channel.
183+ Now, access the noise texture using the ``texture() `` function:
193184
194185.. code-block :: glsl
195186
@@ -198,10 +189,27 @@ this case we'll use the ``r``, or ``x`` channel.
198189 VERTEX.y += height;
199190 }
200191
201- Note: ``xyzw `` is the same as ``rgba `` in GLSL, so instead of ``texture().x ``
202- above, we could use ``texture().r ``. See the `OpenGL documentation
203- <https://www.khronos.org/opengl/wiki/Data_Type_(GLSL)#Vectors> `_ for more
204- details.
192+ :ref: `texture() <shader_func_texture >` takes a texture as the first argument and
193+ a ``vec2 `` for the position on the texture as the second argument. We use the
194+ ``x `` and ``z `` channels of ``VERTEX `` to determine where on the texture to look
195+ up.
196+
197+ Since the PlaneMesh coordinates are within the ``[-1.0, 1.0] `` range (for a size
198+ of ``2.0 ``), while the texture coordinates are within ``[0.0, 1.0] ``, to remap
199+ the coordinates we divide by the size of the PlaneMesh by ``2.0 `` and add
200+ ``0.5 `` .
201+
202+ ``texture() `` returns a ``vec4 `` of the ``r, g, b, a `` channels at the position.
203+ Since the noise texture is grayscale, all of the values are the same, so we can
204+ use any one of the channels as the height. In this case we'll use the ``r ``, or
205+ ``x `` channel.
206+
207+ .. note ::
208+
209+ ``xyzw `` is the same as ``rgba `` in GLSL, so instead of ``texture().x ``
210+ above, we could use ``texture().r ``. See the `OpenGL documentation
211+ <https://www.khronos.org/opengl/wiki/Data_Type_(GLSL)#Vectors> `_ for more
212+ details.
205213
206214Using this code you can see the texture creates random looking hills.
207215
@@ -214,7 +222,8 @@ texture, now let's learn how they work.
214222Uniforms
215223--------
216224
217- Uniform variables allow you to pass data from the game into the shader. They are
225+ :ref: `Uniform variables <doc_shading_language_uniforms >` allow you to pass data
226+ from the game into the shader. They are
218227very useful for controlling shader effects. Uniforms can be almost any datatype
219228that can be used in the shader. To use a uniform, you declare it in your
220229:ref: `Shader<class_Shader> ` using the keyword ``uniform ``.
@@ -228,11 +237,11 @@ Let's make a uniform that changes the height of the terrain.
228237
229238 Godot lets you initialize a uniform with a value; here, ``height_scale `` is set
230239to ``0.5 ``. You can set uniforms from GDScript by calling the function
231- `` set_shader_parameter() `` on the material corresponding to the shader. The value
232- passed from GDScript takes precedence over the value used to initialize it in
233- the shader.
240+ :ref: ` set_shader_parameter() < class_ShaderMaterial_method_set_shader_parameter >`
241+ on the material corresponding to the shader. The value passed from GDScript
242+ takes precedence over the value used to initialize it in the shader.
234243
235- ::
244+ .. code-block :: gdscript
236245
237246 # called from the MeshInstance3D
238247 mesh.material.set_shader_parameter("height_scale", 0.5)
@@ -245,8 +254,8 @@ the shader.
245254 ``get_surface_material() `` or ``material_override ``.
246255
247256Remember that the string passed into ``set_shader_parameter() `` must match the name
248- of the uniform variable in the :ref: ` Shader<class_Shader> ` . You can use the
249- uniform variable anywhere inside your :ref: ` Shader<class_Shader> ` . Here, we will
257+ of the uniform variable in the shader . You can use the
258+ uniform variable anywhere inside your shader . Here, we will
250259use it to set the height value instead of arbitrarily multiplying by ``0.5 ``.
251260
252261.. code-block :: glsl
@@ -264,16 +273,17 @@ especially useful for animations.
264273Interacting with light
265274----------------------
266275
267- First, turn wireframe off. To do so, click in the upper-left of the Viewport
268- again, where it says "Perspective" , and select " Display Normal".
269- Additionally in the 3D scene toolbar, turn off preview sunlight.
276+ First, turn wireframe off. To do so, open the ** Perspective ** menu in the
277+ upper-left of the viewport again , and select ** Display Normal **. Additionally in
278+ the 3D scene toolbar, turn off preview sunlight.
270279
271280.. image :: img/normal.webp
272281
273282Note how the mesh color goes flat. This is because the lighting on it is flat.
274283Let's add a light!
275284
276- First, we will add an :ref: `OmniLight3D<class_OmniLight3D> ` to the scene.
285+ First, we will add an :ref: `OmniLight3D<class_OmniLight3D> ` to the scene, and
286+ drag it up so it is above the terrain.
277287
278288.. image :: img/light.webp
279289
@@ -300,7 +310,7 @@ do that by passing in a second noise texture.
300310 uniform sampler2D normalmap;
301311
302312 Set this second uniform texture to another :ref: `NoiseTexture2D <class_noisetexture2D >` with another
303- :ref: `FastNoiseLite <class_fastnoiselite >`. But this time, check **As Normalmap **.
313+ :ref: `FastNoiseLite <class_fastnoiselite >`. But this time, check **As Normal Map **.
304314
305315.. image :: img/normal-set.webp
306316
@@ -312,20 +322,19 @@ wrapping the texture around the mesh automatically.
312322Lastly, in order to ensure that we are reading from the same places on the noise
313323texture and the normalmap texture, we are going to pass the ``VERTEX.xz ``
314324position from the ``vertex() `` function to the ``fragment() `` function. We do
315- that with varyings .
325+ that using a :ref: ` varying < doc_shading_language_varyings >` .
316326
317- Above the ``vertex() `` define a ``vec2 `` called ``tex_position ``. And inside the
318- ``vertex() `` function assign ``VERTEX.xz `` to ``tex_position ``.
327+ Above the ``vertex() `` define a ``varying vec2 `` called ``tex_position ``. And
328+ inside the ``vertex() `` function assign ``VERTEX.xz `` to ``tex_position ``.
319329
320330.. code-block :: glsl
321331
322332 varying vec2 tex_position;
323333
324334 void vertex() {
325- ...
326335 tex_position = VERTEX.xz / 2.0 + 0.5;
327336 float height = texture(noise, tex_position).x;
328- ...
337+ VERTEX.y += height * height_scale;
329338 }
330339
331340 And now we can access ``tex_position `` from the ``fragment() `` function.
@@ -345,6 +354,9 @@ We can even drag the light around and the lighting will update automatically.
345354
346355.. image :: img/normalmap2.webp
347356
357+ Full code
358+ ---------
359+
348360Here is the full code for this tutorial. You can see it is not very long as
349361Godot handles most of the difficult stuff for you.
350362
0 commit comments