欢迎光临散文网 会员登陆 & 注册

新缓动系统

2023-08-20 03:21 作者:Fuxfantx  | 我要投稿

很久前提到过一个“如何绘制跨屏长条”的问题,当时的思路是:

A. 分析长条的开头节点/结尾节点是否在屏幕上;

B. 开头节点不在屏幕上 -> 使用屏幕底部对应DTime(变速时间)的插值节点替换“开头节点”;

C. 结尾节点不在屏幕上 -> 使用屏幕顶部对应DTime的插值节点替换“结尾节点”;

D. 绘制。

当需要绘制的跨屏长条是曲线长条时,上述的插值操作便会涉及到个人称之为“曲线拆分”的问题。


一、 曲线拆分问题

以下是个人对曲线拆分问题能想到的最简单的描述。

现有一条曲线A:(x1,y1)--<type1>--(x2,y2),即用类型为type1的曲线连接(x1,y1)和(x2,y2)两个点。在这条曲线途经的点中取一点(x3,y3),绘制曲线B:(x1,y1)--<type2>--(x3,y3)--<type3>--(x2,y2)。试问如何规定type2和type3,才能使曲线B与曲线A重合?


二、常规思路

如果type1、type2、type3代表的都是“直线线段”,曲线A和曲线B就一定重合。

因此,在谱面加载阶段通过插值法将曲线A转换为如下形式的折线段:

(x1,y1)--<Linear>--(x3,y3)--<Linear>--(x4,y4)······(xn,yn)--<Linear>--(x2,y2)

即可实现(对该折线段的)任意次无损拆分。


三、新缓动系统

目前,我们正在尝试利用GPU的并行计算能力来优化物件渲染,对于长条而言优势就是可以以极低的成本换取极高的缓动精度,但问题就是将物件信息上传到VRAM需要一定的成本。

进行这种非必需的优化讲求的就是一个极致。“转换为折线”这一过程存在着一定的精度损失,也会造成长条节点数量的暴增,相对应地GPU处理单根长条需要绘制多个梯形也存在着一定的额外开支()

为此,以下介绍一种不转换为折线也能完成曲线拆分的方案。

A. 根据缓动API的封装习惯,缓动曲线使用ratio表示:ratio∈[0,1],f(ratio)∈[0,1]

B. 初始状态提供如下几种缓动曲线:

Linear -> f(x) = x

InSine -> f(x) = sin( x*π/2 )

OutSine -> f(x) = 1 - sin( x*π/2 )

C. 取ratio=m的一点插值:

InSine type2 -> f(x) = sin( x*π/2m )

InSine type3 -> f(x) = sin( x*π/2(1-m) + m/(1-m) )

OutSine type2 -> f(x) = 1 - sin( x*π/2m )

OutSine type3 -> f(x) = 1 - sin( x*π/2(1-m) + m/(1-m) )

D. 传入的数据可以简化为x1、y1、x2、y2初始类型、头部ratio、结尾ratio七个。

设头部ratio=m,尾部ratio=n,曲线类型为InSine f(x)=sin(x*π/2),则先拉伸为原始曲线的1/(n-m)倍,再向左平移m/(n-m)单位长度,使新曲线g(x)满足g(0)=f(m)、g(1)=f(n),那么

InSine g(x) = sin( x*π/2(n-m) + m/(n-m) )

OutSine g(x) = 1 - sin( x*π/2(n-m) + m/(n-m) )

E. 验证:

头部ratio=0、尾部ratio=1 -> InSine g(x) = sin( x*π/2 ) -> 原始曲线

头部ratio≠0、尾部ratio=1 -> InSine g(x) = sin( x*π/2(1-m) + m/(1-m) ) -> type3

头部ratio=0、尾部ratio≠1 -> InSine g(x) = sin( x*π/2n ) -> type2


渲染曲线长条时,每根长条需传入左easetype、左x1、左x2、右easetype、右x1、右x2、y1、y2、ratio(y1)、ratio(y2)十个参数。

参数个数最好能控制在8个以内,那么x方向处理成类似Project SEKAI或者Chunithm的“定轨变宽”风格,就可以用位段将(左x1、左x2、左easetype)合并到一个float,(右x1、右x2、右easetype)同理。

通过在逻辑中固定屏幕底部y1和屏幕顶部y2,可以将y1和ratio(y1)合并为yr1:

yr1>1 : 该值表示y1、ratio(y1)=0

yr1≦1:该值表示ratio(y1),y1为逻辑中固定的屏幕底部y1

同理,y2和ratio(y2)也可以合并为yr2:

yr2>1 : 该值表示y2、ratio(y2)=1

yr2≦1:该值表示ratio(y2),y2为逻辑中固定的屏幕顶部y2

通过这样一轮合并,每根曲线长条的传参量便控制在了4个。

新缓动系统的评论 (共 条)

分享到微博请遵守国家法律