Unity仿海岛奇兵海洋效果
第一篇文章想分享一下使用Unity来制作海岛奇兵海洋效果, 最终的实现效果如下制作这种效果,需要如下几步1, 首先要准备一个Mesh, 我使用的是10 x 10 的Mesh, 一共100个格子,这样的Mesh顶点相对比较多,最后shader计算的时候效果比较好。
2, 然后来看看shader的具体实现首先看一下需要传入的属性,需要传入3张贴图,一张_SeaNormal 法线图,一张亮色的海洋图_LightSea , 一张暗色的海洋图_DarkSea ,u_time 是时间变化参数,u_uvFactor 是uv缩放参数
1
2
3
4
5
6
7
Properties
{
_SeaNormal ("SeaNormal", 2D) = "white" {}
_LightSea ("LightSea", 2D) = "white" {}
_DarkSea ("DarkSea", 2D) = "white" {}
u_time ("u_time", float) = 83.36153
u_uvFactor ("u_uvFactor", float) = 0.7735959
}
接下来看下vertshader的具体实现
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
struct appdata
{
float4 vertex : POSITION0;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertex : POSITION0;
float2 uv : TEXCOORD0;
float2 normaluv : TEXCOORD1;
float v_result : TEXCOORD2;
float v_reflectionPower : TEXCOORD3;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
float ystretch = 0.2;
o.v_reflectionPower = clamp((1.0 - length(float2(v.vertex.x * 0.7 + (v.uv.x - 0.5) * 1.5, v.vertex.z * ystretch) - float2(0.0, ystretch))) * 3.0, 1.5, 4.0);
float x = v.uv.x;
float y = v.uv.y * u_uvFactor;
float mov1 = y / 0.04 * 5.0 + u_time;
float mov2 = x / 0.02 * 5.0;
float c1 = abs((sin(mov1 + u_time) + mov2) * 0.5 - mov1 - mov2 + u_time);
float c4 = 0.5 * sin(sqrt(x * x + y * y) * 150.0 - u_time) + 0.5;
c1 = 0.5 * sin(c1) + 0.5;
o.v_result = c4;
o.normaluv = v.uv * 25.0;
o.normaluv.x -= 0.01 * u_time * 0.5;
o.normaluv.y += 0.02 * u_time * 0.5;
o.normaluv = float2(o.normaluv.x + c1 * 0.01, (o.normaluv.y + c1 * 0.01) * u_uvFactor) * 1.5;
return o;
}
vertexshader传入到pixelshader的参与有5个a, vertex参数不传入pixelshader, 直接由引擎计算出屏幕空间的位置b, uv就是模型的uv, 直接传入pixelshaderc, normaluv是计算出来的法线uv, 来采样法线图, 法线uv是动态的,来模拟海洋的海浪变化d, v_reflectionPower是计算的高光强度e, v_result参数也是用来影响法线uv的变化的
然后看下pixelshader 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
float4 custommix(float4 x, float4 y, float a)
{
return (x * (1 - a) + y * a);
}
fixed4 frag (v2f i) : SV_Target
{
float4 normalMapValue = tex2D(_SeaNormal, i.normaluv);
float4 lightseacol = tex2D(_LightSea, i.uv);
float4 darkseacol = tex2D(_DarkSea, i.uv);
float4 fragcol = custommix(lightseacol, darkseacol, (normalMapValue.x * i.v_result) + (normalMapValue.y * (1.0 - i.v_result)));
float4 fragspeccol = min(0.4, exp2(log2(((normalMapValue.z * i.v_result) + (normalMapValue.w * (1.0 - i.v_result))) * i.v_reflectionPower) * 5.0));
fragcol += fragspeccol;
return fragcol;
}
通过vertexshader传入的参数,采样出亮色海洋贴图,暗色海洋贴图颜色以及动态的法线图通过函数计算得到diffuse颜色fragcol, 然后根据vertexshader传入的v_reflectionPower高光参数,计算出高光值fragspeccol, 然后计算出最终的颜色fragcol并输出,Adreno Profiler是用来分析手机游戏的渲染比较好用的工具,原则上可以用来分析任意发布在手机上游戏的渲染实现截图效果如下
、
知乎@谢刘斌
元素帖子强,满满正能量! 啥也别说了 掌声响起来
66666 楼主真是太强了,谢谢发资源,给力 路过看看 感谢分享 路过看看 感谢分享 感谢分享 有点好玩,有点强 很好很强很喜欢!!!!! 我们先定一个能达到的小目标,先赚它一亿元素币 我们先定一个能达到的小目标,先赚它一亿元素币 赞一个~666 路过围观~感谢分享 6666 不错的资源,谢谢分享
元素那么大,我想来看看! mark mark! {:1_237:} ni
ce
页:
[1]
2