HairStrandPlugin的迭代總結(jié)
來(lái)源:
52vr |
責(zé)任編輯:傳說(shuō)的落葉 |
發(fā)布時(shí)間: 2019-06-13 08:17 | 瀏覽量:
這篇文章介紹了HairStrandPlugin在迭代過(guò)程中遇到的一些問(wèn)題以及思考。
背景
HairStrandPlugin的1.0版本推出到現(xiàn)在也已經(jīng)過(guò)去快一個(gè)月了,在這段期間我也一直在不停調(diào)試這個(gè)插件以及模擬代碼,在此記錄一下迭代過(guò)程中碰到的一些問(wèn)題以及對(duì)應(yīng)的思考。
代碼層次的迭代
長(zhǎng)度約束(Distance Constraint)邏輯迭代
問(wèn)題描述
在參考TressFX的論文和代碼過(guò)程中,我個(gè)人收獲很大,但是開(kāi)源的TressFX似乎還是藏起了一些黑科技。誠(chéng)然,在系統(tǒng)偏向穩(wěn)定的情況下,TressFX的效果非常好,而且針對(duì)于中短發(fā)的約束收斂也做的很不錯(cuò),此外還使用GPU進(jìn)行多線程模擬,大大提升了運(yùn)算效率。
但是略有蛋疼的是——在不太穩(wěn)定的系統(tǒng)下,TressFX針對(duì)于長(zhǎng)度的收斂還是不夠的,在TressFXSimulation.hlsl中能夠找到如下代碼:
[代碼]:
01 |
void ApplyDistanceConstraint(inout float4 pos0, inout float4 pos1, float targetDistance, float stiffness = 1.0) |
02 |
{ |
03 |
float3 delta = pos1.xyz - pos0.xyz; |
04 |
float distance = max(length(delta), 1e-7); |
05 |
float stretching = 1 - targetDistance / distance; |
06 |
delta = stretching * delta; |
07 |
float2 multiplier = ConstraintMultiplier(pos0, pos1); |
08 |
09 |
pos0.xyz += multiplier[0] * delta * stiffness; |
10 |
pos1.xyz -= multiplier[1] * delta * stiffness; |
11 |
} |
這意味著在頭發(fā)高速運(yùn)動(dòng)的過(guò)程中(例如角色急速?zèng)_刺、墜下山崖等),發(fā)絲依然有可能被拉長(zhǎng),以下的截圖來(lái)自原生的TressFX的可執(zhí)行文件。
可以看到當(dāng)模型進(jìn)行位移時(shí),頭發(fā)還是出現(xiàn)了拉扯的情況。這還僅僅是小位移,聯(lián)想到古墓麗影中勞拉運(yùn)動(dòng)速度比這高的情況還是比較多的,因此大概可以推測(cè)還有黑科技沒(méi)有批露出來(lái)。
誠(chéng)然這種狀況可以通過(guò)調(diào)節(jié)例如迭代次數(shù)、Substeptime來(lái)進(jìn)行改善,但畢竟僅僅是改善而已,無(wú)法徹底解決。而且單一的調(diào)整上面的數(shù)值還會(huì)影響整個(gè)發(fā)絲的質(zhì)感,工作量還是比較大。
插件在《隱龍傳:影蹤》的實(shí)裝過(guò)程也遇到了這個(gè)問(wèn)題。由于《隱》是一個(gè)動(dòng)作游戲,角色的運(yùn)動(dòng)速度有時(shí)會(huì)很高(例如主角在空中的重下劈速度達(dá)到了100m/s),因此在最初的實(shí)裝中頭發(fā)不可避免地被拉長(zhǎng)了。
解決方案
最終的解決方案是在進(jìn)行發(fā)絲設(shè)計(jì)時(shí)先離線計(jì)算出各個(gè)粒子與發(fā)根粒子的穩(wěn)定距離,然后在模擬的過(guò)程中檢測(cè)距離的大小關(guān)系。如果距離過(guò)大了,則強(qiáng)制將粒子推至穩(wěn)定距離的位置。
這樣的方案能夠是Iteration數(shù)量大大減少,目前來(lái)看針對(duì)于每根發(fā)絲來(lái)說(shuō)只需要進(jìn)行一次Iteration即可。而且發(fā)絲的表現(xiàn)效果也更加穩(wěn)定,當(dāng)主角在山崖間快速跳躍的時(shí)候發(fā)絲也并不會(huì)被拉長(zhǎng)。
上圖是初次實(shí)裝后的效果,可以看到長(zhǎng)度被約束到了一個(gè)穩(wěn)定值(鋸齒狀的震顫來(lái)源于阻尼沒(méi)有調(diào)整好,大家無(wú)視即可……)。
LOD的實(shí)現(xiàn)
由于發(fā)絲的模型是依照樣條曲線來(lái)進(jìn)行動(dòng)態(tài)構(gòu)建的,因此導(dǎo)致發(fā)絲的網(wǎng)格會(huì)比較密,這樣一來(lái)對(duì)GPU的消耗就有可能比較大(雖然我知道這個(gè)插件主要是CPU殺手……)。
因此花了一些精力用于動(dòng)態(tài)LOD的構(gòu)建了,難度不大也沒(méi)什么好說(shuō)的,距離越遠(yuǎn)則網(wǎng)格越稀疏而已……
發(fā)絲插值
工具鏈問(wèn)題
發(fā)絲插值是一個(gè)很蛋疼的事,而這個(gè)蛋疼不是來(lái)源自技術(shù)而是來(lái)源自工具鏈。
由于《隱》的開(kāi)發(fā)團(tuán)隊(duì)人數(shù)比較少,因此很多時(shí)候都只能使用現(xiàn)有的工具來(lái)進(jìn)行開(kāi)發(fā)。由于模型師的習(xí)慣,針對(duì)于發(fā)型的設(shè)計(jì)是使用Maya的Shave插件,然后直接導(dǎo)出曲線數(shù)據(jù),再在UE4中進(jìn)行導(dǎo)入操作。
但是這樣一來(lái),發(fā)絲與發(fā)絲之間的拓?fù)浣Y(jié)構(gòu)就被破壞了。導(dǎo)出之后的曲線數(shù)據(jù)不帶有“哪三根曲線是在同一個(gè)三角面上”的信息,因此原本想好的三角面插值就難以實(shí)現(xiàn)了。
這個(gè)問(wèn)題嘛……實(shí)際上不隸屬與這個(gè)插件,難度也不大,但是由于涉及到工具鏈改變所帶來(lái)的成本因此暫時(shí)就這樣擱下了。目前的發(fā)絲插值是針對(duì)發(fā)絲插值總數(shù)進(jìn)行隨機(jī)的兩兩發(fā)絲配對(duì),然后在渲染的時(shí)候在這兩根發(fā)絲之間進(jìn)行插值即可。
插值發(fā)絲的碰撞結(jié)算
這個(gè)問(wèn)題目前也還沒(méi)解決。發(fā)絲的插值的出現(xiàn)的目的主要是用于解決模擬發(fā)束太少而導(dǎo)致發(fā)絲稀疏的問(wèn)題,換句話說(shuō),可能針對(duì)于類似于馬尾之類的簡(jiǎn)單發(fā)型,只需要四五根發(fā)絲進(jìn)行模擬結(jié)算,然后在這些發(fā)絲之間進(jìn)行插值即可,這樣能夠大大節(jié)省CPU運(yùn)算時(shí)間。
但是這樣的潛在問(wèn)題在于如果這幾根發(fā)絲之間有一些進(jìn)行了碰撞結(jié)算而其他的沒(méi)有進(jìn)行碰撞結(jié)算該怎么辦?如果直接進(jìn)行插值的話勢(shì)必會(huì)導(dǎo)致有一些發(fā)絲直接進(jìn)入了碰撞體內(nèi),但是如果針對(duì)于插值發(fā)絲再進(jìn)行碰撞結(jié)算則一來(lái)計(jì)算量將增大不少,二來(lái)只有碰撞結(jié)算而無(wú)長(zhǎng)度約束將導(dǎo)致發(fā)絲的極度詭異的狀況。
目前來(lái)看,插件提供的插值功能只適用與單側(cè)馬尾這一類走向統(tǒng)一,發(fā)束簡(jiǎn)單的發(fā)型。如果日后能夠解決三角面插值的問(wèn)題的話,這個(gè)問(wèn)題也將得到一定程度的解決。
線條網(wǎng)格(Line Primitive)
不同于三角網(wǎng)格,Line Primitive是用于線條的繪制。隨著現(xiàn)在機(jī)器性能的提升,大量的Line Primitive也不再是幻想了。
在這個(gè)迭代后,開(kāi)發(fā)者可以選擇是否使用LinePrimitive進(jìn)行模擬,并且也可以工作正常。但是可以預(yù)見(jiàn)的問(wèn)題是:除非插值發(fā)絲的問(wèn)題得到解決,否則使用LinePrimitive勢(shì)必帶來(lái)極高的CPU運(yùn)算量。
或者……如果與TressFX一樣,將模擬邏輯寫到GPU上,應(yīng)該也能解決這個(gè)問(wèn)題。
質(zhì)點(diǎn)系統(tǒng)
這個(gè)東西其實(shí)很簡(jiǎn)單也不需要多說(shuō)——越靠近發(fā)根的粒子質(zhì)量越大,越遠(yuǎn)離發(fā)根的粒子質(zhì)量越小。這樣一來(lái)在進(jìn)行物理模擬的時(shí)候?qū)⒏诱鎸?shí)。
下一步的計(jì)劃
GPU!GPU!GPU!
工具鏈!工具鏈!工具鏈!
GrowMesh的對(duì)應(yīng)邏輯。
-
分享到:
相關(guān)文章
網(wǎng)友評(píng)論
您需要登錄后才可以發(fā)帖 登錄 | 立即注冊(cè)
關(guān)閉
- 用戶名:
- 密 碼:
- 驗(yàn)證碼: 看不清? 點(diǎn)擊更換
- 忘記密碼?
全部評(píng)論:0條
推薦
熱門