利用GPU實現翻頁效果

2021-08-07 13:13:10 字數 2031 閱讀 3404

有一段時間沒有更新部落格了,在考慮寫點什麼的時候正好趕上了這個月我的書《unity 3d指令碼程式設計》又加印了。因此寫篇小文聊聊利用shader來實現翻書的效果吧。

雖然本文是這個週日下午雨天的臨時起意,而演示的demo也有廣告之嫌,但是還是希望各位看官如果覺得有收穫的話能夠點讚支援。

之前看到過類似「unity怎麼實現類似書本的翻頁效果」之類的問題,答案大多是利用現成的外掛程式來實現,這聽上去似乎並沒有實際上解決這個問題。後來又看到過一些更靠譜的解決方案例如利用ugui的vertex modifier修改頂點、或者使用骨骼動畫。

等一下,修改頂點?

修改網格資料這事沒有必要一定要在cpu上進行,我們把這活放到gpu上讓它來實現頂點的修改是不是更有趣一點呢。

事實上我們只需要乙個plane,在vs中根據某個屬性來修改它頂點的x值和y值。

而乙個最簡單的修改方案,就是根據玩家的翻頁角度theta來更改頂點的座標。

float4 flip_book(float4 vertex)

那麼theta的值是怎麼來的呢?一頁書的翻動角度在[0,180]之間,變成弧度值就是[0,π],因此我們只需要在指令碼中計算玩家拖動的距離和總長度的乙個比例ratiovalue,將這個ratiovalue傳遞給vs後再和π相乘就求得了theta。

因此,在c#指令碼中就需要使用這幾個介面了。

idraghandler, ipointerdownhandler, ipointeruphandler
這樣,在只經過乙個pass的情況下,翻頁的初步效果已經實現了。

但是如果翻過90°,可以發現此時不僅第二頁沒有內容,而且第一頁的背面也是空的。

因此,我們還需要另外2個pass分別渲染第一頁的背面和第二頁的內容。

ok,接下來我們就來完成第二個pass。

fixed4 frag_flip_back (v2f i) : sv_target

//翻起來的背面

pass

其實很簡單,只需要剔除正面,修改一下uv,然後正常的採用背面的紋理_backtex就ok了。

可以看到當書頁被翻過90°之後,書頁的背面已經能夠正確的顯示了。

之後就是最後乙個pass了,我們用這個pass來顯示第二頁的內容。其實這個pass很簡單,仍然是只需要正常的採用背面的紋理_backtex就ok了。但是這裡要注意乙個問題,那就是深度的問題。還記得第乙個pass嗎?第乙個pass繪製了第一頁的內容。但是最後乙個pass同樣也要繪製頁面的內容,而且預設情況下深度會覆蓋第乙個pass繪製的內容。

因此,我們要在最後乙個pass中正確的處理深度問題,所以我在這裡使用了offset。

//第二頁

pass

ok,shader部分完工了。之後我們只需要在c#指令碼中簡單的確定當前的頁數,來設定相應的前頁的tex和後頁的tex給shader。

最後的結果大概是這個樣子的。

當然,這個demo的**各位可以在這裡獲取:

chenjd/unity-flip-book-with-shader

-eof-

最後打個廣告,歡迎支援我的書《unity 3d指令碼程式設計》

Iphone實現簡單翻頁效果

經常看到iphone的軟體向上向下翻頁面的效果,其實這個很簡單,已經有封裝好的相關方法處理。首先設定動畫的相關引數 uiview beginanimations curl context nil uiview setanimationduration 1.25 時間 uiviewsetanimati...

翻頁效果的動畫實現

這篇文章是為在 的翻頁的實現的加入了一點點個人的優化,當然是在班門弄斧。本來應該把實現的 傳上來的,但是公司新出了規定。作了資訊保安處理,usb和上傳全作了限制,所有的 弄不出來,為把我的自動彈回的實現原理說一下。主要就是使用scroller 的彈回效果 首先重寫翻頁類的如下方法。public vo...

ios動態效果實現翻頁 iOS實現日曆翻頁動畫

1.日曆 簡單描述原理 2.翻頁動畫 重點 最終的效果如下圖 圖中沿四個對角的翻頁動畫,代表對應方向手勢的滑動 1.日曆 要實現乙個日曆,其實原理很簡單,我們只要知道三個資料 1.今天是哪一天 2.這個月的第一天是星期幾 哪天 3.這個月總共有多少天 1.獲取今天是哪一天 這個應該是最簡單的 nsd...