新緩動系統(tǒng)

很久前提到過一個“如何繪制跨屏長條”的問題,當(dāng)時的思路是:
A. 分析長條的開頭節(jié)點/結(jié)尾節(jié)點是否在屏幕上;
B. 開頭節(jié)點不在屏幕上 -> 使用屏幕底部對應(yīng)DTime(變速時間)的插值節(jié)點替換“開頭節(jié)點”;
C. 結(jié)尾節(jié)點不在屏幕上 -> 使用屏幕頂部對應(yīng)DTime的插值節(jié)點替換“結(jié)尾節(jié)點”;
D. 繪制。
當(dāng)需要繪制的跨屏長條是曲線長條時,上述的插值操作便會涉及到個人稱之為“曲線拆分”的問題。
一、 曲線拆分問題
以下是個人對曲線拆分問題能想到的最簡單的描述。
現(xiàn)有一條曲線A:(x1,y1)--<type1>--(x2,y2),即用類型為type1的曲線連接(x1,y1)和(x2,y2)兩個點。在這條曲線途經(jīng)的點中取一點(x3,y3),繪制曲線B:(x1,y1)--<type2>--(x3,y3)--<type3>--(x2,y2)。試問如何規(guī)定type2和type3,才能使曲線B與曲線A重合?
二、常規(guī)思路
如果type1、type2、type3代表的都是“直線線段”,曲線A和曲線B就一定重合。
因此,在譜面加載階段通過插值法將曲線A轉(zhuǎn)換為如下形式的折線段:
(x1,y1)--<Linear>--(x3,y3)--<Linear>--(x4,y4)······(xn,yn)--<Linear>--(x2,y2)
即可實現(xiàn)(對該折線段的)任意次無損拆分。
三、新緩動系統(tǒng)
目前,我們正在嘗試?yán)肎PU的并行計算能力來優(yōu)化物件渲染,對于長條而言優(yōu)勢就是可以以極低的成本換取極高的緩動精度,但問題就是將物件信息上傳到VRAM需要一定的成本。
進行這種非必需的優(yōu)化講求的就是一個極致。“轉(zhuǎn)換為折線”這一過程存在著一定的精度損失,也會造成長條節(jié)點數(shù)量的暴增,相對應(yīng)地GPU處理單根長條需要繪制多個梯形也存在著一定的額外開支()
為此,以下介紹一種不轉(zhuǎn)換為折線也能完成曲線拆分的方案。
A. 根據(jù)緩動API的封裝習(xí)慣,緩動曲線使用ratio表示:ratio∈[0,1],f(ratio)∈[0,1]
B. 初始狀態(tài)提供如下幾種緩動曲線:
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. 傳入的數(shù)據(jù)可以簡化為x1、y1、x2、y2初始類型、頭部ratio、結(jié)尾ratio七個。
設(shè)頭部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)十個參數(shù)。
參數(shù)個數(shù)最好能控制在8個以內(nèi),那么x方向處理成類似Project SEKAI或者Chunithm的“定軌變寬”風(fēng)格,就可以用位段將(左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個。