Unity shader 角色消失 溶解 隐身 效果

先上两张效果图

在这里插入图片描述
在这里插入图片描述

实现原理

一句话总结:
空间中有一个隐形的面,判断模型上和面的相对位置,根据需求隐藏上方或者下方的点。

原理就这么简单,具体怎么实现呢,首先确定数学几何中平面的性质:原点到到面上任意一点构成的向量a,再这个面的法线(n)方向投影,都是相等的,距离为d。用数学公式表达为:
ax + by + cz = d
画一个小图更容易理解:
在这里插入图片描述
最简单地平面垂直于Y轴。P1和P2在法线方向的投影是红色的虚线,长度相同,为d。P3是面下方的点,在法线方向的投影小于d,由此可以通过空间中任意一点的以原点为起点的向量再面法线方向的投影跟d值比较,判断这个点和面的相对位置。法线方向不同,判断的方式也就不同。
PS:选择原点因为一个点的坐标值就是它的向量,方便计算。也可以选择空间中其他点作为计算的原点。
通过上面的讲解,可以确定,在写shader前,需要拿到法线向量和d,所以选面上的任意一点,再选一个法线向量。为了计算方便,直接选择ntransform.forward,任意一点P为transform.position,通过C#算出d,将法线和d传入shader中,为了节省变量,shader中应选择一个vector,xyz分量为法线的xyz,w分量作为d(当然也可以多个变量)。然后可以开始编写shader了。

Vector3 point = transform.position;
Vector3 normal = transform.forward;
float dis = Vector3.Dot(point, normal.normalized);
material.SetVector("_Plane", new Vector4(normal.x, normal.y, normal.z, dis));
  • 1
  • 2
  • 3
  • 4

此时问题就变成了任意空间的任意一点(坐标即为它的向量)在向量n的投影,和d作比较。
在这里插入图片描述
如上图,只需要计算蓝色虚线的长度即可,使用向量的点乘dot,P点向量点乘法线的单位向量,就直接是蓝色虚线的长度。

float3 face_normal = _Plane.xyz;
float target_dis = _Plane.w;
float dis = dot(i.worldPos.xyz, normalize(face_normal));
clip(dis - target_dis);
  • 1
  • 2
  • 3
  • 4

接下来根据法线的方向或者自己的需求,使用clip剪裁调不符合需求的点就能达到剔除的效果,如下图:
在这里插入图片描述
为了使效果更加柔和点,添加一个噪声图,将需要clip的点进行随机偏移,修改噪声图的Tiling值,改变采样的频率,实现文章开始的效果。

fixed4 col = tex2D(_NoiseTex, TRANSFORM_TEX(i.uv, _NoiseTex));
float offset = (col.r * 2 - 1) * _Strength;
float3 w_pos = i.worldPos.xyz + float3(offset, offset, offset);
float3 face_normal = _Plane.xyz;
float target_dis = _Plane.w;
float dis = dot(w_pos, normalize(face_normal));
clip(dis - target_dis);

猜你喜欢

转载自blog.csdn.net/mango9126/article/details/109373590