专栏首页重归混沌通过Mesh投影来实现贴花系统

通过Mesh投影来实现贴花系统

在做FPS之类的游戏中,如果枪打到了墙角,并不能简单放置一来弹孔面片了事。而是要像一张贴纸一样,完全与墙角贴合。这时就需要去实现一个贴花系统来达到这种效果。

贴花系统有几种不同的实现方式,但这里仅考虑通过Mesh投影来实现贴花系统的实现原理。

这种方式的本质是,找到视野中贴花资源会影响的Mesh, 并创建一个同样大小以贴花资源为纹理的Mesh覆盖上去,从而达到贴花的目的。主要分下面两步来实现。

1. 先找到会受影响的物体,比如将弹孔贴在两面墙的夹角,那么受影响的物体就是两面墙。

怎么找到这两面墙不同的需求可能实现方式也不一样, 在场景编辑器中通过贴花来实现静态点缀效果,可以通过创建贴花资源的AABB盒来实现。如果是运行时动态创建弹孔也可以通过四次射线检测来达到,总之方式有很多。

2. 先创建一个半径为0.5单位的裁切立方体,在裁切坐标系中,贴花资源就被放在y=0平面中,贴花资源的中心就是裁切坐标系的(0, 0, 0)点。

需要说明的时这一步实际上并没有代码操作,只是一个数学抽象。我们的目的是要将所有受影响的三角形投影到y=0平面上,以便可以正确的采样贴花纹理。

3. 将受影响物体Mesh的所有三角形均转换到裁切立方体的坐标系之下对立方体的8个平面进行裁切。

在进行裁切之前,有一种情况需要处理,因为三角形是有朝向的,这个朝向是通过面法线来确定的(Unity中三角形的法线为Cross(v2-v1, v3-v1)),在正常的渲染流程中法线不能射入眼睛时,是不会被渲染的。在Unity中视锥体坐标系中,Vector3(0, 0, -1)是前向,因此眼睛的位置在Vector3(0, 0, 1)处。

在这个裁切立方体同样如此,不可能将纹理投影到一个三角形平面的背面,所以需要先先判断三角形的法线与Vector3(0, 0, 1)的夹角是否小于90度,只有小于90度才可能会被投影,才需要被裁切。

裁切时会出现,三角形完全在立方体外, 三角形完全在立方体内,三角形一部分在立方体外一部分在立方体内。前两种情况很好处理,但是第三种情况有可能会将一个三解形切成2个,因此需要格外注意。具体的裁切算法视锥体裁切算法一致,这里就不赘述。

4. 纹理采样,在创建三角形时,我们需要为每个一顶点指定一个uv坐标。前面已经说过了,我们的实现方式是将裁切后合法的三角形投影到裁切坐标系的y=0平面上, 投影之后的坐标为(x, 0, z). 因此uv可直接执行u = Lerp(0.0f, 1.0f, x + 0.5f), v = Lerp(0.0f, 1.0f, z + 0.5f).这里之所以加0.5f修正是因为立方体中心坐标为(0, 0, 0),这也意味着x,y,z的最小值均为-0.5f.

说了这么多附上源码一篇。需要说明的是,这个源码并不是我实现的,是我从网上找来之后修改的,毕竟我对Unity3d没有那么熟悉。

ps.单位相同的裁切立方体如何适应不同尺寸的贴花资源?在Unity中可以通过设置Scale拉伸坐标轴来实现,所以说3D数学真奇妙。

pps.在实现过程中发现,新创建的Mesh不能紧贴被覆盖的Mesh, 因为在相同的深度情况下,新创建的Mesh并不能保证一定在被覆盖的Mesh之后渲染,这会概率性出现新创建的Mesh与被覆盖的Mesh相互覆盖的情况。因为在创建完Mesh之后,需要根据平面法线上浮一点,以保证Z-Buffer正常工作。

本文分享自微信公众号 - 重归混沌(findstrx),作者:重归混沌

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-06-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 一次性能优化经历

    自从上次修改backlog之后, Silly的IO能力,就一直以少量(约4~6K)的差距落后于redis,却一直找不到原因。

    重归混沌
  • 开卷有益(UNIX编程艺术篇)

    最近《计算机程序设计艺术》看多了,每次写完代码之后,总会习惯估算一下指令级的开销。导致每次写代码都是性能导向,违反了很多设计准则。因此打算重新看一下《UNIX编...

    重归混沌
  • 再学计算机图形学入门

    在网上查资料时,无意间发现了一门课叫《现代计算机图形学入门》。于是事隔将近3年后,我再一次尝试图形学入门。这次学习从8月20号开始,一直到10月11日,约持续了...

    重归混沌
  • mirDIP 4.1:寻找miRNA靶基因的神器

    近年来科研热点不断涌现,包括转录组、lncRNA、m6A、单细胞测序等等,真让人应接不暇,但有一个研究方向一直以来都未曾真正的失宠,那就是miRNA。根据pub...

    Mark Chen
  • php定期拉取数据对比

    前面的是运行周期的配置,后面的是sh脚本的路径,该方式一般需要自己编写sh脚本来执行

    宣言言言
  • 【笔记】《C++Primer》—— 第12章:动态内存

    这一章介绍了标准库对动态内存的管理方面,其中12.1的几个智能指针是C11引入的非常实用的类。这章对优化C++代码的编写有很大意义,值得好好理解。至此第...

    ZifengHuang
  • 【学习】《R实战》读书笔记(第六章)

    读书会是一种在于拓展视野、宏观思维、知识交流、提升生活的活动。PPV课R语言读书会以“学习、分享、进步”为宗旨,通过成员协作完成R语言专业书籍的精读和分享,达到...

    小莹莹
  • 你的网站是否已经被谷歌浏览器Chrome68将标记为不安全

    谷歌一直是互联网工作的重要浏览工具,由于它各方面性能优于同行业其他浏览器许多,所以一直是大家追捧的目标。今年2月来自谷歌安全博客宣布的,关于7月将发布的 Chr...

    砸漏
  • Google Chrome 68 正式向所有不安全的 HTTP 网站开炮

    在 7 月 24 号发布的 Chrome 68 中,Google 引入了一项重大的变化。当加载非 HTTPS 网站时,该浏览器的处理方式会更加审慎。据悉,只要遇...

    C4rpeDime
  • 基础扩展 | 11. 使用ADO和SQL在Excel工作表中执行查询操作

    我们可以将存储数据的工作表当作数据库,使用ADO技术,结合SQL查询语句,可以在工作表中获取满足指定条件的数据。

    fanjy

扫码关注云+社区

领取腾讯云代金券