小小橘子 发表于 2024-10-12 14:01:41

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是用来分析手机游戏的渲染比较好用的工具,原则上可以用来分析任意发布在手机上游戏的渲染实现截图效果如下

知乎@谢刘斌

趁年轻拼一拼 发表于 2018-10-18 14:24:20


元素帖子强,满满正能量!

夜空之魔 发表于 2018-10-18 14:47:43

啥也别说了 掌声响起来

852501557 发表于 2018-10-19 08:06:17

66666

今今屋迷 发表于 2018-10-19 08:19:55

楼主真是太强了,谢谢发资源,给力

有点淡定 发表于 2018-10-19 08:29:02

路过看看 感谢分享

有点淡定 发表于 2018-10-19 08:29:04

路过看看 感谢分享

LWZ63358621 发表于 2018-10-19 08:47:12

感谢分享

ゞYx。 发表于 2018-10-19 08:53:02

有点好玩,有点强

xiaygn 发表于 2018-10-20 09:48:32

很好很强很喜欢!!!!!

qq_马卡龙_WRh 发表于 2018-10-22 09:42:17

我们先定一个能达到的小目标,先赚它一亿元素币

experiencc 发表于 2018-10-22 09:48:27

我们先定一个能达到的小目标,先赚它一亿元素币

飞~ 发表于 2018-10-22 09:55:23

赞一个~666

@LD 发表于 2018-10-22 10:01:50

路过围观~感谢分享

qq_Violet_aNs 发表于 2018-10-22 11:13:04

6666

madmonkey 发表于 2018-10-22 13:36:35

不错的资源,谢谢分享

刘亮亮-游戏果动 发表于 2018-10-23 19:32:19



元素那么大,我想来看看!

qq_繁华落尽_LAh 发表于 2018-10-23 20:45:18

mark mark!

xiaowei1980 发表于 2018-10-23 20:51:04

{:1_237:}

zdl412 发表于 2018-10-24 09:29:36

ni
ce
页: [1] 2
查看完整版本: Unity仿海岛奇兵海洋效果