您好,登錄后才能下訂單哦!
這篇文章主要介紹了Unity3D如何實現(xiàn)舊電視濾鏡shade,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
既然是要實現(xiàn)舊電視的后處理效果,那么只要回憶一下那些古舊的電視的顯示效果然后進行模擬就可以了。
1.首先那種大頭電視一般屏幕有一些曲率,并不是完全的一個平面,而且一般是向外凸起,這種凸起會造成中間的顯示區(qū)域會比原來更近一些,邊緣的顯示區(qū)域會比原來更遠一些。這種效果我們直接用簡單的二次函數(shù)來實現(xiàn)。
2.那種老舊電視會有不斷運動的噪聲,我們直接使用噪聲函數(shù)加上時間變量來實現(xiàn)。
3.屏幕上會有一些條紋效果,這種周期性的條紋效果一般用三角函數(shù)來實現(xiàn)。
當然不可能模擬的完全準確。。也沒有完全準確一說。畢竟每個人對老電視的印象也是不同的,我這里也只是把我印象里的效果來實現(xiàn)一下,看起來差不多就行了。
首先實現(xiàn)第一點,實現(xiàn)屏幕的曲率。
我們采用的方法是先計算該uv坐標離(0.5,0.5)的距離,這個(0.5,0.5)的uv坐標其實可以看成屏幕的中心點。計算出距離之后根據(jù)這個距離的大小來對uv進行偏移,這其中用到了一個參數(shù)_Expand 為偏移的距離。
需要注意的是dot函數(shù)里填入兩次同樣的向量,算出的是向量模的平方而不是向量的模,不過這正是我們需要的,可以達到平方衰減的效果。
float d2 = dot(i.uv - half2(0.5, 0.5), i.uv - half2(0.5, 0.5)); half2 coord = (i.uv - half2(0.5, 0.5)) * (_Expand + d2 * (1 - _Expand)) + half2(0.5, 0.5);
接下來用這個偏移后的uv坐標來對紋理進行采樣。
half4 color = tex2D(_MainTex, coord);
調(diào)整參數(shù)后就會出現(xiàn)一些屏幕凸出的效果,當然這里整個顯示范圍也變小了,這里是因為如果要顯示原范圍的話,需要的公式太復雜了,我們這里簡單起見使用了簡單的公式。
原圖
添加shader后
接下來添加噪聲,我們用一個變量控制噪聲強度,同時傳入時間變量來得到噪聲一直變化的效果。
float n = simpleNoise(coord.xy * _Time.x); half3 result = color.rgb * (1-_NoiseIntensity) + _NoiseIntensity * n;
而噪聲函數(shù)具體的實現(xiàn)如下
至于為什么這個函數(shù)就可以得到噪聲,其實也不好解釋。大致就是sin函數(shù)倍增之后加上取小數(shù)的frac函數(shù)可以近似得到一種隨機數(shù)的效果吧。
float simpleNoise(float2 uv) { return frac(sin(dot(uv, float2(12.9898, 78.233))) * 43758.5453); }
效果如下
最后添加上條紋效果
這個公式也不是什么經(jīng)過精心推導的公式,只是因為我們需要一個周期出現(xiàn)的條紋效果,然后就想到用sin和cos函數(shù),然后隨便調(diào)整一下看起來有點樣子就可以了
half2 sc = half2((sin(coord.y * _StripeIntensity) + 1) / 2, (cos(coord.y * _StripeIntensity) + 1) / 2); result += color.rgb * sc.xyx;
添加條紋之后
效果2
c#代碼
namespace Colorful { using UnityEngine; [ExecuteInEditMode] public class OldTV : MonoBehaviour { public Shader shader; [Range(0, 1)] public float Expand = 0.7f; [Range(0, 1)] public float NoiseIntensity = 0.3f; public int StripeIntensity = 500; protected void OnRenderImage(RenderTexture source, RenderTexture destination) { Material material = new Material(shader); material.SetFloat("_Expand", Expand); material.SetFloat("_NoiseIntensity", NoiseIntensity); material.SetInt("_StripeIntensity", StripeIntensity); Graphics.Blit(source, destination, material, 0); } } }
shader代碼
Shader "LX/OldTV" { Properties { _MainTex ("Base (RGB)", 2D) = "white" {} } CGINCLUDE #include "UnityCG.cginc" sampler2D _MainTex; float _Expand; float _NoiseIntensity; int _StripeIntensity; float simpleNoise(float2 uv) { return frac(sin(dot(uv, float2(12.9898, 78.233))) * 43758.5453); } half4 frag(v2f_img i) : SV_Target { float d2 = dot(i.uv - half2(0.5, 0.5), i.uv - half2(0.5, 0.5)); half2 coord = (i.uv - half2(0.5, 0.5)) * (_Expand + d2 * (1 - _Expand)) + half2(0.5, 0.5); half4 color = tex2D(_MainTex, coord); float n = simpleNoise(coord.xy * _Time.x); half3 result = color.rgb * (1-_NoiseIntensity) + _NoiseIntensity * n; half2 sc = half2((sin(coord.y * _StripeIntensity) + 1) / 2, (cos(coord.y * _StripeIntensity) + 1) / 2); result += color.rgb * sc.xyx; return half4(result, color.a); } ENDCG SubShader { ZTest Always Cull Off ZWrite Off Fog { Mode off } Pass { CGPROGRAM #pragma vertex vert_img #pragma fragment frag ENDCG } } FallBack off }
感謝你能夠認真閱讀完這篇文章,希望小編分享的“Unity3D如何實現(xiàn)舊電視濾鏡shade”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業(yè)資訊頻道,更多相關知識等著你來學習!
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。