设为首页收藏本站喵玉殿官方微博

 找回密码
 少女注册中
搜索
楼主: Darksword

[编程算法] Dx中曲线激光的实现方法

  [复制链接]
发表于 2014-12-10 17:40:09 | 显示全部楼层
本帖最后由 lrdcq 于 2014-12-10 20:13 编辑

因为制作过以还原东方曲线激光为目标的小游戏(http://tieba.baidu.com/p/2827270606
所以自誉对东方中的曲线激光还算有点研究了
准备长篇大论,占楼待编辑好吧,其实我刚才去吃了个晚饭,然后回来慢慢截图然后来了几局STG
其实LZ已经把问题解决得差不多了,我从一些细节和大家争论的地方,以ZUN为标准来讲一些东西吧。

1.定义,什么是东方中的曲线激光?
嘛,曲线激光就曲线激光嘛,东方的曲线激光,ZUN的曲线激光,非要确定下来的话是自东方亲民船出现的,使用bullet文件夹的这张贴图作为素材(除了火葬场里面的闪电曲线激光)
rxx1.jpg
形成的激光。所以,这样
rxx5.jpg
rxx6.jpg
rxx3.jpg
这样就是曲线激光。
而另一种大家很容易想到的方法,由大量高光blend出来的弹幕组成的看起来像激光一样的瞎眼的东西,比如这样
rxx333.jpg
rxx335.jpg
rxx334.jpg
就不属于东方的曲线激光,不在我们讨论范围之列。


2.曲线激光模型是的怎么构成的呢?
a.仔细观察每一条曲线激光,它是由完整的一块贴图扭曲而成,也就是大家想到的四边形细分扭曲
rxx7.jpg
b.游戏中可以显而易见的得到,曲线激光的形状是由一颗弹幕移动牵引出的轨迹而得到的,并且牵引轨迹的控制点的数目对于每一条激光是固定(通过大圣非符速度变慢的激光长度变短可证)。


3.曲线激光的牵引弹幕的控制点是怎么选取的?
前提:牵引弹幕的移动路径留下的点压入长度为按需求定义的N的队列中,作为控制点队列
a.可以直接选取需求长度中的所有的N个点构成曲线激光模型。
b.对于宽度过大速度过慢的曲线激光会出现问题,比如弹幕腾讯狗早喵二符
rxx2.jpg
会导致控制点相对太慢,构成的模型拐弯处内侧可能会出现如下情况
rxx8.jpg
此时应修改参数来解决问题。
c.对于放B或者拍照(文花帖ds),有可能将一条激光打断为两条甚至多条
rxx.jpg
仔细观察打断的激光,他们各自应用了完整的贴图,是一条完整的激光,但是是沿着相同的轨迹在行进
因此可以得到结论:一个牵引弹幕可以牵引多条曲线激光


4.曲线激光的判定点是怎么构成的?
a.是点构成的么?肯定不是,对于速度稍快的牵引弹幕牵引出的控制点间距就较大,显然如果全是点构成的判定对于激光来说也是凹凸不平的,如下图
rxx9.jpg
如果速度更快,甚至有神穿的可能,显然就完全是游戏BUG。
因此曲线激光的判断一定是由N个牵引点的N-1条短线段做判定构成的: QQ截图20141210200938.jpg
(附赠点到线段判定算法)

  1. hit_test_line=function(p,n1,n2,d){//测试点 碰撞线段点1 碰撞线段点1 测试距离
  2.         var a=MATH.dis(p,n1),b=MATH.dis(p,n2),c=MATH.dis(n2,n1),ds=0;
  3.         if(a*a>=b*b+c*c){ds=b}
  4.         else if(b*b>=a*a+c*c){ds=a}
  5.         else{
  6.                 var s=(a+b+c)/2;
  7.                 s=Math.sqrt(s*(s-a)*(s-b)*(s-c));
  8.                 ds=2*s/c;
  9.         }
  10.         if(ds>d){return 0;}
  11.         else{return 1;}
  12. }
复制代码
b.是所有的控制点间线段都有判定么?显然不是,首先,收尾的两段肯定没有判定,否则判断肯定就超出激光模型范围了
同理,对于超宽曲线激光,判定范围减退到收尾第X个点,显然X=判定长度/牵引点平均间距
但其实这样判断也会在拐歪处稍微超出一点点,这就是弹幕腾讯狗早喵那张符小弯的激光外侧特别难擦很容易撞的原因。

大概要关注的点就是这些?具体数据结构应该肯定没问题了

点评

牵引子弹走过的轨迹应该是一个有厚度的曲线集,显然要写出曲线系的解析式比较困难,因此不妨考虑进行数值逼近,构成可以通过走过的N-1个位置之间的线性插值出N-2条首尾相连的梯形,显然这个N取得越大显然精度越高。  发表于 2014-12-10 22:14
论坛的点评不能艾特人啦。。。你这里是微分么,两点距离很近的那样?进行近似代替吧  发表于 2014-12-10 19:57
@drzzm32 是轨迹哦~计算的判定点到控制点线段的距离(控制点连起来就是轨迹嘛)  发表于 2014-12-10 19:54
点到线的呢。。。要求出。。。诶是对顶点进行计算的么? 我倒想计算点到轨迹距离呢。。。  发表于 2014-12-10 19:52
哇哦!期待大触的文字=w=  发表于 2014-12-10 17:46

评分

参与人数 1积分 +4 喵玉币 +10 萌度 +30 收起 理由
drzzm32 + 4 + 10 + 30 嘛这样才够劲呢。。。氛围一下子就起来了

查看全部评分

回复

使用道具 举报

发表于 2014-12-10 17:41:19 | 显示全部楼层
本帖最后由 HHui 于 2014-12-10 17:47 编辑
Darksword 发表于 2014-12-10 17:26
信号处理相关专业的Baka在这里看到FFT莫名感动QwQ 原来还能做滤波以外的事!
用shader来解决平滑扭曲的想 ...

shader的好处就是在于它能够动态加载而不用硬编码,因此对于不同的激光效果可以给予不同的shader进行处理,因此这并不是一个effect的事,而是effect集合的问题了,诚如你所说的,这种方法大概就是一个激光一个fx,不过这都不是什么事,尤其是当嵌入一个interpreter的情况下(比如lua),这样子既降低了耦合同时也能够照顾到软编码与extendibility的需求。

点评

谢谢指教!我会再好好理解一番的!  发表于 2014-12-10 17:45
回复

使用道具 举报

发表于 2014-12-10 17:46:58 | 显示全部楼层
Darksword 发表于 2014-12-10 17:26
信号处理相关专业的Baka在这里看到FFT莫名感动QwQ 原来还能做滤波以外的事!
用shader来解决平滑扭曲的想 ...

另一方面,事实上对于很多商业级别的游戏而言,连effect本身的使用就比较少了,大多数情况下都是直接使用单独的shader来操作,毕竟effect的灵活性并不算很高。越是复杂的游戏它的渲染就更加多样化,不可能存在一个所谓的global-render-solution-in-one-fx(GRSIOF)模型的(当然非常简单的游戏或者直接使用游戏引擎简化的另当别论)。

点评

哇哦。。原来是这样,明白了,任重而道远!  发表于 2014-12-10 17:49
回复

使用道具 举报

发表于 2014-12-10 20:13:53 | 显示全部楼层
这是赠品
刚才搞了个很好玩(误)的http://lrdcq.com/test/webgl/demo4/index2.html 虽然是老物了
回复

使用道具 举报

 楼主| 发表于 2014-12-10 23:53:37 | 显示全部楼层
lrdcq 发表于 2014-12-10 17:40
因为制作过以还原东方曲线激光为目标的小游戏(http://tieba.baidu.com/p/2827270606)
所以自誉对东方中的 ...

感谢分享!!
十分敬佩你的反复实践研究,有理有据不得不服!
顺着你的思路我测试了一下,如下图
test.jpg
这张图撞出了3段,忘保存录像了,下面是用PIX分析撞成两段的结果:
QQ截图20141210230643.jpg
下面是撞出来的一小段的分析。
QQ截图20141210225019.jpg
还有很多截图不方便传了,简单总结下结论。。
1、分段前总顶点数256(254个三角形,128个控制结点),
分段后小的顶点数10(8个三角形,5个结点),大的顶点数226(224个三角形,118个结点),
由消失的结点数128-118-5=5来看,绘制与碰撞检测分离,5个结点为一组进行碰撞拟合判断。
(也许计算方法不对,我没有细想。。)
2、每一段的纹理都是0-1重新取平均的,如5个结点的纹理横坐标分别是(0,0.25,0.5,0.75,1)
3、每一段不同时绘制!且新分离的激光,后端激光最后绘制!
关于这点我试着凭经验解释一下,不一定对。
①激光本身顶点数巨大,如果按相同纹理批处理绘制的话,几十条激光会共同绘制会超出预设的顶点最大缓存值,画不出来。因此每条激光都是独立的。
②后段激光并不紧跟着前段激光,而是在其他激光都绘制完再绘制,仿佛诞生了一个新激光一样。如果是直接分裂,显然应该前后的绘制顺序紧密相连,但是,我并不认为会重新生成新的控制点队列。头结点还是唯一的。
因此我推测:控制点序列与绘制顶点序列分离,绘制部分只需确定各段首结点(不一定是控制头)的位置以及该段长度,而控制点序列则应该作为一种游戏实际逻辑体存在,并且5结点作为一个碰撞检测部分。当碰撞分段后,前段直接缩减段长,同时new一个从第二段段首开始的新的绘制体,并且放到绘制队列的最后。
如此一来,绘制和逻辑部分较好的分离了。
于是,一个逻辑体对应N个不同的绘制体,一个绘制体对应M个effect。。。
天哪,我要好好重写我的架构了,收获巨大。。。


点评

思路是大家提供的啊=w= 版主提示了可以擦激光弹,你提示了激光可以分段(我都没意识到)。不过也就天邪鬼能这么做了,其他作miss会消弹呢  发表于 2014-12-11 01:16
屌!彻底明晰了!题外话:擦,忘了可以撞断激光,我在文花帖DS里用相机剪了好久才剪出一个看着舒服的激光。。。。  发表于 2014-12-11 00:24
回复

使用道具 举报

发表于 2014-12-14 09:32:18 | 显示全部楼层
lrdcq 发表于 2014-12-10 17:40
因为制作过以还原东方曲线激光为目标的小游戏(http://tieba.baidu.com/p/2827270606)
所以自誉对东方中的 ...

真要算的话曲线激光第一次出现大概是在妖妖梦……蕾迪之类的

点评

喔,对。。。。。蕾迪的那个我也撞过。。。。  发表于 2014-12-14 17:12
四面的骚灵姐妹也有曲线激光……有判定的那种……我就撞过  发表于 2014-12-14 16:08
是的我也是这么认为的~!震撼到了,不过当时没有算作物理判定,只是特效~  发表于 2014-12-14 15:56
回复

使用道具 举报

发表于 2014-12-22 19:38:45 | 显示全部楼层
关于判定.d2d也提供了另一种思路.

d2d中有直接对于Geometry对象的定义.
可以自己把所有的弹幕的判定域定义成geometry然后在一个覆盖屏幕的geometry对象里执行combine命令.这样所有的判定域就都在一张图里了(我表达不好,大概意思是这样.)这时候再用角色坐标参照刚刚的geometry对比直接看出是否在定义域中.
曲线激光可以用比较复杂的Geometry,通过加点,连线的方法实现.
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 少女注册中

本版积分规则

合作与事务联系|无图版|手机版|小黑屋|喵玉殿

GMT+8, 2025-10-31 11:21

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表