原创作品

Unity简单卡通水体

SHENG 发表于   2021-09-27 13:53:42
4189
4
19



效果一览:

不带有水底扰动的效果

带有水底扰动的效果


具体实现:

无扰动效果

ToonWater.shader


Shader "Custom/ToonWater"

{

Properties

{

_Color("Color", Color) = (1, 1, 1, 1)

_DepthColor("DepthColor", color) = (1,1,1,1)

            _DepthBlend("Depth",float) = 1

_FoamColor("FoamColor",color) = (1,1,1,1)

_FoamSpeed("FoamSpeed",float) = 1

_FoamEdgeDepth("Foam Edge Depth", float) = 1.0

_WaveSpeed("Wave Speed", float) = 1.0

_WaveHeight("Wave Height", float) = 0.2

_NoiseTex("Noise Texture", 2D) = "white" {}

_MainTex("Main Texture", 2D) = "white" {}

}


SubShader

{

        Tags

"Queue" = "Transparent"

}


Pass

{

//在_Color,_DepthColor中设置Alpha值从而使水面与水底混合

              Blend SrcColor OneMinusSrcAlpha


CGPROGRAM

              #include "UnityCG.cginc"


#pragma vertex vert

#pragma fragment frag

// Properties

float  _FoamEdgeDepth;

float  _WaveSpeed;

float  _WaveHeight;

float _DepthBlend;

float _FoamSpeed;

float4 _Color;

float4 _MainTex_ST;

float4 _DepthColor;

float4 _FoamColor;

sampler2D _CameraDepthTexture;

sampler2D _NoiseTex;

sampler2D _MainTex;


struct a2v

{

float4 vertex : POSITION;

float4 texCoord : TEXCOORD0;

};


struct v2f

{

float4 pos : SV_POSITION;

float2 texCoord : TEXCOORD0;

float4 screenPos : TEXCOORD1;

};


v2f vert(a2v i)

{

v2f o;


o.pos = UnityObjectToClipPos(i.vertex);


//波浪顶点动画

//为什么用tex2Dlod(),见http://www.ufgame.com/9620.html

float noise = tex2Dlod(_NoiseTex, float4(i.texCoord.xy, 0, 0));

o.pos.y += sin(_Time*_WaveSpeed*noise+(o.pos.x*o.pos.z))*_WaveHeight;


// 计算屏幕空间深度

o.screenPos = ComputeScreenPos(o.pos);

//水面泡沫位移

_MainTex_ST.w +=_Time*_FoamSpeed;

 

o.texCoord = TRANSFORM_TEX(i.texCoord,_MainTex);


return o;

}


float4 frag(v2f i) : COLOR

{

//采样并线性化深度值

float4 depthSample = SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, i.screenPos);

float depth = LinearEyeDepth(depthSample).r;


//通过深度值对比创建边缘泡沫因子,其中i.screenPos.w存放的视空间下的线性深度值

float foamLine = 1 - saturate(_FoamEdgeDepth * (depth - i.screenPos.w));

//通过深度值对比创建水体深度颜色渐变因子

float waterDepth = saturate(_DepthBlend * (depth - i.screenPos.w));

                //混合最终颜色

float4 mainColor = tex2D(_MainTex,i.texCoord);

  float4 color = lerp(_Color,_DepthColor,waterDepth) + (foamLine * _FoamColor) + (mainColor *_FoamColor);

                return color;

}

ENDCG

}

}

}


创建一个plane,挂上带有上述shader的材质

参数参考


带扰动效果

ToonWaterWithDistortion.shader


Shader "Custom/Water"

