游戏蛮牛学习群(纯技术交流,不闲聊):159852603
游戏蛮牛 手机端
开启辅助访问
 找回密码
 注册帐号

扫一扫,访问微社区

查看: 244|回复: 3

[网友原创插件] 寻找更好的海水的移动解决方案 24 0

[复制链接]  [移动端链接]

1

主题

1

帖子

2

积分

Rank: 1

UID
287724
好友
0
蛮牛币
11
威望
0
注册时间
2018-6-28
在线时间
0 小时
最后登录
2018-6-28
发表于 2018-6-28 15:23:27 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有帐号?注册帐号

x
本来已经实现了海岛奇兵的海水,但总觉得差点意思。(海岛奇兵海水地址:https://blog.csdn.net/yxriyin/article/details/78708040 )

打算进一步优化一下。

顶点着色器并不需要变化(以后打算加入波动模型,但现在暂时不考虑,因为是在很远的地方看海)

片段着色器我首先想的是增加一张法线贴图,用来模拟海浪的波纹,因为海盗奇兵是波光,而不是波纹,所以看上去稍微有点呆板。

    float4变量offsetColor =(tex2D(_BumpTex,i.bumpCoord + FLOAT2(_WaterSpeed * _Time.x * 0.5,0))+ tex2D(_BumpTex,FLOAT2(1 - i.bumpCoord .y,i.bumpCoord.x)+ float2(_WaterSpeed * _Time.x * 0.3,0)))/ 2;
    half2 offset = UnpackNormal(offsetColor).xy * _Refract;
    float4 bumpColor =(tex2D(_BumpTex,(i.bumpCoord + offset)+ float2(_WaterSpeed * _Time.x * 0.5,0))+ tex2D(_BumpTex,(float2(1 - i.bumpCoord.y,i.bumpCoord.x )+ offset)+ float2(_WaterSpeed * _Time.x * 0.3,0)))/ 2;
    float3 Normal = UnpackNormal(bumpColor).xyz;
    color = _PureColor * _Pure +(1-Pure)* color;
    color.rgb = color.rgb * 1.2;

原理很简单,就是通过法线贴图的uv偏移,制造海水流动的感觉,其中_PureColor的用途后面再说。

如果只是 这样还远远不够,因为法线必须要有光照才能有更好的效果,但我的目标是移动平台的中低端机,所以肯定不会使用自带的光照,而是直接自己模拟一个最简单的光照和计算

    。float3 lightDir = normalize (float3(1,1,1));
    half3 halfVector = normalize(lightDir);
    float diffFactor = max(0,dot(lightDir,Normal));
    float addValue = min(0.2,exp2(log2(((normalMapValue.z * i.args.x *(1 - Pure * 0.8))+
                    (normalMapValue.w *(1.0 - i.args.x *(1 - Pure ))* i.args.y * 0.8))*((1-i.args.y)* _Pure + i.args.y))* 5.0));
    颜色+ = addValue;
    color.rgb + = color.rgb * diffFactor * strength;

通过法线和光线的夹角,计算出明暗的分量,加到海水颜色上。


简单处理后,效果已经有所体现:但这 还不够,海面本身的效果和海岸效果都不能少。 于是打算根据深度来计算海岸部分的变化。由于手机上对深度图的获取比较耗性能,所以还是打算使用额外的一张贴图来表示深度。越白的地方越浅,越黑的地方越深。我自己取了海岛模型的外轮廓,然后用PS做了一个简单的外发光处理,就当做深度图了。当然如果有美术帮忙,可以根据高度图得到一个完美的深度图,但作为测试,先这样子吧。 然后就是代码:     float deltaDepth = tex2D(_DepthTex,i.texcoord * 10).a;     color.rgb + = color.rgb * diffFactor *(1 - min(1,deltaDepth * 2));     fixed4 waveColor = tex2D(_WaveTex,float2(1-min(_Range.z,deltaDepth)/ _Range.z + _WaveRange * sin(_Time.x * _WaveSpeed + noiseColor.r * _NoiseRange),1)+ offset);     waveColor.rgb * =(1 - (sin(_Time.x * _WaveSpeed + noiseColor.r * _NoiseRange)+ 1)/ 2)* noiseColor.r;
2_53622_1ca13de8214bd4e.jpg
    fixed4 waveColor2 = tex2D(_WaveTex,float2(1-min(_Range.z,deltaDepth)/ _Range.z + _WaveRange * sin(_Time.x * _WaveSpeed + _WaveDelta + noiseColor.r * _NoiseRange),1)+ offset);
    waveColor2.rgb * =(1 - (sin(_Time.x * _WaveSpeed + _WaveDelta + noiseColor.r * _NoiseRange)+ 1)/ 2)* noiseColor.r;
    half water_A = 1 - min(_Range.z,deltaDepth)/ _Range.z;
    half water_B = min(_Range.w,deltaDepth)/ _Range.w;
    color.rgb + =(waveColor.rgb + waveColor2.rgb)* water_A;
    color.a = min(1,deltaDepth * 1.5);

原理也不难,就是根据深度,获取波浪贴图的像素,渲染到海面上,因为波浪要有运动,所以增加了一个sin函数来实现这种变化。另外为了使变化不要那么规则,增加了一个噪点来扭曲海面。

效果如下: 。然后再说一下_PureColor,主要是因为镜头拉高到一定程度之后,海面上的明暗其实是很刺眼的于是模拟了一个减弱振幅, 根据摄像机和海面的距离调整海面的变化强度。
2_53622_30c000080d5043d.jpg


。打算未来更多增加的特性参数状语从句:适用来风格不同游戏的

目前已经上传资产仓库上面了,地址是:

https://www.assetstore.unity3d.com/en/#!/content/120466


已向官方申请打折,不知道会不会通过,哈哈。


最后是片段着色器完整的源代码:
本部分设定了隐藏,以下是隐藏的内容


注意:

用'UnityObjectToClipPos(*)'

替换'mul(UNITY_MATRIX_MVP,*)'//升级注意: UnityObjectToClipPos(*)'

//升级注意:用'UnityObjectToClipPos(*)'

Shader“                 Ocean2 ”
{
        Properties
        {
_MainTex(“Base(RGB),Alpha(A)”,2D)替换'mul(UNITY_MATRIX_MVP,*) “Black”{}
                _MainTex1(“Base(RGB),Alpha(A)”,2D)=“black”{}
                Map(“Base(RGB),Alpha(A)”,2D)=“black”{}
                _BumpTex (” BumpTex“,2D)=”bump“{}
                _DepthTex(”_ DepthTex“,2D)=”black“{}
                _WaveTex(“_ WaveTex”,2D)=“white”{}
                _WaterSpeed(“_ WaterSpeed”,float)= 1
                _Refract(“_ Refract”,Range(0,0.1))= 0.03
                strength(“strength” ))= 0.5
                _Alpha(“_ Alpha”,Range(0,1))= 1
                _Pure(“_ Pure”,Range(0,1))= 1
                _PureColor(“_ PureColor”,Color)=(0, 0)
                _Range(“Range”,vector)=(                0.13,1.53,0.37,0.78 )
        }

SubShader
        {
                LOD 100

                Tags
        {
                “Queue”=“ Geometry-1000“
                ”IgnoreProjector“=”False“
//“RenderType”=“Transparent”
        }
//混合一个
//混合SrcAlpha OneMinusSrcAlpha
                混合SrcAlpha OneMinusSrcAlpha
                Pass
        {
                CGPROGRAM
//升级注意:排除DX11中的着色器; 没有语义的结构(struct v2f members v_darkColor)
#pragma exclude_renderers d3d11
#pragma vertex vert
#pragma fragment frag

#include“UnityCG.cginc”
        struct appdata_t
        {
                float4 vertex:POSITION;
                float2 texcoord:TEXCOORD0;
        };

        结构v2f
        {
                float4 pos:SV_POSITION;
                float2 texcoord:TEXCOORD0;
                float2 normalCoord:TEXCOORD1;
                float2 bumpCoord:TEXCOORD2;
                float4 color:COLOR;
                float2 args:TEXCOORD4;
        };
        统一浮点数_Points [25];
        sampler2D _MainTex;
        sampler2D _MainTex1;
        sampler2D Map;
        sampler2D _BumpTex;
        sampler2D _DepthTex;
        sampler2D _GTex;
        sampler2D _WaveTex;
        浮动_Pure;
      
        浮力;
        float _Alpha;
         
        float4 _PureColor;
        float _WaterSpeed;
        float _Refract;
        float4 _Range;
        fixed4 frag(v2f i):COLOR
        {
                fixed4 color;
                float4 normalMapValue = tex2D(Map,i.normalCoord);
                color = tex2D(_MainTex,i.texcoord);
                color = lerp(color,tex2D(_MainTex1,i.texcoord),(normalMapValue.x * i.args.x)+(normalMapValue.y *(1.0 - i.args.x)));
                float4 offsetColor =(tex2D(_BumpTex,i.bumpCoord + float2(_WaterSpeed * _Time.x * 0.5,0))+ tex2D(_BumpTex,float2(1 - i.bumpCoord.y,i.bumpCoord.x)+ float2(_WaterSpeed * _Time.x * 0.3,0)))/ 2;
                half2 offset = UnpackNormal(offsetColor).xy * _Refract;
                float4 bumpColor =(tex2D(_BumpTex,(i.bumpCoord + offset)+ float2(_WaterSpeed * _Time.x * 0.5,0))+ tex2D(_BumpTex,(float2(1 - i.bumpCoord.y,i.bumpCoord.x )+ offset)+ float2(_WaterSpeed * _Time.x * 0.3,0)))/ 2;
                float3 Normal = UnpackNormal(bumpColor).xyz;
                color = _PureColor * _Pure +(1-Pure)* color;
                color.rgb = color.rgb * 1.2;
                float3 lightDir = normalize(float3(1,1,1));
                half3 halfVector = normalize(lightDir);
                float diffFactor = max(0,dot(lightDir,Normal));
                float addValue = min(0.2,exp2(log2(((normalMapValue.z * i.args.x *(1 - Pure * 0.8))+
                        (normalMapValue.w *(1.0 - i.args.x *(1 - _Pure))* i.args.y * 0.8))*((1 - i.args.y)* _Pure + i.args.y) )* 5.0));
                颜色+ = addValue;
                color.rgb + = color.rgb * diffFactor * strength;
                float index = floor(i.texcoord.x * 10)* 5 + floor(i.texcoord.y * 10);

                if(_Points [index]> 0)
                {
                        float deltaDepth = tex2D(_DepthTex,i.texcoord * 10).a;
                        color.rgb + = color.rgb * diffFactor *(1 - min(1,deltaDepth * 2));
                        //color.rgb + = color.rgb * diffFactor * strength;
                        float _WaveRange = 0.3;
                        float _WaveSpeed = -12.64;
                        float4 noiseColor = float4(1,1,1,1);
                        float _NoiseRange = 6.43;
                        float _WaveDelta = 2.43;
                        fixed4 waveColor = tex2D(_WaveTex,float2(1-min(_Range.z,deltaDepth)/ _Range.z + _WaveRange * sin(_Time.x * _WaveSpeed + noiseColor.r * _NoiseRange),1)+ offset);


                        waveColor.rgb * =(1 - (sin(_Time.x * _WaveSpeed + noiseColor.r * _NoiseRange)+ 1)/ 2)* noiseColor.r;

                        fixed4 waveColor2 = tex2D(_WaveTex,float2(1-min(_Range.z,deltaDepth)/ _Range.z + _WaveRange * sin(_Time.x * _WaveSpeed + _WaveDelta + noiseColor.r * _NoiseRange),1)+ offset);
                        waveColor2.rgb * =(1 - (sin(_Time.x * _WaveSpeed + _WaveDelta + noiseColor.r * _NoiseRange)+ 1)/ 2)* noiseColor.r;

                        half water_A = 1 - min(_Range.z,deltaDepth)/ _Range.z;
                        half water_B = min(_Range.w,deltaDepth)/ _Range.w;

                        // color.rgb = color.rgb * pow(deltaDepth,1)+ waterColor.rgb *(1-pow(deltaDepth,1));
                        // color.rgb = color.rgb *(1 - waterColor.a * water_A)+ waterColor.rgb * waterColor.a * water_A;
                        color.rgb + =(waveColor.rgb + waveColor2.rgb)* water_A;

                        // color.a = min(_Range.x,deltaDepth)/ _Range.x;
                        color.a = min(1,deltaDepth * 1.5);
                }
                color.a * = _Alpha;
        // color = float4(normalMapValue.z,normalMapValue.z,normalMapValue.z,1);
                返回颜色;
        }
                ENDCG
        }
        }
}

