项目为方便编辑地图,使用的是Unity自带的Tilemap功能。因为使用的是俯视视角,拼好第一个地图后发现2D图片展现的效果太平了,地面和障碍物很难分辨。所以才有了“把2d图片展现出3d效果”的需求。
最终花了一个礼拜的时间把这个功能搞出来。
3d效果有阴影和透视两个需求,透视还在研究中,先讲阴影
使用3d物体的真实阴影
- 因为Tilemap是按照单个Tile来渲染的,所以完全可以获取这张Tilemap上所有被填充的格子,生成具有高度的3d物体,设为Cast Shadow Only,我这里直接用Cube,如果是其他的Tile的形状,也可以让模型做一个简单的几何体。
- 使用一张Plane接收阴影。
- 渲染这个平面及阴影到一张Render Texture
- Shader只针对渲染这张Render Texture的物体:依据颜色进行剔除操作。
fixed _CutoutFactor;//剔除因子,因为处理的颜色rgb值完全相同,使用单个数字即可
sampler2D _MainTex;//Render Texture
v2f vert(a2v v)
{
v2f o;
o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
o.uv=v.texcoord;
return o;
}
fixed4 frag(v2f i)
{
fixed3 c=tex2D(_MainTex,i.uv);
if(c.r>_CutoutFactor)
{
discard;
}
}
用于接收阴影的Plane不是纯白色也没关系,只要和阴影的颜色有明显的分界,外部调整Cutout Factor也能剔除非阴影部分。
优点
- 使用方便
- 使用Unity的内置阴影,能承接很多插件
缺点
- 使用Unity的内置阴影,无法精确控制其上的每一个像素。
- 2d游戏使用了3d的功能,感觉是个偏方,万一用cocos做可咋办呢。
后续需要实现软阴影的效果,如果要保持这种做法会很麻烦,于是就有了第二种做法。
在2d平面上模拟3d阴影
在3d空间中,俯视情况下,阴影看起来像从物体的背光边界出发,往外延伸一段距离所产生的图片。
所以只要某个片元的位置+特定方向(光照的反方向)*一定距离(阴影距离)是障碍物,那这个片元就属于阴影的一部分。
具体做法如下:
-
先获取这样的一张图
黑色的方块代表障碍物,主要目的是把障碍物的轮廓显示出来,获取这种图片的方法有很多,深度图或者自己写shader处理render texture都可以,这里就不讲了。 -
把这张图片渲染到一张面片上,shader如下。片元着色器中有迭代采样的函数,是因为需要获取片元到边界的距离,方便对颜色进行操作,以实现软阴影的需求。
Shader "Custom/MapShadow"
{
Properties
{
_MainTex</