Unity Shaders and Effects Cookbook (7-2) Surface Shader 中实现 顶点动画

上一节中说了,在 Surface Shader 中,添加顶点函数,我们可以在 顶点函数中获取到 顶点数据,比如顶点颜色、顶点坐标等。

这一节学习获取顶点坐标,并且修改顶点坐标,来实现顶点动画。

简单介绍原理:

在顶点函数中,获取到顶点坐标 vertex,然后,求float offsetY = sin(vertex.x) ,然后将 offsetY 加到 vertex.y 上,这样就把原来的平面 ,变成了 正弦 波浪。

然后再使用之前学过的 内置变量 _Time ,算式变为 float offsetY=sin(vertex.x * _Time) ,这样就形成了动画。

下面开始练习。

新建Scene,导入随书资源,新建Material、新建Shader。

将新建的 Material 赋值给 Plane 。

刚搭建好场景,如下

按照上面所说的原理,来修改Shader。

1、首先声明参数 vertex ,告诉Unity 我们的Shader 中有顶点函数

pragma surface surf Lambert vertex:vert

2、创建 vert 顶点函数

void vert(inout appdata_full v,out Input o)
{
	UNITY_INITIALIZE_OUTPUT(Input,o);
	float offsetY=sin(v.vertex.x);

	v.vertex.xyz=float3(v.vertex.x,v.vertex.y+offsetY,v.vertex.z);
}

在顶点函数中,以 顶点坐标 vertex.x 为参数 ,求sin值 作为 offsetY,然后 vertex.y 与 offsetY 相加。

得到如下图的效果

转自http://blog.csdn.net/huutu  http://www.thisisgame.com.cn

3、使用 _Time ,动起来

void vert(inout appdata_full v,out Input o)
{
	UNITY_INITIALIZE_OUTPUT(Input,o);
	float offsetY=sin(v.vertex.x + _Time.y);

	v.vertex.xyz=float3(v.vertex.x,v.vertex.y+offsetY,v.vertex.z);
}

动起来了,但是却没有明暗效果。

这是因为虽然修改了顶点的位置,但是法线数据没有修改。所以现在的法线数据仍然是之前 平面 的那一套。因为平面的法线数据都是相同的,也就没有了明暗之分。

4、修改法线

在顶点函数中修改法线

void vert(inout appdata_full v,out Input o)
{
	UNITY_INITIALIZE_OUTPUT(Input,o);
	float offsetY=sin(v.vertex.x + _Time.y);

	v.vertex.xyz=float3(v.vertex.x,v.vertex.y+offsetY,v.vertex.z);
	v.normal=normalize(float3(v.normal.x+offsetY,v.normal.y,v.normal.z));
}

5、看起来更圆滑些

上面的效果中,能很明显的看出 折线,看起来不圆滑。这是因为 Plane 的顶点数不多,比如 x 轴上只有 10个 顶点,这 10个顶点被分配到了 2 个正弦波周期,肯定会看起来曲折。

那么我们减少 正弦波周期,让它看起来更圆滑些。

修改顶点函数中的 sin 这一句

float offsetY=sin(v.vertex.x * 0.5 + _Time.y);

完整Shader 代码

Shader "CookBookShaders/Chapt7-2/VertexAnimation"
{
	Properties
	{
		_MainTex ("Base (RGB)", 2D) = "white" {}
	}

	SubShader
	{
		Tags { "RenderType"="Opaque" }
		LOD 200

		CGPROGRAM
		#pragma surface surf Lambert vertex:vert

		sampler2D _MainTex;

		struct Input
		{
			float2 uv_MainTex;
		};

		void vert(inout appdata_full v,out Input o)
		{
			UNITY_INITIALIZE_OUTPUT(Input,o);
			float offsetY=sin(v.vertex.x * 0.5 + _Time.y);

			v.vertex.xyz=float3(v.vertex.x,v.vertex.y+offsetY,v.vertex.z);
			v.normal=normalize(float3(v.normal.x+offsetY,v.normal.y,v.normal.z));
		}

		void surf (Input IN, inout SurfaceOutput o)
		{
			half4 c = tex2D (_MainTex, IN.uv_MainTex);
			o.Albedo = c.rgb;
			o.Alpha = c.a;
		}
		ENDCG
	}
	FallBack "Diffuse"
}

书上还加上了 颜色混合 让效果看起来更炫丽,这里就不做了。

转自http://blog.csdn.net/huutu  http://www.thisisgame.com.cn

了解一下书上提到的一个函数 lerp

Lerp (from : float, to : float, t : float) 

Lerp 插值函数

float f = Lerp(from,to,t)  =  from*(1-t) + to*t

当t = 0返回from,当t = 1 返回to。当t = 0.5 返回from和to的平均值。

示例项目下载

http://pan.baidu.com/s/1qXUbsUK
时间: 2024-10-12 23:52:21

Unity Shaders and Effects Cookbook (7-2) Surface Shader 中实现 顶点动画的相关文章

Unity Shaders and Effects Cookbook (7-1) 在Surface Shader 中 访问 顶点颜色

在OpenGL中,需要顶点着色器和片段着色器的支持才能进行正确的渲染,在顶点着色器中,每一帧 对 场景中物体的每个顶点都要执行一次处理. 如果自己使用OpenGL,需要在C++ 代码读取模型数据,将顶点坐标.顶点颜色.UV坐标传递到顶点着色器中. 所以在顶点着色器中 ,是可以对顶点数据进行修改的. 搭建好测试场景,导入随书的FBX模型. 在Unity3d中,将FBX 或者其它模型  导入编辑器,默认会创建一个 Diffuse 材质.这个材质中是 没有顶点函数的,也就是说不能 对 顶点数据进行处理