回复

使用道具 举报

3偶尔光临
254/300
排名
16357
昨日变化
18

0

主题

152

帖子

254

积分

Rank: 3Rank: 3Rank: 3

UID
277552
好友
0
蛮牛币
79
威望
0
注册时间
2018-4-17
在线时间
62 小时
最后登录
2018-10-7
发表于 2018-7-2 13:37:29 | 显示全部楼层
正在学shader,看不懂看不懂

回复 支持 反对

使用道具 举报

3偶尔光临
267/300
排名
33754
昨日变化
71

0

主题

198

帖子

267

积分

Rank: 3Rank: 3Rank: 3

UID
247666
好友
0
蛮牛币
38
威望
0
注册时间
2017-10-9
在线时间
61 小时
最后登录
2018-11-12
发表于 2018-7-2 20:33:58 | 显示全部楼层
这个很有用,谢谢分享

回复 支持 反对

使用道具 举报

7日久生情
3438/5000
排名
2201
昨日变化
11

0

主题

2450

帖子

3438

积分

Rank: 7Rank: 7Rank: 7Rank: 7

UID
185339
好友
1
蛮牛币
4445
威望
0
注册时间
2016-11-20
在线时间
378 小时
最后登录
2018-11-15
发表于 2018-7-3 09:58:07 | 显示全部楼层

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册帐号

本版积分规则

关闭

站长推荐 上一条 /1 下一条

快速回复 返回顶部 返回列表