CRT Image Effect – 映像管滤镜

发表于2017-03-20
评论0 4.9k浏览
阴极射线管 Cathode ray tube 简称 CRT,这种效果在游戏中往往会应用在复古效果的游戏风格上,而下面要给大家爱介绍的是CRT Image Effect – 映像管滤镜,一起来看看吧。

图片来源 (Filthy Pants: A Computer Blog)

这次透过结合几种效果
来试著模拟 CRT 效果

使用的效果有
1. Lens Distortion Lens Distortion White Paper
2. Noise Effect 【Unity】【Shader】Noise Image Effect
3. Scan line
4. Vignette texture

CRT shader.shader
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
Shader "Unlit/CRT Shader"
{
    Properties
    {
        _MainTex ("Main Texture", 2D) = "white" {}
        _NoiseTex ("Noise Texture", 2D) = "white" {}
        _NoiseXSpeed ("Noise X Speed", Float) = 100.0
        _NoiseYSpeed ("Noise Y Speed", Float) = 100.0
        _NoiseCutoff ("Noise Cutoff", Range(0, 1.0)) = 0
        _VignetteTex ("Vignette Texture", 2D) = "white" {}
        _LineTex ("Line Texture", 2D) = "white" {}
        _LineColor ("Line Color", Color) = (1, 1, 1, 1)
        _DistortionSrength ("Distortion Strength", Float) = 1
    }
  
    SubShader
    {
        Cull Off
        ZWrite Off
        ZTest Always
  
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
              
            #include "UnityCG.cginc"
  
            struct appdata
            {
                fixed4 vertex : POSITION;
                fixed2 uv : TEXCOORD0;
            };
  
            struct v2f
            {
                fixed2 uv : TEXCOORD0;
                fixed4 vertex : SV_POSITION;
            };
  
            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
                o.uv = v.uv;
                return o;
            }
              
            uniform sampler2D _MainTex;
            uniform sampler2D _NoiseTex;
            uniform fixed _NoiseXSpeed;
            uniform fixed _NoiseYSpeed;
            uniform fixed _NoiseCutoff;
            uniform sampler2D _VignetteTex;
            uniform sampler2D _LineTex;
            uniform fixed4 _LineColor;
            uniform fixed _DistortionSrength;
  
            fixed2 LensDistortion(fixed2 uv)
            {
                fixed2 center = uv - 0.5;
                fixed r2 = center.x * center.x + center.y * center.y;
                fixed ratio = 1.0 + r2 * _DistortionSrength * sqrt(r2); 
                    
                return center * ratio + 0.5; 
            }
  
            fixed4 frag (v2f i) : SV_Target
            {
                fixed2 distortionUV = LensDistortion(i.uv);
  
                fixed4 mainTex = tex2D(_MainTex, distortionUV);
  
                fixed4 vignetteTex = tex2D(_VignetteTex, i.uv);
  
                fixed2 noiseUV = distortionUV + fixed2(_NoiseXSpeed * _SinTime.z, _NoiseYSpeed * _SinTime.z);
                fixed4 noiseTex = tex2D(_NoiseTex, noiseUV);
                if(noiseTex.r > _NoiseCutoff)
                    noiseTex = fixed4(1, 1, 1, 1);
  
                fixed4 lineTex = tex2D(_LineTex, distortionUV);
                lineTex *= _LineColor;
                lineTex *= noiseTex;
  
                fixed4 finalColor = mainTex;
                finalColor *= vignetteTex;
                finalColor += lineTex * vignetteTex;
  
                return finalColor;
            }
            ENDCG
        }
    }
}
CRTImageEffect.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
using UnityEngine;
using System.Collections;
  
[ExecuteInEditMode]
public class CRTImageEffect : MonoBehaviour
{
    [Header("Noise")]
    public Texture noiseTexture;
    public float noiseXSpeed = 100f;
    public float noiseYSpeed = 100f;
    [Range(0, 1.0f)]
    public float noiseCutoff = 0.35f;
  
    [Header("Vignette")]
    public Texture vignetteTexture;
  
    [Header("Line")]
    public Texture lineTexture;
    public Color lineColor = Color.white;
  
    [Header("Distortion")]
    public float distortionStrength = 3.0f;
      
    private string m_noiseTexPropertyName = "_NoiseTex";
    private string m_noiseXSpeedPropertyName = "_NoiseXSpeed";
    private string m_noiseYSpeedPropertyName = "_NoiseYSpeed";
    private string m_noiseCutoffPropertyName = "_NoiseCutoff";
    private string m_vignettePropertyName = "_VignetteTex";
    private string m_linePropertyName = "_LineTex";
    private string m_lineColorPropertyName = "_LineColor";
    private string m_nightVisionPropertyName = "_NightVisionColor";
    private string m_distortionStrengthPropertyName = "_DistortionSrength";
  
    private int m_noiseTexID;
    private int m_noiseXSpeedID;
    private int m_noiseYSpeedID;
    private int m_noiseCutoffID;
    private int m_vignetteTexID;
    private int m_lineTexID;
    private int m_lineColorID;
    private int m_nightVisionID;
    private int m_distortionStrengthID;
  
    private Material m_material;
      
    void Awake ()
    {
        InitPropertyIDs();
        OnValidate();
    }
      
      
    private void InitPropertyIDs()
    {
        if(m_material == null)
            m_material = new Material( Shader.Find("Unlit/CRT Shader") );
          
        m_noiseTexID = Shader.PropertyToID(m_noiseTexPropertyName);
        m_noiseXSpeedID = Shader.PropertyToID(m_noiseXSpeedPropertyName);
        m_noiseYSpeedID = Shader.PropertyToID(m_noiseYSpeedPropertyName);
        m_noiseCutoffID = Shader.PropertyToID(m_noiseCutoffPropertyName);
        m_vignetteTexID = Shader.PropertyToID(m_vignettePropertyName);
        m_lineTexID = Shader.PropertyToID(m_linePropertyName);
        m_lineColorID = Shader.PropertyToID(m_lineColorPropertyName);
        m_distortionStrengthID = Shader.PropertyToID(m_distortionStrengthPropertyName);
    }
      
      
    private void OnValidate()
    {
        if(m_material == null)
            m_material = new Material( Shader.Find("Unlit/CRT Shader") );
          
        m_material.SetTexture(m_noiseTexID, noiseTexture);
        m_material.SetFloat(m_noiseXSpeedID, noiseXSpeed);
        m_material.SetFloat(m_noiseYSpeedID, noiseYSpeed);
        m_material.SetFloat(m_noiseCutoffID, noiseCutoff);
        m_material.SetTexture(m_vignetteTexID, vignetteTexture);
        m_material.SetTexture(m_lineTexID, lineTexture);
        m_material.SetColor(m_lineColorID, lineColor);
        m_material.SetFloat(m_distortionStrengthID, distortionStrength);
    }
      
      
    void OnRenderImage (RenderTexture source, RenderTexture destination)
    {
        Graphics.Blit (source, destination, m_material);
    }
}
接著将 CRTImageEffect.cs 附加到 Camera 上
并附加对应的贴图

附上这次所使用的贴图
1. NoiseTexture
2. VignetteTexture

3. LineTexture
原始画面

CRT 画面

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

0个评论