forked from cotes2020/jekyll-theme-chirpy
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
105 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
--- | ||
category: shader | ||
tags: [U3D, Shader,Cookbook,中文版] | ||
|
||
--- | ||
|
||
## 对表面着色器中的顶点使用动画 | ||
|
||
我们现在知道了如何访问每个顶点数据的一些基础知识,这次让我们更进一步的了解一些其他类型的数据和顶点的位置。 | ||
|
||
使用顶点函数,我们可以访问网格中每个顶点位置。具体来说就是可以在着色器处理渲染的过程中,这些函数可以让我们单独对每一个顶点进行修改。 | ||
|
||
这个知识点当中,我们会创建一个着色器,并且用三角函数的正弦函数(**sine wave**)来修改网格当中的每一个顶点。该技术可以用来创建旗子飘动或者海浪等物体动画。 | ||
|
||
*** | ||
|
||
- **始前准备** | ||
我们把资源都放一块儿,这样方便我们为顶点着色器( **Vertex Shader** )编写代码: | ||
- 1.创建一个新的场景,并且创建一个平面网格( **plane mesh** ),把它放在场景正中央,位置归零。 | ||
- 2.然后创建一个新的材质和着色器。 | ||
- 3.最后,把着色器挂到材质上,在把材质挂到平面网格上。 | ||
|
||
最终,你的场景看起来应该跟下图一样: | ||
![diagram](https://linkliu.github.io/game-tech-post/assets/img/shader_book/diagram60.png){: .shadow width = "90%" } | ||
|
||
*** | ||
- **操作步骤** | ||
场景创建好后,鼠标双击打开刚刚我们创建的着色器: | ||
- 1.让我们给着色器的属性块下面的预设值: | ||
``` C# | ||
Properties | ||
{ | ||
_MainTex ("Base (RGB)", 2D) = "white" {} | ||
_tintAmount ("Tint Amount", Range(0,1)) = 0.5 | ||
_ColorA ("Color A", Color) = (1,1,1,1) | ||
_ColorB ("Color B", Color) = (1,1,1,1) | ||
_Speed ("Wave Speed", Range(0.1, 80)) = 5 | ||
_Frequency ("Wave Frequency", Range(0, 5)) = 2 | ||
_Amplitude ("Wave Amplitude", Range(-1, 1)) = 1 | ||
} | ||
``` | ||
- 2.接下来我们通过下面的声明告诉Unity,我们需要使用顶点函数了,添加声明的位置在: **#pragma statement**: | ||
``` C# | ||
CGPROGRAM | ||
#pragma surface surf Lambert vertex:vert | ||
``` | ||
- 3.为了访问属性块中的值,我们还要在 **CGPROGRAM** 块中声明与之对应的变量: | ||
``` C# | ||
sampler2D _MainTex; | ||
float4 _ColorA; | ||
float4 _ColorB; | ||
float _tintAmount; | ||
float _Speed; | ||
float _Frequency; | ||
float _Amplitude; | ||
float _OffsetVal; | ||
``` | ||
- 4.我们也将使用顶点位置的变化作为 **vert** 颜色。因为这样我们可以顺便修改物体的颜色了: | ||
``` c# | ||
struct Input | ||
{ | ||
float2 uv_MainTex; | ||
float3 vertColor; | ||
} | ||
``` | ||
- 5.此时,我们要修改顶点的表现了,我们要使用到下面的正选函数和顶点函数,在我们的 **Input Struct** 后面添加如下代码: | ||
``` c# | ||
void vert(inout appdata_full v, out Input o) | ||
{ | ||
float time = _Time * _Speed; | ||
float waveValueA = sin(time + v.vertex.x * _Frequency) * _Amplitude; | ||
v.vertex.xyz = float3(v.vertex.x, v.vertex.y + waveValueA, v.vertex.z); | ||
v.normal = normalize(float3(v.normal.x + waveValueA, v.normal.y,v.normal.z)); | ||
o.vertColor = float3(waveValueA,waveValueA,waveValueA); | ||
} | ||
``` | ||
- 6.最后,我们要使用一个 **lerp()** 函数对两个颜色进行一个插值,这样我们就可以对新网格的波峰和波谷应用不同的颜色,为了获得这种表现,添加下面的代码让顶点函数起作用: | ||
``` c# | ||
void surf (Input IN, inout SurfaceOutput o) | ||
{ | ||
half4 c = tex2D (_MainTex, IN.uv_MainTex); | ||
float3 tintColor = lerp(_ColorA, _ColorB, IN.vertColor).rgb; | ||
o.Albedo = c.rgb * (tintColor * _tintAmount); | ||
o.Alpha = c.a; | ||
} | ||
``` | ||
|
||
|
||
当你完成了着色器的编写后,回到Unity并且等待着色器编译完成。当编译完成后,你就会看到如下图所示的情形: | ||
|
||
![diagram](https://linkliu.github.io/game-tech-post/assets/img/shader_book/diagram61.png){: .shadow width = "90%" } | ||
*** | ||
|
||
- **原理介绍** | ||
这个特定的着色器使用了我们上个知识点的一些概念,但不同的是,我们这里改变的是网格上那些顶点的位置。有时候你不想用骨骼结构( **skeleton structure** )或者是节点结构( **hierarchy of transforms** )来扣动画, | ||
然后在简单的拼接它们,比如旗帜,在旗子上做动画然后跟旗杆组合拼接成旗帜。这个时候你使用这个着色器就特别有用了。 | ||
|
||
我们简单的使用了正弦函数 **sin()** 来创建正弦波,这个函数式Cg语言内建的。当计算好正弦值后,我们把这个值赋值给了每个顶点位置的 **y**,然后就产生了波动的效果。 | ||
|
||
当然我们还顺便稍微修改了网格上面的法线,让它针对正弦波有更真实的着色。 | ||
|
||
从这里你也可以知道,通过利用表面着色器内建的顶点参数,来获得一些比较复杂的顶点效果,还是比较容易的。 | ||
|
||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.