Shader Graph(一)基本使用

一、如何使用Shader Graph

1.1 新建项目

通过创建URP或HDRP模板项目,可以自动配置好Shader Graph。

1.2 已有项目

在「Package Manager」中安装「Shader Graph」及URP或HDRP组件。然后在弹出的渲染管线向导面板中点击「Fix All」即可。如果项目中存在已经创建好的材质,则需要在向导面板最下方将项目的材质升级到对应的渲染管线。

二、创建第一个Shader Graph

下面来编写我们的第一个Shader Graph。首先在目录中右键「Create -> Shader Graph -> HDRP -> Lit Shader Graph」创建一个新的Shader Graph。

然后双击打开,就可以看到Shader Graph的编辑界面

接下来在空白处右键「Create Node」创建一个节点,并选择「Input -> Basic -> Color」。

创建完成后会出现如下所示的节点

我们需要将它的输出连接到片元着色器的输入上

然后点击左上角的「Save Asset」,第一个Shader Graph就编写好了。接下来创建一个材质球,并应用我们刚才创建的Shader Graph。然后把材质挂载到场景中的物体上,效果如下

如果我们想改变物体的颜色,需要在Shader Graph编辑器中手动修改Color节点

这样显然很不方便。为了能直接在Inspector面板中随时更改物体的颜色,我们需要在左侧的面板中新建一个Color类型的变量,然后拖拽到编辑器中,并将其连接到片元着色器的输入端

保存Shader Graph。然后我们就能在材质的Inspector面板上手动调整颜色了

三、顶点着色器

3.1 改变顶点位置

我们知道顶点着色器的作用之一是将本地坐标下的顶点变换到裁剪空间。所以如果在顶点着色器中,对其位置信息进行修改,那么最终渲染出的顶点位置也会相应的发生变化。

比如我们在Shader Graph中创建一个「Position」节点用来接收物体本地坐标下的顶点坐标,然后再添加一个「Add」节点,对顶点坐标的Z轴进行修改,最后再将结果传入Vertex

就可以看到如下效果。渲染的物体在Z轴上产生了偏移。

3.2 动态改变顶点位置

上面这种偏移是固定的,如果我们想让物体随时间动态地进行偏移又该如何实现呢?其实Unity在Shader Graph中提供了「Time」这种节点

它的输出值就是自场景加载开始经过的时间,以及该时间的一系列三角函数值。这里我们要使用到「Sine Time」。因为正弦函数值是相对原点往复变化的,所以通过正弦值改变物体的偏移值正好能够实现往复运动的效果。接下来就是将「Time」的输出值加到顶点的位置信息中。这里仍然是加到Z轴上

效果如下

如果在编译器模式下看不到运动效果,可以打开编译器模式下的「Always Refresh」选项

接下来加大难度。虽然我们在前面实现了顶点的动态移动效果,但只是整体上对所有的顶点进行移动。如果让所有的顶点错开进行移动,就可以更加柔软的效果。

为了实现这一效果,我们就不能对所有的顶点增加同样的偏移值,而是根据顶点的位置确定不同的偏移值。具体的做法是将顶点位置的X值与时间值相加后再取正弦值,然后再增加到Z轴上。

效果如下

四、片元着色器

4.1 改变片元颜色

片元着色器主要的作用是计算片元的颜色值。我们可以通过改变Fragment下的Base Color来改变物体最终渲染的颜色

效果如下

如果想让颜色多一些变化,可以根据法线的方向来决定最终的颜色值

效果如下

可以发现有一部分区域是黑色,这是因为法线各分量的取值范围为[-1,1],而颜色各分量的取值范围为[0,1],小于0的部分按0取值。所以法线的各个分量都小于0时,就会取到黑色。解决方法也很简单,只需要对法线向量n*0.5+0.5,即可将法线向量的取值范围映射到[0,1]。

效果如下

4.2 光照模型

接下来我们尝试使用Shader Graph实现一个之前学过的光照模型——半兰伯特模型的效果。

首先创建一个「Unlit Shader Graph」,这是一种不考虑场景光照的Shader。我们可以通过自己定义的变量模拟光照效果。创建如下变量:DiffuseColor(材质颜色)、DIrectionLightVector(平行光方向)、DirectionLightColor(平行光颜色)、DirectionLightIntensity(平行光强度)。然后根据半兰伯特模型的公式
c d i f f u s e = ( c l i g h t ⋅ m d i f f u s e ) ( 0.5 ( n ⋅ l ) + 0.5 ) c_{diffuse}=(c_{light}·m_{diffuse})(0.5(n·l)+0.5) cdiffuse=(clightmdiffuse)(0.5(nl)+0.5)
形成如下连线

效果如下

五、参考资料

[1]. https://www.sikiedu.com/course/907/

猜你喜欢

转载自blog.csdn.net/LWR_Shadow/article/details/128452291