Unity3d 使二维水看起来像三维水

Unity3d 使二维水看起来像三维水,unity3d,shader,cg,Unity3d,Shader,Cg,如果有人能帮忙的话,我对这方面不太了解 我正在使用这个免费的2d水资源,它包含一个水着色器。我想编辑该着色器,使其看起来更像2.5d或3d 现在看起来是这样的 我想让它看起来像 在顶部添加一个泡沫类型的东西,使其有点反光 资源中用于生成二维水的着色器 Shader "Water2D/Metaballs_Simple" { Properties { _MainTex ("Texture", 2D) = "white" { } _Color ("Main color", Color) =

如果有人能帮忙的话,我对这方面不太了解

我正在使用这个免费的2d水资源,它包含一个水着色器。我想编辑该着色器,使其看起来更像2.5d或3d

现在看起来是这样的

我想让它看起来像

在顶部添加一个泡沫类型的东西,使其有点反光

资源中用于生成二维水的着色器

Shader "Water2D/Metaballs_Simple" {
Properties {  
_MainTex ("Texture", 2D) = "white" { }  
_Color ("Main color", Color) = (1,1,1,1)
_Cutoff ("Alpha cutoff", Range(0,1)) = 0.5

_Stroke ("Stroke alpha", Range(0,1)) = 0.1
_StrokeColor ("Stroke color", Color) = (1,1,1,1)

}
/// <summary>
/// Multiple metaball shader.

/// </summary>
SubShader {
Tags {"Queue"="AlphaTest" "IgnoreProjector"="True" "RenderType"="TransparentCutout"}
GrabPass{}
Pass {
Blend SrcAlpha OneMinusSrcAlpha  
// Blend One One // Additive
// Blend One OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag  
#include "UnityCG.cginc"  
float4 _Color;
sampler2D _MainTex;  
fixed _Cutoff;
fixed _Stroke;
half4 _StrokeColor;
float2 _screenPos;



float4 _CameraDepthTexture_TexelSize;


struct v2f {
    float4  pos : SV_POSITION;
    float2  uv : TEXCOORD0;
};  

float4 _MainTex_ST;      
v2f vert (appdata_base v){
    v2f o;
    o.pos = UnityObjectToClipPos (v.vertex);
    o.uv = TRANSFORM_TEX (v.texcoord, _MainTex);
    return o;
};




half4 frag (v2f i) : COLOR{      
    half4 texcol= tex2D (_MainTex, i.uv);
    //half4 finalColor = texcol;


    clip(texcol.a - _Cutoff);

    if (texcol.a < _Stroke) {
        texcol = _StrokeColor;
    } else {
        texcol = _Color;
    }



     return texcol;


}




ENDCG

}
}
Fallback "VertexLit"
}
Shader“Water2D/Metaballs\u Simple”{
属性{
_MainTex(“纹理”,2D)=“白色”{}
_颜色(“主颜色”,颜色)=(1,1,1,1)
_截止点(“α截止点”,范围(0,1))=0.5
_行程(“行程α”,范围(0,1))=0.1
_笔划颜色(“笔划颜色”,颜色)=(1,1,1,1)
}
/// 
///多重变形球着色器。
/// 
子阴影{
标记{“队列”=“AlphaTest”“IgnoreProjector”=“True”“RenderType”=“TransparentCuout”}
GrabPass{}
通过{
混合SrcAlpha ONEMUSSRCALPHA
//混合一种/一种添加剂
//把一个混合在一起
CGP程序
#pragma顶点顶点
#布拉格碎片碎片
#包括“UnityCG.cginc”
浮色;
取样器2D_MainTex;
固定切断;
固定行程;
半4_色;
浮动2_屏幕位置;
float4 _CameraDepthTexture _TexelSize;
结构v2f{
浮动4位置:SV_位置;
float2uv:TEXCOORD0;
};  
浮动4(缅特克斯街);;
v2f垂直(appdata_base v){
v2fo;
o、 pos=单位对象到lippos(v.顶点);
o、 uv=变换_TEX(v.texcoord,_MainTex);
返回o;
};
半4碎片(v2f i):颜色{
half4 texcol=tex2D(_MainTex,i.uv);
//半4最终颜色=texcol;
夹子(texcol.a-_切断);
if(texcol.a<\u冲程){
texcol=_StrokeColor;
}否则{
texcol=_颜色;
}
返回texcol;
}
ENDCG
}
}
回退“顶点照明”
}

根据着色器判断,流体的纹理似乎包含基于到边缘距离的alpha渐变。如果这类似于距离场,则可以使用它基于导数重建屏幕空间法线

float3 normal;
normal.x = ddx(texcol.a);
normal.y = ddy(texcol.a);
normal.z = sqrt(1 - normal.x*normal.x - normal.y * normal.y);
然后,您可以使用此值计算一些基本的blinn phong镜面反射照明。这涉及到使用灯光矢量和相机矢量之和来获得中间矢量

由于法线位于摄影机空间中,我们可能也希望在摄影机空间中执行所有其他计算。理想情况下,我们希望在顶点着色器中执行尽可能多的计算,然后将它们传递给片段着色器:

struct v2f {
    float4  pos : SV_POSITION;
    float2  uv : TEXCOORD0;
    float3  viewDir : TEXCOORD1;
    float3  lightDir : TEXCOORD2;
};  

float4 _MainTex_ST;      
v2f vert (appdata_base v){
    v2f o;
    o.pos = UnityObjectToClipPos (v.vertex);
    o.viewDir = mul((float3x3)UNITY_MATRIX_MVP, ObjSpaceViewDir(v.vertex));
    o.lightDir = mul((float3x3)UNITY_MATRIX_MVP, ObjSpaceLightDir (v.vertex));
    o.uv = TRANSFORM_TEX (v.texcoord, _MainTex);
    return o;
};
我假设ObjSpaceLightDir适用于2D灯光,但我不确定。 在片段着色器中,我们现在可以获得镜面反射高光:

float3 lightDir = normalize(i.lightDir);
float3 viewDir = normalize(i.viewDir);
float3 halfDir = normalize(lightDir + viewDir);

float spec = pow(saturate(dot(normal, halfDir)), _Glossiness * 128);

return saturate(_BaseColor + spec);
还可以添加一些细微的lambert着色以在下面创建阴影:

float diff = saturate(dot(normal, lightDir));
// 20% diffuse contribution, because lots of light passes through the liquid.
// Can be tweaked based on artistic needs.
return saturate(_BaseColor * (0.8 + 0.2 * diff) + spec);
请注意,这不会正确地给出参考的厚度错觉。为此,您需要将流体的厚度模拟到高度贴图中,并在此基础上生成法线。您可以通过向镜面反射添加一些程序噪声来打破镜面反射的形状,尽管我没有尝试过这一点。当writing shaders是因为GPU除了你赋予它的内容外,对像素的上下文一无所知,所以像到最近边缘的距离之类的东西必须预先计算并作为纹理输入到材质中。老实说,我不确定他们是如何在顶部产生泡沫的——它可能是水纹理的一部分,也可能是一个单独的spr它在背景中渲染