|
@@ -118,22 +118,10 @@ what you want.
|
|
|
|
|
|
.. image:: img/11_Godot.png
|
|
|
|
|
|
-In our default scene (3D), create a root node "Spatial". Next, import
|
|
|
-the mesh OBJ file. Click "Import", choose "3D Mesh" and select your
|
|
|
-plane.obj file, set the target path as "/" (or wherever you want in
|
|
|
-your project folder).
|
|
|
+In our default scene (3D), create a root node "Spatial".
|
|
|
|
|
|
-.. image:: img/12_Godot_ImportMesh.png
|
|
|
-
|
|
|
-I like to check "Normals" in the import pop-up so the import will also
|
|
|
-consider faces normals, which can be useful (even if we don't use them
|
|
|
-in this tutorial). Your mesh is now displayed in the FileSystem in
|
|
|
-"res://".
|
|
|
-
|
|
|
-.. image:: img/13_Godot_ImportPopup.png
|
|
|
-
|
|
|
-Create a MeshInstance node. In the Inspector, load the mesh we just
|
|
|
-imported. Select "plane.msh" and hit ok.
|
|
|
+Create a MeshInstance node as a child of the node we just created.
|
|
|
+Then, load the Mesh selecting "Load" and then our "plane.obj" file.
|
|
|
|
|
|
.. image:: img/14_Godot_LoadMesh.png
|
|
|
|
|
@@ -142,108 +130,106 @@ Great! Our plane is now rendered in the 3D view.
|
|
|
.. image:: img/15_Godot_MeshPlaneRendered.png
|
|
|
|
|
|
It is time to add some shader stuff. In the Inspector, in the
|
|
|
-"Material Override" line, add a "New ShaderMaterial". Edit it by
|
|
|
-clicking the ">" button just right to it.
|
|
|
+"Material" line, add a "New ShaderMaterial". Edit it by
|
|
|
+clicking it and then selecting the "Edit" option.
|
|
|
|
|
|
.. image:: img/16_Godot_ShaderMaterial.png
|
|
|
|
|
|
-You have two ways to create a shader: by code (MaterialShader), or
|
|
|
-using a shader graph (MaterialShaderGraph). The second one is a bit
|
|
|
-more visual, but we will not cover it for now. Create a "New
|
|
|
-MaterialShader".
|
|
|
+We need now to create the actual shader. On the Inspector,
|
|
|
+select the "Shader" line and click on "New Shader".
|
|
|
|
|
|
.. image:: img/17_Godot_newMaterialShader.png
|
|
|
|
|
|
-Edit it by clicking the ">" button just right to it. The Shaders
|
|
|
+Edit it by clicking the "Edit" option just like we did before. The Shader
|
|
|
editor opens.
|
|
|
|
|
|
.. image:: img/18_Godot_ShaderEditorOpened.png
|
|
|
|
|
|
-The Vertex tab is for the Vertex shader, and the Fragment tab is for
|
|
|
-the Fragment shader. No need to explain what both of them do, right?
|
|
|
-If so, head to the :ref:`doc_shading_language` page. Else, let's start with the
|
|
|
-Fragment shader. This one is used to texture the plane using an image.
|
|
|
+Let's start writing our shader. If you don't know how to use shaders in Godot
|
|
|
+you can check the :ref:`doc_shading_language` page.
|
|
|
+
|
|
|
+Let's start with the Fragment part.
|
|
|
+This one is used to texture the plane using an image.
|
|
|
For this example, we will texture it with the heightmap image itself,
|
|
|
so we'll actually see mountains as brighter regions and canyons as
|
|
|
darker regions. Use this code:
|
|
|
|
|
|
::
|
|
|
|
|
|
- uniform texture source;
|
|
|
- uniform color col;
|
|
|
- DIFFUSE = col.rgb * tex(source,UV).rgb;
|
|
|
-
|
|
|
-This shader is very simple (it actually comes from the :ref:`doc_shading_language` page).
|
|
|
-What it basically does is take 2 parameters that we have to provide from
|
|
|
-outside the shader ("uniform"):
|
|
|
-
|
|
|
-- the texture file
|
|
|
-- a color
|
|
|
- Then, we multiply every pixel of the image given by
|
|
|
- ``tex(source, UV).rgb`` by the color defined ``col`` and we set it to
|
|
|
- DIFFUSE variable, which is the rendered color. Remember that the
|
|
|
- ``UV`` variable is a shader variable that returns the 2D position of
|
|
|
- the pixel in the texture image, according to the vertex we are
|
|
|
- currently dealing with. That is the use of the UV Layout we made
|
|
|
- before. The color ``col`` is actually not necessary to display the
|
|
|
- texture, but it is interesting to play and see how it does, right?
|
|
|
-
|
|
|
-However, the plane is displayed black! This is because we didn't set
|
|
|
+ shader_type spatial;
|
|
|
+ render_mode unshaded;
|
|
|
+
|
|
|
+ uniform sampler2D source;
|
|
|
+
|
|
|
+ void fragment() {
|
|
|
+ ALBEDO = texture(source, UV).rgb;
|
|
|
+ }
|
|
|
+
|
|
|
+First, we set the shader type as ``spatial`` (for 3D). The
|
|
|
+``render_mode unshaded`` line makes our MeshInstance be unaffected
|
|
|
+by the lighting in our world. It doesn't matter since it is a
|
|
|
+greyscale image. We take a parameter (``uniform``) as a ``sampler2D``,
|
|
|
+which will be the texture of our heightmap.
|
|
|
+
|
|
|
+Then, we set the color of every pixel of the image given by
|
|
|
+``texture(source, UV).rgb`` setting it to the ALBEDO variable.
|
|
|
+Remember that the ``UV`` variable is a shader variable that returns
|
|
|
+the 2D position of the pixel in the texture image, according to the
|
|
|
+vertex we are currently dealing with. That is the use of the UV Layout
|
|
|
+we made before.
|
|
|
+
|
|
|
+However, the plane is displayed white! This is because we didn't set
|
|
|
the texture file and the color to use.
|
|
|
|
|
|
.. image:: img/19_Godot_BlackPlane.png
|
|
|
|
|
|
-In the Inspector, click the "Previous" button to get back to the
|
|
|
+In the Inspector, click the back arrow to get back to the
|
|
|
ShaderMaterial. This is where you want to set the texture and the
|
|
|
-color. In "Source", click "Load" and select the texture file
|
|
|
-"heightmap.png". But the mesh is still black! This is because our
|
|
|
-Fragment shader multiplies each pixel value of the texture by the
|
|
|
-``col`` parameter. However, this color is currently set to black
|
|
|
-(0,0,0), and as you know, 0\*x = 0 ;) . Just change the ``col``
|
|
|
-parameter to another color to see your texture appear:
|
|
|
+color. Click the "Shader Param" line, in "Source", click "Load"
|
|
|
+and select the texture file "heightmap.png". Now you will see
|
|
|
+our heightmap.
|
|
|
|
|
|
.. image:: img/20_Godot_TexturedPlane.png
|
|
|
|
|
|
-Good. Now, the Vertex Shader.
|
|
|
+Good. Now, the Vertex part.
|
|
|
|
|
|
The Vertex Shader is the first shader to be executed by the pipeline. It
|
|
|
deals with vertices.
|
|
|
|
|
|
-Click the "Vertex" tab to switch, and paste this code:
|
|
|
+Insert a new "uniform" variable right after the one that we introduced
|
|
|
+before:
|
|
|
|
|
|
::
|
|
|
|
|
|
- uniform texture source;
|
|
|
uniform float height_range;
|
|
|
- vec2 xz = SRC_VERTEX.xz;
|
|
|
- float h = tex(source, UV).g * height_range;
|
|
|
- VERTEX = vec3(xz.x, h, xz.y);
|
|
|
- VERTEX = MODELVIEW_MATRIX * VERTEX;
|
|
|
-
|
|
|
-This shader uses two "uniform" parameters. The ``source`` parameter is
|
|
|
-already set for the fragment shader. Thus, the same image will be used
|
|
|
-in this shader as the heightmap. The ``height_range`` parameter is a
|
|
|
+
|
|
|
+The ``height_range`` parameter is a
|
|
|
parameter that we will use to increase the height effect.
|
|
|
|
|
|
-At line 3, we save the x and z position of the SRC_VERTEX, because we
|
|
|
-do not want them to change : the plane must remain square. Remember
|
|
|
+Then, insert the following function before the fragment function we wrote before.
|
|
|
+
|
|
|
+::
|
|
|
+
|
|
|
+ void vertex() {
|
|
|
+ vec2 xz = VERTEX.xz;
|
|
|
+ float h = texture(source, UV).g * height_range;
|
|
|
+ VERTEX = vec3(xz.x, h, xz.y);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+First, we save the x and z position of the VERTEX, because we
|
|
|
+do not want them to change: the plane must remain square. Remember
|
|
|
that Y axis corresponds to the "altitude", which is the only one we
|
|
|
want to change with the heightmap.
|
|
|
|
|
|
-At line 4, we compute an ``h`` variable by multiplying the pixel value
|
|
|
+Then, we compute an ``h`` variable by multiplying the pixel value
|
|
|
at the UV position and the ``height_range``. As the heightmap is a
|
|
|
-greyscale image, all r, g and b channels contain the same value. I
|
|
|
-used ``g``, but any of r, g and b have the same effect.
|
|
|
+greyscale image, all r, g and b channels contain the same value. We
|
|
|
+use ``g``, but any of r, g and b have the same effect.
|
|
|
|
|
|
-At line 5, we set the current vertex' position at (xz.x, h, xz.y)
|
|
|
+After that, we set the current vertex' position at (xz.x, h, xz.y)
|
|
|
position. Concerning xz.y remember that its type is "vec2". Thus, its
|
|
|
-components are x and y. The y component simply contains the z position
|
|
|
-we set at line 3.
|
|
|
-
|
|
|
-Finally, at line 6, we multiply the vertex by the model/view matrix in
|
|
|
-order to set its position according to camera position. If you try to
|
|
|
-comment this line, you'll see that the mesh behaves weird as you move
|
|
|
-and rotate the camera.
|
|
|
+components are x and y.
|
|
|
|
|
|
That's all good, but our plane remains flat. This is because the
|
|
|
``height_range`` value is 0. Increase this value to observe the mesh
|