渲染到ui_虚幻4渲染编程(UI篇)【第二卷:程序化UI特效-[1]】
MY BLOG DIRECTORY:
小IVan:專題概述及目錄?zhuanlan.zhihu.comINTRODUCTION:
當遇見某些特殊需求,比如對游戲效果有很多變化的要求,這時使用靜態的貼圖就不太適合了,這時候就需要實時計算繪制出來的數據。下面就來總結一些常用的程序化UI效果,下面的效果將全部使用公式計算的方式生成,不使用一張貼圖。
MAIN CONTENT:
【1】律動波形
使用
這個簡單的公式,把圖像畫出來然后重復一次相減即可得到一條細線。然后再重疊第二個波上去,即可得到更有變化的效果。我這里只疊加了兩個波,如果還想更豐富還可以繼續往上疊。
上面的材質連線是不是太亂了呢,而且如果想做更復雜的疊波就比較困難了,材質編輯器能把人頭連暈,所以我下面封裝了一個框架來幫助我解決這個事情。
void GetWaveFeild(out float Up, out float Down, in float A, in float T, in float WaveWidth, in float2 UV, in float time) {float TwoPI = 3.1415926 * 2;Up = A * sin(TwoPI / T * UV.x + time);Down = A * sin(TwoPI / T * UV.x + time) + WaveWidth; }float GetWaveColor(in float FeildUp, in float FeildDown, in float UVY) {UVY = UVY - 0.5;return step(UVY, FeildDown) - step(UVY, FeildUp); }float CalculateWave(in float2 UV, float A, float T, float WaveWidth, in float time) {float Output = 0;float WaveFeildUp = 0;float WaveFeildDown = 0;// If you need more wave feild. Adding them here!float WaveUp_01 = 0;float WaveDown_01 = 0;GetWaveFeild(WaveUp_01, WaveDown_01, A, T, WaveWidth, UV, time);float WaveUp_02 = 0;float WaveDown_02 = 0;GetWaveFeild(WaveUp_02, WaveDown_02, A, T * 2, WaveWidth, UV, time * -1.2);float WaveUp_03 = 0;float WaveDown_03 = 0;GetWaveFeild(WaveUp_03, WaveDown_03, A * 5, T * 0.2, WaveWidth, UV, time * 8);//Wave field blend operationsWaveFeildUp = WaveUp_01 + WaveUp_02 * WaveUp_03 + WaveUp_03 * 0.1;WaveFeildDown = WaveDown_01 + WaveDown_02 * WaveDown_03 + WaveDown_03 * 0.1;Output = GetWaveColor(WaveFeildUp, WaveFeildDown, UV.y);return Output; }float RenderWave(in float2 UV, in float t) {float Output = 0;Output = CalculateWave(UV, 0.1, 0.2, 0.02, t * 2);return Output; } //return RenderWave(UV, t);最后的效果:
我這里只疊了三層,其實還可以疊更多。我來稍微講解下這個框架。首先是要計算出波場,上波場和下波場,上下波場相減就能得到波的細線。GetWaveColor便是相減上下波場。我們如果要混合不同波,只能在計算波場的時候混合,在GetWaveColor之前。計算波場有很多種混合方式,相加相減相乘等。
把自變量x變成整數就可以得到柱狀波形
如果不和Y的絕對值比較的話,可以得到一邊的效果
【2】技能冷卻
先用代碼畫個圓然后畫冷卻線
圓
step(distance(uv, float2(0.5, 0.5)) , R);冷卻線
step(H, uv.y );如果想要制作扇形效果,可以使用極坐標的方法,先把UV變換到中心點
然后用極坐標判斷即可
float SkillTime(float2 uv, float R, float Radius) {float2 centeruv = uv - 0.5f;float cos = dot(normalize(centeruv), float2(1,0));return step(Radius, cos); }【3】旋轉扭曲
使用旋轉矩陣變換一下就好了,還是非常簡單的
請無視gif壓縮產生的馬賽克float2 RotateUV(float2 uv,float2 center, float angle) {float PI = 3.1415927f;float Ang = angle * (2.0f * PI/ 360.0f);float2 RowX = float2(cos(Ang), -sin(Ang));float2 RowY = float2(sin(Ang), cos(Ang));float ArgOne = dot(RowX, uv - center);float ArgTwo = dot(RowY, uv - center);return float2(ArgOne, ArgTwo) + center; }有了最基礎的旋轉,就可以在此基礎上做些其它效果了
代碼如下:
float2 Twirl(float2 uv, float2 centeroffset, float strenth) { //Transform uv to centeruv = uv - float2(0.5, 0.5);//Offset the uv centerfloat2 delta = uv - centeroffset;float angle = strenth * length(delta);float x = cos(angle) * delta.x - sin(angle) * delta.y;float y = sin(angle) * delta.x + cos(angle) * delta.y;float RowX = x + centeroffset.x;float RowY = y + centeroffset.y;return float2(RowX, RowY); }【4】SubUVAnimation
把水印P掉即可使用SubUVAnimation其實是經常會使用到的東西,原理非常簡單,就是整塊整塊挪動UV,雖然很簡單但是很容易出錯。
float2 SubUV(float t, float2 coord) {float SubUVX = 4;float SubUVY = 4;float Time = floor(t);float row = floor(Time / SubUVX);float cloum = Time + row * SubUVX;float2 UV = coord + float2(cloum, row);UV.x /= SubUVX;UV.y /= SubUVY;return UV; }首先需要確保UV的方向和貼圖的Animation方向是相同的
float row = floor(Time / SubUVX); float cloum = Time + row * SubUVX;Cloum的數量是Row的橫軸格數的倍數加當前橫軸位置。
這里的UV偏移是非常大的,需要把UV限制到0-1所以除以X和Y的SubUV數目,這里一定是最后縮放到0-1,因為如果先縮放到0-1會產生累積誤差。最后可以再采一次time+1時候的圖像和當前圖像做插值,這樣來做幀緩存讓圖像更加順滑。
SUMMARY AND OUTLOOK:
Enjoy it!
NEXT:
YivanLee:虛幻4渲染編程(UI篇)【第三卷:程序化UI特效-[2]】
總結
以上是生活随笔為你收集整理的渲染到ui_虚幻4渲染编程(UI篇)【第二卷:程序化UI特效-[1]】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: roobo机器人怎么唱歌_可爱的小伙伴
- 下一篇: 智慧树python程序设计基础山东联盟期