参考链接:http://liweizhaolili.blog.163.com/blog/static/1623074420140591864/
效果图:
1.首先就是简单的渐现效果,同时要注意,在出现网格时,需要用到透明度混合
Shader "Custom/Mesh"
{
Properties
{
_MainTex ("MainTex", 2D) = "white" {}
_MeshTex ("MeshTex", 2D) = "white" {}
_ThresholdY ("ThresholdY", Range(-8, 0)) = -8//调试出来的范围
}
SubShader
{
Tags { "Queue" = "Transparent" "IgnoreProjector" = "true" "RenderType"="Transparent" }
Pass
{
ZWrite off
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
};
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _MeshTex;
half _ThresholdY;
v2f vert (appdata v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
//最好选择世界空间坐标系下的顶点而非模型空间下的顶点
//因为后者会因为模型制作的规范不同而不同
half y = -i.vertex.y;
if(y < _ThresholdY * 50)//50是调试出来的值
{
fixed4 col = tex2D(_MainTex, i.uv);
return col;
}
else
{
return fixed4(0, 0, 0, 0);
}
}
ENDCG
}
}
}
2.上面的是手动拖动_ThresholdY的情况,现在我们需要使它自动化
Shader "Custom/Mesh"
{
Properties
{
_MainTex ("MainTex", 2D) = "white" {}
_MeshTex ("MeshTex", 2D) = "white" {}
_ThresholdY ("ThresholdY", Range(-8, 0)) = -8//调试出来的范围
_Speed ("Speed", Range(0.1, 1)) = 0.5
}
SubShader
{
Tags { "Queue" = "Transparent" "IgnoreProjector" = "true" "RenderType"="Transparent" }
Pass
{
ZWrite off
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
};
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _MeshTex;
half _ThresholdY;
half _Speed;
v2f vert (appdata v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
//最好选择世界空间坐标系下的顶点而非模型空间下的顶点
//因为后者会因为模型制作的规范不同而不同
half y = -i.vertex.y;
half threY = lerp(-8, 0, _Time.y * _Speed);
//_ThresholdY就不需要了
if(y < threY * 50)//50是调试出来的值
{
fixed4 col = tex2D(_MainTex, i.uv);
return col;
}
else
{
return fixed4(0, 0, 0, 0);
}
}
ENDCG
}
}
}
3.上面的渐现,是一条“线”从下到上去“扫描”模型,而想达到效果图那样的效果,就要使用两条"线",为了更好了解,我画了幅图。如下图,其中高度范围会随时间不断向上。对于每个像素的Y值,如果大于maxY,则透明;如果小于maxY大于minY,则显示网格;如果小于minY,则出现真正的贴图
Shader "Custom/Mesh"
{
Properties
{
_MainTex ("MainTex", 2D) = "white" {}
_MeshTex ("MeshTex", 2D) = "white" {}
_MinY ("MinY", Range(-20, 0)) = -20
_MaxY ("MaxY", Range(-15, 0)) = -15
_Speed ("Speed", Range(1, 10)) = 5
}
SubShader
{
Tags { "Queue" = "Transparent" "IgnoreProjector" = "true" "RenderType"="Transparent" }
Pass
{
ZWrite off
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
};
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _MeshTex;
half _MinY;
half _MaxY;
half _Speed;
v2f vert (appdata v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
//最好选择世界空间坐标系下的顶点而非模型空间下的顶点
//因为后者会因为模型制作的规范不同而不同
half y = -i.vertex.y;
_MinY += _Time.y * _Speed;
_MaxY += _Time.y * _Speed;
_MinY *= 50;//让_MinY更"负"
_MaxY *= 50;//让_MaxY更"负"
if(y > _MaxY)
{
return fixed4(0, 0, 0, 0);
}
else if(y > _MinY)
{
fixed4 col = tex2D(_MeshTex, i.uv);
return col;
}
else
{
fixed4 col = tex2D(_MainTex, i.uv);
return col;
}
}
ENDCG
}
}
}
最上面的效果图是先显示完整的网格,然后再显示原贴图的,那么我们可以通过缩小高度范围,达到边显示网格边显示原贴图
这是unitypackage:
http://pan.baidu.com/s/1pLvQuON