Shader從入門到跑路:實作螢幕扭曲效果
前言
這次來實作上章提到的螢幕扭曲效果,需要用到這張圖(文章最後提供連結)
5.1位移圖
先稍微花點時間思考一下這張圖怎麼用。
5.2畫素取樣偏移方法
紋理中紅色的部分代表uv在x軸上的位移,而綠色則表示uv在y軸上的位移。
正文
為此我們的shader需要一個額外的二維紋理屬性用以儲存位移圖,以及一個magnitude屬性,用來調整我們的扭曲效果的強度。以上一章寫好的shader為基礎,加入以下程式碼:
- Properties{
- _MainTex("Main Text", 2D) = "white" {}
- _DisplacementTex("Displacement Texture", 2D) = "white" {}
- _Magnitude("Magnitude", Range(0, 1)) = 0
- }
新增一個二維的位移紋理,接著加上一個magnitude拖動條。記得在使用之前要先在CGPROGRAM裡面定義這些屬性:
sampler2D _MainTex;
sampler2D _DisplacementTex;
float _Magnitude;
接下來在frag函式裡面的運算可能有些複雜,看不懂記得來回看多幾遍:
- float4 frag(v2f i) : SV_Target
- {
- float2 disp = tex2D(_DisplacementTex, i.uv).xy;
- disp = ((disp * 2) - 1) * _Magnitude;
- float4 color = tex2D(_MainTex, i.uv + disp);
- return color;
- }
首先第一步是定義了一個float2的disp來對位移圖進行取樣,下面一行做了一些數學上的轉換。因為從uv中獲取的值是介於0到1之間的,這樣的數值算出來的扭曲效果會不明顯,所以要讓值定位到-1到1之間,讓介面有飄來飄去的感覺,並乘上magnitude讓我們可以控制強度。最後,將我們的主紋理取樣為法向量,但這次,我們將uv加上位移的量
然後回到材質的皮膚,位移圖拖到displacement texture的位置,然後拖動magnitude的拖動條,得到下面的效果
5.3熱起來香菜都扭曲
其實如果你直接把這個效果放到遊戲裡面,也可以製造一些火焰山的感覺,熱到扭曲就是說的這個,連周邊的空氣都要與影像混合在一齊。
但是要手動拖動magnitude畢竟還是太遜了,我們不能給程式猿丟臉,得用程式碼從外部改變內部狀態。
我們可以用unity提供的一個叫_Time的引數,這個引數是寫在了UnityCG.cginc檔案裡的。_它有很多用法,比如_Time.x返回的是當前的時間的20分之一,_Time.y則是當前時間等等。
https://docs.unity3d.com/Manual/SL-UnityShaderVariables.html
在告訴你解法之前,我強烈建議你先遮住這一段下面的程式碼部分(伸手黨的同學可以跳過這一部分),自己好好想一想用_Time引數怎麼實現動態扭曲。首先思考一下剛才我們是怎麼實現扭曲的。我們將位移圖的取樣結果新增到uv上,在對主紋理(在這裡就是螢幕)取樣時使用偏移過的uv來進行取樣,便會得到渲染效果。(沒懂?劃上去看程式碼,依然沒懂翻前一章看OnRenderImage的程式碼)那麼,如果扭曲是動態的,就是說,一開始,uv值就隨著時間的推移而改變,我們在對位移圖進行取樣的時候,uv值就已經改變過了。到此為止,思路上的提示我已經給得差不多,現在到你思考了。
動態扭曲的程式碼:
- float4 frag (v2f i) : SV_Target
- {
- float2 distuv = float2(i.uv.x + _Time.x * 2, i.uv.y + _Time.x * 2);
- float2 disp = tex2D(_DisplacementTex, distuv).xy;
- disp = ((disp * 2) - 1) * _Magnitude;
- float4 col = tex2D(_MainTex, i.uv + disp);
- return col;
- }
隨便給magnitude設一個值就可以看到這樣的動態扭曲效果:
5.4美麗的香菜
位移圖連結:
https://pan.baidu.com/share/init?surl=dtMOiK5WstENYspRUyv0JQ
提取碼:ewjq
相關閱讀:
Shader從入門到跑路:樸實無華的圖形學基礎
Shader從入門到跑路:自定義紋理輸入
Shader從入門到跑路:螢幕後處理效果
作者:俊銘
https://zhuanlan.zhihu.com/p/86237202
相關文章
- Shader從入門到跑路:螢幕後處理效果
- Shader從入門到跑路:自定義紋理輸入
- Docker實戰-從入門到跑路Docker
- Shader從入門到跑路:樸實無華的圖形學基礎
- babel從入門到跑路Babel
- Shader從入門到跑路:顏色自定義輸出、紋理取樣
- Kotlin從入門到跑路(一)Kotlin
- Vue入門到跑路---VuexVue
- 《Golang 從入門到跑路》之開發環境搭建Golang開發環境
- Linux Shell 從入門到刪除根目錄跑路指南Linux
- Linux Shell從入門到刪除根目錄跑路指南Linux
- VC實現螢幕變暗效果 (轉)
- GraphQL 從入門到實踐
- Locust 從入門到實戰
- Redis從入門到實踐Redis
- Redis 從入門到實戰Redis
- nginx從入門到實踐Nginx
- 平板入門第四講:從螢幕引數選平板電腦
- Linux 從入門到跑路第二十一講 -- 字串擷取Linux字串
- scala 從入門到入門+
- makefile從入門到入門
- Docker從入門到實戰pdfDocker
- Tessellation Shader的GLSL入門實現: 平面
- Uni-app從入門到實戰APP
- Docker從入門到動手實踐Docker
- GDB除錯-從入門到實踐除錯
- 麒麟作業系統 (kylinos) 從入門到精通作業系統
- kafka從入門到關門Kafka
- LVGL庫入門教程01-移植到STM32(觸控式螢幕)
- 資料庫運維初入門-SQL Server入門到跑路002-初使用資料庫運維SQLServer
- iOS逆向安防從入門到實戰iOS
- 小程式從入門到實戰系列(一)
- 日誌實時分析:從入門到精通
- MongoDB一篇從入門到實戰MongoDB
- Python Type Hints 從入門到實踐Python
- webpack:從入門到真實專案配置Web
- Thymeleaf從入門到精通
- LESS從入門到精通