赞
踩
在很多游戏场景中,例如fps游戏,为了使游戏更加更加生动逼真,往往会给游戏添加一些细节,例如子弹射击墙壁留下弹痕,刀砍到树木留下刀痕等等类似的细节。所以就需要使用到贴图融合的方式,去实现这样一个效果。当然贴图融合只是其中的一种解决方案,你也可以让美术做成对应的特效,这里就不多做介绍。直接讲贴图融合。
其实一个贴图就有很多个像素点构成的。如果我们需要以面墙壁上出现弹痕,那么只需要将墙壁的贴图子弹击中位置的像素区域,替换成我们实现准备好的弹痕贴图。是不是就完美的解决了问题。下面以unity3d为例,介绍贴图融合的过程以及代码实现。
导入需要融合的两张贴图,因为融合贴图涉及到贴图的读写操作,所以需要设置贴图为 read/write enabled,同时Format属性设置成RGBA32bit。
代码实现两张贴图的融合
**这里有一个必要条件,就是贴图融合的对象必须要拥有碰撞体collider,不然是没办法获取碰撞点对应的uv的。**从上述的作用场景,我们也不难看出,一般都是都碰撞的时候,用贴图融合的方式去实现碰撞留下的痕迹,而碰撞发生的前提就是collider。具体实现步骤如下:
a.获取目标贴图,获取融合点UV坐标
b.加载需要融合在目标贴图上的贴图。
c. 双层循环遍历弹痕贴图的长宽,计算弹痕贴图在主帖图的像素位置
uv.x主帖图宽度-弹痕贴图宽度/2+i;
uv.y主帖图宽度-弹痕贴图长度/2+j;
d.通过循环索引获取弹痕像素颜色值
e.在目标贴图上相应位置设置新的颜色值(加上alpha值判断)
f.循环外保存融合后的贴图 texture2d.apply();
下面贴出代码供大家参考
pivate Texture2D mark_Texture; private Texture2D main_Texture; /// <summary> /// 贴图融合 /// </summary> /// <param name="hit">碰撞点</param> public void CreateMark(RaycastHit hit) { //TODO:可以在这里添加碰撞音效 eg:子弹击中墙壁的音效 Vector2 uv = hit.textureCoord; //获取碰撞点坐标(UV既碰撞中心点的坐标x,0~1,y,0~1) for (int i = 0; i < mark_Texture.width; i++) //遍历弹痕贴图的像素横坐标 { for (int j = 0; j < mark_Texture.height; j++) //遍历弹痕贴图的像素纵坐标 { //求取弹痕的像素坐标对应在主帖图的像素位置(参考上图理解) float x = uv.x * main_Texture.width - mark_Texture.width / 2 + i; float y = uv.y * main_Texture.height - mark_Texture.height / 2 + j; Color color = mark_Texture.GetPixel(i,j); if (color.a > 0.2f) main_Texture.SetPixel((int)x, (int)y, color); } } main_Texture.Apply(); }
这里只是贴图融合的一个方法。这里需要思考的问题是,产生了**”碰撞痕迹“,游戏中一般都不会一直存在碰撞痕迹**,所以需要消除痕迹。就应该有消除融合,原理就是拿原来的贴图再融合一下,只是过程反着来一下,就不多解释。需要注意的是产生和消除,就会频繁的创建和销毁碰撞痕迹这样一个对象。所以我们最好还是用对象池去管理一下,减少不必要的消耗。
另外就是,可以把融合贴图这个事情本身封装成一个工厂,提供不同的参数,产生不同的碰撞痕迹,就提高了脚本的通用性。
希望今天的分享对大家有所帮助,有不明白的,可以评论区留言我会尽快回复,我是程序员小虎。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。