{

Properties

{

_Color("Color", Color) = (1, 1, 1, 1)

_DepthColor("DepthColor", color) = (1,1,1,1)

            _DepthBlend("Depth",float) = 1

_FoamColor("FoamColor",color) = (1,1,1,1)

_FoamSpeed("FoamSpeed",float) = 1

_FoamEdgeDepth("Foam Edge Depth", float) = 1.0

_WaveSpeed("Wave Speed", float) = 1.0

_WaveHeight("Wave Height", float) = 0.2

_NoiseTex("Noise Texture", 2D) = "white" {}

_MainTex("Main Texture", 2D) = "white" {}

_DistortStrength("Distort Strength", float) = 1.0

}


SubShader

{

        Tags

"Queue" = "Transparent"

}


//抓取背景图

        GrabPass

        {

            "_BackgroundTexture"

        }


Pass

{

CGPROGRAM

                        #include "UnityCG.cginc"


#pragma vertex vert

#pragma fragment frag

float  _FoamEdgeDepth;

float  _WaveSpeed;

float  _WaveHeight;

float _DepthBlend;

float _FoamSpeed;

float _DistortStrength;

float4 _Color;

float4 _MainTex_ST;

float4 _DepthColor;

float4 _FoamColor;

sampler2D _CameraDepthTexture;

sampler2D _BackgroundTexture;

sampler2D _NoiseTex;

sampler2D _MainTex;


struct a2v

{

float4 vertex : POSITION;

float4 texCoord : TEXCOORD0;

};


struct v2f

{

float4 pos : SV_POSITION;

float2 texCoord : TEXCOORD0;

float4 screenPos : TEXCOORD1;

float4 grabPos : TEXCOORD2;

};


v2f vert(a2v i)

{

v2f o;


o.pos = UnityObjectToClipPos(i.vertex);


o.grabPos = ComputeGrabScreenPos(o.pos);


//波浪顶点动画

//为什么用tex2Dlod(),见http://www.ufgame.com/9620.html

float noise = tex2Dlod(_NoiseTex, float4(i.texCoord.xy, 0, 0));

o.pos.y += sin(_Time*_WaveSpeed*noise+(o.pos.x*o.pos.z*noise))*_WaveHeight;

//对背景图采样坐标进行噪声扰动

o.grabPos.y += sin(_Time*_WaveSpeed*noise)*_WaveHeight * _DistortStrength;

                                o.grabPos.x += cos(_Time*_WaveSpeed*noise)*_WaveHeight * _DistortStrength;

// 计算屏幕空间深度

o.screenPos = ComputeScreenPos(o.pos);

//水面泡沫位移

_MainTex_ST.w +=_Time*_FoamSpeed;

 

o.texCoord = TRANSFORM_TEX(i.texCoord,_MainTex);


return o;

}


float4 frag(v2f i) : COLOR

{

//采样并线性化深度值

float4 depthSample = SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, i.screenPos);

float depth = LinearEyeDepth(depthSample).r;


float4 mainColor = tex2D(_MainTex,i.texCoord);

//通过深度值对比创建边缘泡沫因子,其中i.screenPos.w存放的视空间下的线性深度值

float foamLine = 1 - saturate(_FoamEdgeDepth * (depth - i.screenPos.w));

//通过深度值对比创建水体深度颜色渐变因子

float waterDepth = saturate(_DepthBlend * (depth - i.screenPos.w));

//采样扰动后的背景图

float4 backColor = tex2Dproj(_BackgroundTexture, i.grabPos);

//混合水面水底颜色与边缘泡沫线颜色

        float4 color = lerp(_Color,_DepthColor,waterDepth) + foamLine * _FoamColor;

//混合背景图与水体颜色以及表面泡沫(MainColor)颜色

color = lerp(backColor,color,color.a) + mainColor*_FoamColor;


                                return color;

}


ENDCG

}

}

}



参数参考


注意事项:

注意正确配置Color和DepthColor的alpha值,使得水体颜色能够恰当的混合



没有标签
确定
评论(4)
鸡汁的松哥哥
为什么我复制下来用不了,大佬教教我
回复
929天前
胡子白了
谢谢大佬分享
回复
930天前
cokey
天美的TA大佬吗
回复
940天前
没有更多啦~
  • 咨询
    客服
  • 扫码加入QQ群 或搜索QQ群号: 797421367
  • 扫码关注公众号 或微信搜索: cokey游戏特效