Unity Shaders and Effects Cookbook (4-3)遮罩反射

今天看完了4.3小节,Unity3d 中的遮罩反射,这一节内容比较少. 如果大家对Unity Shader 感兴趣的白菜,那么推荐大家购买一本 Unity 着色器和屏幕特效开发秘笈 .这本书写的浅显易懂,很适合入门. 当看完这本书,大概了解 Shader 的用处的时候,再去看更高级的 Shader 教程也可以. 京东图书连接 http://item.jd.com/1338728578.html 转自http://blog.csdn.net/huutu http://www.thisisgame.

Unity Shaders and Effects Cookbook (4-4)在Cubemap 上使用 法线贴图 (法线贴图与反射)

法线贴图 在之前学习过了,我们使用法线贴图在低分辨率的模型上 模拟 高分辨率的效果. Unity中 通过 UnpackNormal 函数 来使用法线贴图. 之前学习法线贴图的记录 Unity Shaders and Effects Cookbook (2-5) 如何使用法线贴图 这一节讲的是 在Cubemap 上使用法线贴图.模拟凹凸效果. 最终效果如图 一起来做吧. 首先搭建好场景,和上一节一样. 导入法线贴图 创建材质 .Shader . 复制上一节的 Shader 就行.然后修改成下面的内

Unity Shaders and Effects Cookbook (4-6)震撼的实时反射 动态立方图系统

昨天逛街的时候看到太平鸟里面摆了个金属的米老鼠,于是职业病犯了,一直在想金属的颜色是什么,这个反射该怎么写,想不出来-- 今天正好看到动态反射立方图系统这一节,看完觉得很别扭,因为书上介绍的是事先踩点生成Cubemap的方式而不是实时的.于是到官方文档找到实时反射的代码,做了一个比较花俏的场景,运行之后吃了一大惊,实时反射是如此的震撼.. 第四章第一节第二节介绍了创建Cubemap,然后学习了如何使用. Unity Shaders and Effects Cookbook (4-1)(4-2)静

Unity Shaders and Effects Cookbook (6-1) 使用 alpha 参数的 半透明着色器

对于游戏项目,透明是很消耗资源的一个操作,在Unity的Profile 中可以很直观的看到透明所消耗的系统资源. 在Unity的表面着色器 Surface Shader 中,我们可以很方便的创建一种全透明的效果.如草的表面.这一节学习 通过在 #pragma 语句中添加 alpha 参数 来使用透明功能. 这一节我使用了下面这张贴图作为球 的表面纹理. 这张 512x 512 的图片分为了 4个色块区域.分别是 Green .Red.White.Blue. Green:就是 G通道为1,R.B

Unity Shaders and Effects Cookbook (2-4) 压缩和混合纹理贴图:使用灰度图存储插值信息

这一节看了几次才慢慢的读懂. 首先是这个灰度图,为什么叫灰度图,是因为 这个图片中的 R.G.B 存放的都是同一份数据,打开Unity 来调一下颜色看看 更直观. 可以看到,当 R.G.B 三个值相同的时候,图片是只有黑白,而丢失了其它的颜色的,所以我们叫灰度图. 什么时候用到灰度图? 本文转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn 比如说高度图,在这个坐标的点,海拔高,就记作 1,海拔低就记作0 .把这一份数据 同时存储到

Unity Shaders and Effects Cookbook (6-4) GUI 和 透明度

在游戏项目中使用透明最多的地方就是 GUI 了.这一节用一个非常简单的 GUI 例子,来熟悉控制透明物体的渲染顺序. 搭建场景,导入随书资源. 创建着色器 GUI,创建两个Material,一个 GUIBG 用于背景图片,一个 GUIGRP 用于 按钮界面. 转自http://blog.csdn.net/huutu http://www.thisisgame.com.cn 把创建的Material 分别赋值给 GUIBG 和 GUIGRP. 场景搭建完毕后 效果如下 因为创建的Shader 默认

Unity Shaders and Effects Cookbook (4-1)(4-2)静态立方体贴图的创建与使用

开始学习第4章 - 着色器的反射 看完了1.2节,来记录一下.反射主要是利用了 Cubemap 立方体贴图. 认识Cubemap 立方体贴图,就如同名字所说,在一个立方体上有6张图,就这样认为吧. 假想一下 ,在一个艳丽的房间里,有一个表面是镜子的圆球,那这个圆球表面就反射了房间里面的所有东西,就是一个大号的凸镜. 这是到网上找得一张图,很直观的表达了我的意思-- 注意标题中说的,静态立方体贴图,为什么叫静态,因为这一次使用的立方体贴图是提前生成好的图片,而不是动态生成的. 这又是什么意思呢?

Unity Shaders and Effects Cookbook (D-1) 设置 ZTest 来实现遮挡半透效果

在游戏里面经常看到这样的效果,英雄走到障碍物后面,但是我们能够透过障碍物看到英雄的身体,好像我们有了透视眼一般. 都是套路. 其实是程序猿在显示英雄模型的时候,画了两次. 一次是被遮挡的部分用半透明的样子画了一遍. 另一次是没有遮挡的部分画了一遍. 下面在Unity中来实现. 首先新建材质 .Shader.场景. 搭建好场景,一个Cube.一个Capsule 好了,现在是最正常不过的情况了,Capsule被Cube 挡住了. 转自http://blog.csdn.net/huutu http:/