原文地址:Docs » Shading » Your first shader » Your first Spatial shader
准备工作
在你的场景中添加以一个MeshInstance
节点。
在检视面板中Mesh
的旁边,点击[empty]
然后选择New PlaneMesh
。然后再点击平面的图标。
这样就在场景中添加了一个PlaneMesh
。
然后,在视图中,点击左上角名为透视(Perspective)的按钮。这时会弹出一个菜单,在菜单的中部,是关于场景显示方式的选项。选择显示线框(Display Wireframe)
这样你可以看到那些组成这个平面的三角形。
设置宽度细分(Subdivide Width)和深度细分(Subdivide Depth)为32.
你可以看到,现在这个网格中有更多的三角形了。这样会提供更多的顶点,是我们可以添加更多的细节。
预置网格(PrimitiveMeshes),如PlaneMesh
,只有一个面,所以它只有一个材质而不是一个材质数组。点击材质(Material)旁边,标记着[empty]
的地方,然后选择New Shadermaterial
。然后点击出现的球形。
然后再点击显示为empty
的Shader
位置,再选择New Shader
。
这时Shader编辑器会弹出来,你终于可以写你的第一个3D Shader啦!
Shader魔法时刻
注意:怎么会有一个error?这是因为你首先应该声明Shader的类型。我们将变量shader_type
设为spatial
,因为额诶这是一个3D Shader。
shader_type spatial;
接下来,我们定义一个顶点函数vertex()
。顶点函数决定你的网格模型的顶点最终定位在屏幕的哪里。我们会使用它偏移每个顶点的高度然后让我们的平面看起来像一个模型。
我们向下面这样定义顶点函数:
void vertex() {
}
如果顶点函数中什么也不写,Godot会使用它的默认顶点函数。我们可以通过一行代码很容易地让它发生变化:
void vertex() {
VERTEX.y += cos(VERTEX.x) * sin(VERTEX.z);
}
添加完以后,你应该得到了一个如下的图片。
好吧,让我们分解一下这段代码。我们为y
值添加增量。将VERTEX
的x
和z
分量作为cos
和sin
的参数,这样就获得了一个在x
和z
轴向上像波一样的效果。
我们的目标是把它变成像山丘一样,尽管cos
和sin
看起来已经有点山丘的意思了,我们可以缩放cos
和sin
的参数,来达到这个目的。
void vertex() {
VERTEX.y += cos(VERTEX.x * 4.0) * sin(VERTEX.z * 4.0);
}
这样看起来更像了,但是还有很死板,让我们把它弄得更有趣一些。
噪声高度图
噪声是模拟地形非常常用的工具。类似于之前的cos
函数,与之不同的是,噪声会给每一个山丘不同的高度。
Godot提供了噪声纹理(NoiseTexture)资源来生成噪声纹理,并且可以在Shader中访问。
要访问Shader中的纹理,请在顶点函数之外且Shader的顶端添加如下代码:
uniform sampler2D noise;
这将允许你传递一个噪声纹理到Shader中。查看一下检视面板你的材质的下方。你可以看到一个叫做“Shader Params”的区域。将这个区域展开,你会看到一个区域叫"noise"。
点击其中显示为empty
的地方,然后选择New NoiseTexture
.然后在你的NoiseTexture
中点击旁边显示为Noise
的地方,再点击New OpenSimplexNoise
。
噪声纹理(NoiseTexture)用OpenSimplexNoise
生成高度图(heightmap)
当你设置完毕,它会像下面这样:
现在,用texture()
函数访问噪声纹理。texture()
的第一个参数是纹理,第二个参数是所取区块的位置。我们使用VERTEX
的x
和z
通道来决定从哪里查找纹理。
float height = texture(noise, VERTEX.xz / 2.0 ); //divide by the size of the PlaneMesh
VERTEX.y += height;
译者注:
原文档有误,应当在后面加个y
float height = texture(noise, VERTEX.xz / 2.0 ).y; //divide by the size of the PlaneMesh
VERTEX.y += height;
使用这段代码你可以看到纹理创建了一些随机的山丘。
现在它们还有是些太尖锐了,我们想让它们平滑一些。我们将用一个uniform
变量来实现,实际上,你已经使用过一次uniform
变量来传递噪声纹理了,现在让我们学习一下它们是如何工作的。