Search Unity

CRT shader?

Discussion in 'Shaders' started by laurentlavigne, Sep 16, 2013.

  1. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    6,363
    Hello awesome shader makers out there!

    I came across this fantastic CRT shader and would like to use it but I have neither time nor skill to do the conversion to the exotic shaderlab.

    Can anyone do that for me and the whole community?

    Cheerio!

    original link : http://4.bp.blogspot.com/-7IEbxhfeA6k/TdCO-tGD_4I/AAAAAAAAA2s/lFproErnij8/s1600/CRT-simple.png
    (got I love this moiré)

    Code (csharp):
    1. #<!--
    2. #    CRT-simple shader
    3. #
    4. #    Copyright (C) 2011 DOLLS. Based on cgwg's CRT shader.
    5. #
    6. #    This program is free software; you can redistribute it and/or modify it
    7. #    under the terms of the GNU General Public License as published by the Free
    8. #    Software Foundation; either version 2 of the License, or (at your option)
    9. #    any later version.
    10. #    -->
    11. language: GLSL
    12. vertex: |
    13.         uniform vec2 rubyInputSize;
    14.         uniform vec2 rubyOutputSize;
    15.         uniform vec2 rubyTextureSize;
    16.  
    17.         // Define some calculations that will be used in fragment shader.
    18.         varying vec2 texCoord;
    19.         varying vec2 one;
    20.         varying float mod_factor;
    21.  
    22.         void main()
    23.         {
    24.                 // Do the standard vertex processing.
    25.                 gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
    26.  
    27.                 // Precalculate a bunch of useful values we'll need in the fragment
    28.                 // shader.
    29.  
    30.                 // Texture coords.
    31.                 texCoord = gl_MultiTexCoord0.xy;
    32.  
    33.                 // The size of one texel, in texture-coordinates.
    34.                 one = 1.0 / rubyTextureSize;
    35.  
    36.                 // Resulting X pixel-coordinate of the pixel we're drawing.
    37.                 mod_factor = texCoord.x * rubyTextureSize.x * rubyOutputSize.x / rubyInputSize.x;
    38.         }
    39. linear: true
    40. fragment: |
    41.         uniform sampler2D rubyTexture;
    42.         uniform vec2 rubyInputSize;
    43.         uniform vec2 rubyOutputSize;
    44.         uniform vec2 rubyTextureSize;
    45.  
    46.         varying vec2 texCoord;
    47.         varying vec2 one;
    48.         varying float mod_factor;
    49.  
    50.         // Enable screen curvature.
    51.         #define CURVATURE
    52.  
    53.         // Controls the intensity of the barrel distortion used to emulate the
    54.         // curvature of a CRT. 0.0 is perfectly flat, 1.0 is annoyingly
    55.         // distorted, higher values are increasingly ridiculous.
    56.         #define distortion 0.1
    57.  
    58.         // Simulate a CRT gamma of 2.4.
    59.         #define inputGamma  2.4
    60.  
    61.         // Compensate for the standard sRGB gamma of 2.2.
    62.         #define outputGamma 2.2
    63.  
    64.         // Macros.
    65.         #define TEX2D(c) pow(texture2D(rubyTexture, (c)), vec4(inputGamma))
    66.         #define PI 3.141592653589
    67.  
    68.         // Apply radial distortion to the given coordinate.
    69.         vec2 radialDistortion(vec2 coord)
    70.         {
    71.                 coord *= rubyTextureSize / rubyInputSize;
    72.                 vec2 cc = coord - 0.5;
    73.                 float dist = dot(cc, cc) * distortion;
    74.                 return (coord + cc * (1.0 + dist) * dist) * rubyInputSize / rubyTextureSize;
    75.         }
    76.  
    77.         // Calculate the influence of a scanline on the current pixel.
    78.         //
    79.         // 'distance' is the distance in texture coordinates from the current
    80.         // pixel to the scanline in question.
    81.         // 'color' is the colour of the scanline at the horizontal location of
    82.         // the current pixel.
    83.         vec4 scanlineWeights(float distance, vec4 color)
    84.         {
    85.                 // The "width" of the scanline beam is set as 2*(1 + x^4) for
    86.                 // each RGB channel.
    87.                 vec4 wid = 2.0 + 2.0 * pow(color, vec4(4.0));
    88.  
    89.                 // The "weights" lines basically specify the formula that gives
    90.                 // you the profile of the beam, i.e. the intensity as
    91.                 // a function of distance from the vertical center of the
    92.                 // scanline. In this case, it is gaussian if width=2, and
    93.                 // becomes nongaussian for larger widths. Ideally this should
    94.                 // be normalized so that the integral across the beam is
    95.                 // independent of its width. That is, for a narrower beam
    96.                 // "weights" should have a higher peak at the center of the
    97.                 // scanline than for a wider beam.
    98.                 vec4 weights = vec4(distance / 0.3);
    99.                 return 1.4 * exp(-pow(weights * inversesqrt(0.5 * wid), wid)) / (0.6 + 0.2 * wid);
    100.         }
    101.  
    102.         void main()
    103.         {
    104.                 // Here's a helpful diagram to keep in mind while trying to
    105.                 // understand the code:
    106.                 //
    107.                 //  |      |      |      |      |
    108.                 // -------------------------------
    109.                 //  |      |      |      |      |
    110.                 //  |  01  |  11  |  21  |  31  | <-- current scanline
    111.                 //  |      | @    |      |      |
    112.                 // -------------------------------
    113.                 //  |      |      |      |      |
    114.                 //  |  02  |  12  |  22  |  32  | <-- next scanline
    115.                 //  |      |      |      |      |
    116.                 // -------------------------------
    117.                 //  |      |      |      |      |
    118.                 //
    119.                 // Each character-cell represents a pixel on the output
    120.                 // surface, "@" represents the current pixel (always somewhere
    121.                 // in the bottom half of the current scan-line, or the top-half
    122.                 // of the next scanline). The grid of lines represents the
    123.                 // edges of the texels of the underlying texture.
    124.  
    125.                 // Texture coordinates of the texel containing the active pixel.
    126.         #ifdef CURVATURE
    127.                 vec2 xy = radialDistortion(texCoord);
    128.         #else
    129.                 vec2 xy = texCoord;
    130.         #endif
    131.  
    132.                 // Of all the pixels that are mapped onto the texel we are
    133.                 // currently rendering, which pixel are we currently rendering?
    134.                 vec2 ratio_scale = xy * rubyTextureSize - vec2(0.5);
    135.                 vec2 uv_ratio = fract(ratio_scale);
    136.  
    137.                 // Snap to the center of the underlying texel.
    138.                 xy.y = (floor(ratio_scale.y) + 0.5) / rubyTextureSize.y;
    139.  
    140.                 // Calculate the effective colour of the current and next
    141.                 // scanlines at the horizontal location of the current pixel.
    142.                 vec4 col  = TEX2D(xy);
    143.                 vec4 col2 = TEX2D(xy + vec2(0.0, one.y));
    144.  
    145.                 // Calculate the influence of the current and next scanlines on
    146.                 // the current pixel.
    147.                 vec4 weights  = scanlineWeights(uv_ratio.y, col);
    148.                 vec4 weights2 = scanlineWeights(1.0 - uv_ratio.y, col2);
    149.                 vec3 mul_res  = (col * weights + col2 * weights2).rgb;
    150.  
    151.                 // dot-mask emulation:
    152.                 // Output pixels are alternately tinted green and magenta.
    153.                 vec3 dotMaskWeights = mix(
    154.                         vec3(1.0, 0.7, 1.0),
    155.                         vec3(0.7, 1.0, 0.7),
    156.                         floor(mod(mod_factor, 2.0))
    157.                     );
    158.  
    159.                 mul_res *= dotMaskWeights;
    160.  
    161.                 gl_FragColor = vec4(pow(mul_res, vec3(1.0 / outputGamma)), 1.0);
    162.         }
     
  2. aubergine

    aubergine

    Joined:
    Sep 12, 2009
    Posts:
    2,880
    You can find it in my "aubergines postprocess effects" pack in assetstore. Its an image effect by the way.
     
  3. WGermany

    WGermany

    Joined:
    Jun 27, 2013
    Posts:
    78
    Yes and I'll do it for free just give me time, school is making my schedule pretty tight, if I don't post it in a week just reply again and I'll see it then :D
     
  4. tanoshimi

    tanoshimi

    Joined:
    May 21, 2013
    Posts:
    297
    You've already got the GLSL - if you want to understand more about how shaders work, it would be a great learning experience for you to convert it to CG yourself ;)

    Here's a few tips:

    GLSL vec2, vec4 etc. => CG float2, float4 etc.
    GLSL mod => CG fmod (actually, they don't quite behave the same, but don't worry about that for now)
    GLSL inversesqrt => CG rsqrt
    GLSL fract => CG frac
    GLSL texture2d => CG tex2d
    GLSL mix => CG lerp
    GLSL gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; => CG o.pos = mul(UNITY_MATRIX_MVP, v.vertex); (i.e. output position in clipspace)
    GLSL gl_FragColor = vec4(pow(mul_res, vec3(1.0 / outputGamma)), 1.0); => CG FragColor = float4(pow(mul_res, vec3(1.0 / outputGamma)), 1.0); (i.e. output colour from fragment shader)

    Other than that, you can pretty much copy and paste all the same routines as is. Go on, give it a go and see how you get on ;)
     
    nandovilla likes this.
  5. Drowning-Monkeys

    Drowning-Monkeys

    Joined:
    Mar 6, 2013
    Posts:
    328
    anyone ever get this going?
     
  6. WGermany

    WGermany

    Joined:
    Jun 27, 2013
    Posts:
    78
    No, but I will convert this for 22 payments of 19.95 USD :). Jk I'll do this now even though i'm late.. Should only take a second. It may require Shader Model 3.0 though...
     
  7. WGermany

    WGermany

    Joined:
    Jun 27, 2013
    Posts:
    78
    All done! It may be some things to change etc. but im all out of time sorry!

    Shader:
    Code (csharp):
    1. //#<!--
    2. //#    CRT-simple shader
    3. //#
    4. //#    Copyright (C) 2011 DOLLS. Based on cgwg's CRT shader.
    5. //#
    6. //#    This program is free software; you can redistribute it and/or modify it
    7. //#    under the terms of the GNU General Public License as published by the Free
    8. //#    Software Foundation; either version 2 of the License, or (at your option)
    9. //#    any later version.
    10. //#    -->
    11.  
    12. Shader "Custom/CRT"
    13. {
    14.     Properties
    15.     {
    16.         _MainTex ("Base (RGB)", 2D) = "white" {}
    17.  
    18.     }
    19.     SubShader
    20.     {
    21.         Pass
    22.         {
    23.        
    24.         CGPROGRAM
    25.         #pragma vertex vert_img
    26.         #pragma fragment frag
    27.         #include "UnityCG.cginc"
    28.         #define CURVATURE
    29.         #pragma target 3.0
    30.         #define PI 3.141592653589
    31.  
    32.         uniform sampler2D _MainTex;
    33.         uniform float2 _InputSize;
    34.         uniform float2 _OutputSize;
    35.         uniform float2 _TextureSize;
    36.         uniform float2 _One;
    37.         uniform float2 _Texcoord;
    38.         uniform float _Factor;
    39.         uniform float _Distortion; // 0.1f
    40.         uniform float _InputGamma; // 2.4f
    41.         uniform float _OutputGamma; //2.2f
    42.  
    43.         float2 RadialDistortion(float2 coord)
    44.         {
    45.             coord *= _TextureSize / _InputSize;
    46.             float2 cc = coord - 0.5f;
    47.             float dist = dot(cc, cc) * _Distortion;
    48.             return (coord + cc * (1.0f + dist) * dist) * _InputSize / _TextureSize;
    49.         }
    50.        
    51.         float4 ScanlineWeights(float distance, float4 color)
    52.         {
    53.             float4 width = 2.0f + 2.0f * pow(color, float4(4.0f, 4.0f, 4.0f, 4.0f));
    54.             float4 weights = float4(distance / 0.3f, distance / 0.3f, distance / 0.3f, distance / 0.3f);
    55.             return 1.4f * exp(-pow(weights * rsqrt(0.5f * width), width)) / (0.6f + 0.2f * width);
    56.         }
    57.        
    58.         float4 frag(v2f_img i) : COLOR
    59.         {
    60.             _Texcoord = i.uv;
    61.             _One = 1.0f / _TextureSize;
    62.             _OutputSize = _TextureSize;
    63.             _InputSize = _TextureSize;
    64.             _Factor = _Texcoord.x * _TextureSize.x * _OutputSize.x / _InputSize.x;
    65.            
    66.             float4 ScreenGamma = pow(tex2D(_MainTex, _Texcoord), _InputGamma);
    67.            
    68.             #ifdef CURVATURE
    69.             float2 xy = RadialDistortion(_Texcoord);
    70.             #else
    71.             float2 xy = _Texcoord;
    72.             #endif
    73.            
    74.             float2 ratio = xy * _TextureSize - float2(0.5f, 0.5f);
    75.             float2 uvratio = frac(ratio);
    76.            
    77.             xy.y = (floor(ratio.y) + 0.5f) / _TextureSize;
    78.             float4 col = tex2D(_MainTex, xy);
    79.             float4 col2 = tex2D(_MainTex, xy + float2(0.0f, _One.y));
    80.            
    81.             float4 weights = ScanlineWeights(uvratio.y, col);
    82.             float4 weights2 = ScanlineWeights(1.0f - uvratio.y, col2);
    83.             float3 res = (col * weights + col2 * weights2).rgb;
    84.            
    85.             float3 rgb1 = float3(1.0f, 0.7f, 1.0f);
    86.             float3 rgb2 = float3(0.7f, 1.0f, 0.7f);
    87.            
    88.             float3 dotMaskWeights = lerp(rgb1, rgb2, floor(fmod(_Factor, 2.0f)));
    89.             res *= dotMaskWeights;
    90.            
    91.             return float4(pow(res, float3(1.0f / _OutputGamma, 1.0f / _OutputGamma, 1.0f / _OutputGamma)), 1.0f);
    92.            
    93.            
    94.         }
    95.  
    96.         ENDCG
    97.         }
    98.     }
    99. }
    100.  
    C# script:
    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. [ExecuteInEditMode]
    5. public class CRT : MonoBehaviour {
    6.     #region Variables
    7.     public Shader curShader;
    8.     public float Distortion = 0.1f;
    9.     public float InputGamma = 2.4f;
    10.     public float OutputGamma = 2.2f;
    11.     private Material curMaterial;
    12.     #endregion
    13.    
    14.     #region Properties
    15.     Material material
    16.     {
    17.         get
    18.         {
    19.             if(curMaterial == null)
    20.             {
    21.                 curMaterial = new Material(curShader);
    22.                 curMaterial.hideFlags = HideFlags.HideAndDontSave; 
    23.             }
    24.             return curMaterial;
    25.         }
    26.     }
    27.     #endregion
    28.     // Use this for initialization
    29.     void Start ()
    30.     {
    31.         if(!SystemInfo.supportsImageEffects)
    32.         {
    33.             enabled = false;
    34.             return;
    35.         }
    36.     }
    37.    
    38.     void OnRenderImage (RenderTexture sourceTexture, RenderTexture destTexture)
    39.     {
    40.         if(curShader != null)
    41.         {
    42.             material.SetFloat("_Distortion", Distortion);
    43.             material.SetFloat("_InputGamma", InputGamma);
    44.             material.SetFloat("_OutputGamma", OutputGamma);
    45.             material.SetVector("_TextureSize", new Vector2(512.0f, 512.0f));
    46.             Graphics.Blit(sourceTexture, destTexture, material);
    47.         }
    48.         else
    49.         {
    50.             Graphics.Blit(sourceTexture, destTexture); 
    51.         }
    52.        
    53.        
    54.     }
    55.    
    56.     // Update is called once per frame
    57.     void Update ()
    58.     {
    59.        
    60.     }
    61.    
    62.     void OnDisable ()
    63.     {
    64.         if(curMaterial)
    65.         {
    66.             DestroyImmediate(curMaterial); 
    67.         }
    68.        
    69.     }
    70.    
    71.    
    72. }
     
    kebrus likes this.
  8. WGermany

    WGermany

    Joined:
    Jun 27, 2013
    Posts:
    78
    Also change this line in the C# code to make the lines thinner or thicker. From 512 --> 256 makes them thicker. From 512 --> 1024 makes them thinner.

    Code (csharp):
    1. material.SetVector("_TextureSize", new Vector2(512.0f, 512.0f));
     
  9. Superrodan

    Superrodan

    Joined:
    Nov 10, 2013
    Posts:
    10
    Thank you!

    I was having trouble getting it to work, so I sent you a PM asking if you could give me some help.
     
  10. Hogge

    Hogge

    Joined:
    Aug 7, 2012
    Posts:
    12
    I really want to acheive an effect similar to this.
    I've inserted the script into the game and applied it to the main camera. Problem is that as soon as I start the game, the script disables and I have to activate it again manually. Could someone make a guide for this, because this shader is pure gold.
     
  11. fontmas

    fontmas

    Joined:
    Dec 2, 2013
    Posts:
    1
    Hi!

    I did some improvements in CRT shader and CRT scripts.

    In this new scripts I created public variable to ajust distortion, dot weight, gamma and color.

    Shader:
    Code (CSharp):
    1. //#<!--
    2. //#    CRT-simple shader
    3. //#
    4. //#    Copyright (C) 2011 DOLLS. Based on cgwg's CRT shader.
    5. //#
    6. //#    Modified by fontmas: 2015-03-06
    7. //#
    8. //#    This program is free software; you can redistribute it and/or modify it
    9. //#    under the terms of the GNU General Public License as published by the Free
    10. //#    Software Foundation; either version 2 of the License, or (at your option)
    11. //#    any later version.
    12. //#    -->
    13. Shader "Custom/CRT"
    14. {
    15.     Properties
    16.     {
    17.         _MainTex ("Base (RGB)", 2D) = "white" {}
    18.     }
    19.    
    20.     SubShader
    21.     {
    22.         Pass
    23.         {
    24.      
    25.         CGPROGRAM
    26.         #pragma vertex vert_img
    27.         #pragma fragment frag
    28.         #include "UnityCG.cginc"
    29.         #define CURVATURE
    30.         #pragma target 3.0
    31.         #define PI 3.141592653589
    32.         uniform sampler2D _MainTex;
    33.         uniform float2 _InputSize;
    34.         uniform float2 _OutputSize;
    35.         uniform float2 _TextureSize;
    36.         uniform float2 _One;
    37.         uniform float2 _Texcoord;
    38.         uniform float _Factor;
    39.         uniform float _Distortion = 0.1f; // 0.1f
    40.         uniform float _Gamma = 1.0f; // 1.0f
    41.         uniform float _curvatureSet1 = 0.5f; // 0.5f
    42.         uniform float _curvatureSet2 = 0.5f; // 0.5f
    43.         uniform float _YExtra = 0.5f; // 0.5f;
    44.         uniform float _rgb1R = 1.0f; // 1.0f
    45.         uniform float _rgb1G = 1.0f; // 1.0f
    46.         uniform float _rgb1B = 1.0f; // 1.0f
    47.         uniform float _rgb2R = 1.0f; // 1.0f
    48.         uniform float _rgb2G = 1.0f; // 1.0f
    49.         uniform float _rgb2B = 1.0f; // 1.0f
    50.         uniform float _dotWeight = 2.0f; // 2.0f
    51.         float2 RadialDistortion(float2 coord)
    52.         {
    53.             coord *= _TextureSize / _InputSize;
    54.             float2 cc = coord - _curvatureSet1;
    55.             float dist = dot(cc, cc) * _Distortion;
    56.             return (coord + cc * (_curvatureSet2 + dist) * dist) * _InputSize / _TextureSize;
    57.         }
    58.      
    59.         float4 ScanlineWeights(float distance, float4 color)
    60.         {
    61.             float4 width = 2.0f + 2.0f * pow(color, float4(4.0f, 4.0f, 4.0f, 4.0f));
    62.             float4 weights = float4(distance / 0.5f, distance / 0.5f, distance / 0.5f, distance / 0.5f);
    63.             return 1.4f * exp(-pow(weights * rsqrt(0.5f * width), width)) / (0.3f + 0.2f * width);
    64.         }
    65.      
    66.         float4 frag(v2f_img i) : COLOR
    67.         {
    68.             _Texcoord = i.uv;
    69.             _One = 1.0f / _TextureSize;
    70.             _OutputSize = _TextureSize;
    71.             _InputSize = _TextureSize;
    72.             _Factor = _Texcoord.x * _TextureSize.x * _OutputSize.x / _InputSize.x;
    73.          
    74.             //float4 ScreenGamma = pow(tex2D(_MainTex, _Texcoord), _Gamma);
    75.          
    76.             #ifdef CURVATURE
    77.             float2 xy = RadialDistortion(_Texcoord);
    78.             #else
    79.             float2 xy = _Texcoord;
    80.             #endif
    81.          
    82.             float2 ratio = xy * _TextureSize - float2(0.5f, 0.5f);
    83.             float2 uvratio = frac(ratio);
    84.          
    85.             xy.y = (floor(ratio.y) + _YExtra) / _TextureSize;
    86.             float4 col = tex2D(_MainTex, xy);
    87.             float4 col2 = tex2D(_MainTex, xy + float2(0.0f, _One.y));
    88.          
    89.             float4 weights = ScanlineWeights(uvratio.y, col);
    90.             float4 weights2 = ScanlineWeights(1.0f - uvratio.y, col2);
    91.             float3 res = (col * weights + col2 * weights2).rgb;
    92.          
    93.             float3 rgb1 = float3(_rgb1R, _rgb1G, _rgb1B);
    94.             float3 rgb2 = float3(_rgb2R, _rgb2G, _rgb2B);
    95.          
    96.             float3 dotMaskWeights = lerp(rgb1, rgb2, floor(fmod(_Factor, _dotWeight)));
    97.             res *= dotMaskWeights;
    98.          
    99.             return float4(pow(res, float3(1.0f / _Gamma, 1.0f / _Gamma, 1.0f / _Gamma)), 1.0f);
    100.             //return float4(pow(res, float3(1.0f / ScreenGamma.x, 1.0f / ScreenGamma.y, 1.0f / ScreenGamma.z)), 1.0f);
    101.          
    102.          
    103.         }
    104.         ENDCG
    105.         }
    106.     }
    107. }

    C# script:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public enum CRTScanLinesSizes {S32=32,S64=64,S128=128,S256=256,S512=512,S1024=1024};
    5.  
    6. [ExecuteInEditMode]
    7. public class CRT : MonoBehaviour {
    8.  
    9.     #region Variables
    10.     public Shader curShader;
    11.     public float Distortion = 0.1f;
    12.     public float Gamma = 1.0f;
    13.     public float YExtra = 0.5f;
    14.     public float CurvatureSet1 = 0.5f;
    15.     public float CurvatureSet2 = 1.0f;
    16.     public float DotWeight = 1.0f;
    17.     public CRTScanLinesSizes scanSize = CRTScanLinesSizes.S512;
    18.     public Color rgb1 = Color.white;
    19.     public Color rgb2 = Color.white;
    20.     private Material curMaterial;
    21.  
    22.     #endregion
    23.    
    24.     #region Properties
    25.     Material material
    26.     {
    27.         get
    28.         {
    29.             if(curMaterial == null)
    30.             {
    31.                 curMaterial = new Material(curShader);
    32.                 curMaterial.hideFlags = HideFlags.HideAndDontSave;
    33.             }
    34.             return curMaterial;
    35.         }
    36.     }
    37.     #endregion
    38.     // Use this for initialization
    39.     void Start ()
    40.     {
    41.         if(!SystemInfo.supportsImageEffects)
    42.         {
    43.             enabled = false;
    44.             return;
    45.         }
    46.     }
    47.    
    48.     void OnRenderImage (RenderTexture sourceTexture, RenderTexture destTexture)
    49.     {
    50.         if(curShader != null)
    51.         {
    52.             material.SetFloat("_Distortion", Distortion);
    53.             material.SetFloat("_Gamma", Gamma);
    54.             material.SetFloat("_curvatureSet1", CurvatureSet1);
    55.             material.SetFloat("_curvatureSet2", CurvatureSet2);
    56.             material.SetFloat("_YExtra", YExtra);
    57.             material.SetFloat("_rgb1R", rgb1.r);
    58.             material.SetFloat("_rgb1G", rgb1.g);
    59.             material.SetFloat("_rgb1B", rgb1.b);
    60.             material.SetFloat("_rgb2R", rgb2.r);
    61.             material.SetFloat("_rgb2G", rgb2.g);
    62.             material.SetFloat("_rgb2B", rgb2.b);
    63.             material.SetFloat("_dotWeight",DotWeight);
    64.             material.SetVector("_TextureSize", new Vector2((float)scanSize, (float)scanSize));
    65.             Graphics.Blit(sourceTexture, destTexture, material);
    66.         }
    67.         else
    68.         {
    69.             Graphics.Blit(sourceTexture, destTexture);
    70.         }
    71.        
    72.        
    73.     }
    74.    
    75.     // Update is called once per frame
    76.     void Update ()
    77.     {
    78.        
    79.     }
    80.    
    81.     void OnDisable ()
    82.     {
    83.         if(curMaterial)
    84.         {
    85.             DestroyImmediate(curMaterial);
    86.         }
    87.        
    88.     }
    89.    
    90.    
    91. }
     
    musaranya, SeinmFraoch and kebrus like this.
  12. BoltScripts

    BoltScripts

    Joined:
    Feb 12, 2015
    Posts:
    20
    Thanks for the update, the improvements are really nice. Gj
     
  13. rimiki

    rimiki

    Joined:
    Dec 30, 2014
    Posts:
    102
    Why I got black object when I put the shader !
     
  14. ashwinFEC

    ashwinFEC

    Joined:
    May 19, 2013
    Posts:
    49
    I modified the shader so it can be used on sprites and uGUI objects.

    Code (CSharp):
    1.  
    2. //#<!--
    3. //#    CRT-simpleshader
    4. //#
    5. //#    Copyright (C) 2011 DOLLS. Basedoncgwg'sCRTshader.
    6. //#
    7. //#    Modified by fontmas: 2015-03-06
    8. //#    Modified by ashwinFEC: 2015-06-20
    9. //#
    10. //#    This program is free software; you can redistribute it and/or modify it
    11. //#    under the terms of the GNU General Public License as published by the Free
    12. //#    Software Foundation; either version 2 of the License, or (at your option)
    13. //#    any later version.
    14. //#    -->
    15. Shader "Sprites/CRT"
    16. {
    17.     Properties
    18.     {
    19.         [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
    20.         _Color ("Tint", Color) = (1,1,1,1)
    21.         [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
    22.  
    23.         _ScanLineSize ("Scan line size XY", Vector ) = (256,256,0,0)
    24.         _YExtra ("Y-extra", Float) = 0.5
    25.         _Gamma ("Gamma", Float) = 1.0
    26.    
    27.         _ColorScanLine1("Scan lines color 1", Color) =  (1,1,1,1)
    28.         [MaterialToggle] UseIndividualColorChannels1 ("Use Individual Color Channels 1", Float) = 0
    29.         _rgb1R ("Color1 r", Float) = 1.0
    30.         _rgb1G("Color1 g", Float) = 1.0
    31.         _rgb1B ("Color 1 b", Float)= 1.0
    32.    
    33.  
    34.         _ColorScanLine2("Scan lines color 2", Color) =  (1,1,1,1)
    35.          [MaterialToggle] UseIndividualColorChannels2("Use Individual Color Channels 2", Float) = 0
    36.         _rgb2R ("Color2 r", Float)= 1.0
    37.         _rgb2G ("Color2 g", Float) = 1.0
    38.         _rgb2B ("Color2 b", Float)= 1.0
    39.      
    40.            _dotWeight ("dot weight", Float)= 2.0
    41.      
    42.            [MaterialToggle] UseDistortion("Use Distortion", Float) =0
    43.            _Distortion ("Distortion", Float) = 0.1
    44.     }
    45.  
    46.     SubShader
    47.     {
    48.         Tags
    49.         {
    50.             "Queue"="Transparent"
    51.             "IgnoreProjector"="True"
    52.             "RenderType"="Transparent"
    53.             "PreviewType"="Plane"
    54.             "CanUseSpriteAtlas"="True"
    55.         }
    56.  
    57.         Cull Off
    58.         Lighting Off
    59.         ZWrite Off
    60.         Blend One OneMinusSrcAlpha
    61.  
    62.         Pass
    63.         {
    64.         CGPROGRAM
    65.             #pragma vertex vert
    66.             #pragma fragment frag
    67.             #pragma multi_compile _ PIXELSNAP_ON
    68.             #pragma multi_compile _ USEINDIVIDUALCOLORCHANNELS1_ON
    69.             #pragma multi_compile _ USEINDIVIDUALCOLORCHANNELS2_ON
    70.             #pragma multi_compile _ USEDISTORTION_ON
    71.             #include "UnityCG.cginc"
    72.             //#define CURVATURE
    73.               //#pragma target 3.0
    74.             #define PI 3.141592653589
    75.        
    76.             struct appdata_t
    77.             {
    78.                 float4 vertex   : POSITION;
    79.                 float4 color    : COLOR;
    80.                 float2 texcoord : TEXCOORD0;
    81.             };
    82.  
    83.             struct v2f
    84.             {
    85.                 float4 vertex   : SV_POSITION;
    86.                 fixed4 color    : COLOR;
    87.                 half2 texcoord  : TEXCOORD0;
    88.             };
    89.        
    90.             fixed4 _Color;
    91.          
    92.  
    93.             v2f vert(appdata_t IN)
    94.             {
    95.                 v2f OUT;
    96.                 OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex);
    97.                 OUT.texcoord = IN.texcoord;
    98.                 OUT.color = IN.color * _Color;
    99.                 #ifdef PIXELSNAP_ON
    100.                 OUT.vertex = UnityPixelSnap (OUT.vertex);
    101.            
    102.                 #endif
    103.            
    104.            
    105.  
    106.                 return OUT;
    107.             }
    108.  
    109.             uniform sampler2D _MainTex;
    110.        
    111.             fixed2 _InputSize;
    112.             fixed2 _OutputSize;
    113.             int2 _TextureSize;
    114.             fixed2 _One;
    115.             half2 _Texcoord;
    116.              fixed  _Factor;
    117.        
    118.             uniform fixed _Distortion = .1f; // 0.1f
    119.             uniform fixed _Gamma = 1.0f; // 1.0f
    120.             uniform fixed _curvatureSet1 = 0.5f; // 0.5f
    121.             uniform fixed _curvatureSet2 = 0.5f; // 0.5f
    122.             uniform fixed _YExtra = 0.5f; // 0.5f;
    123.             uniform fixed _rgb1R = .4f; // 1.0f
    124.             uniform fixed _rgb1G = 1.0f; // 1.0f
    125.             uniform fixed _rgb1B = .5f; // 1.0f
    126.             uniform fixed _rgb2R = 1.0f; // 1.0f
    127.             uniform fixed _rgb2G = .2f; // 1.0f
    128.             uniform fixed _rgb2B = 1.0f; // 1.0f
    129.             uniform fixed _dotWeight = 2.0f; // 2.0f
    130.             uniform int4 _ScanLineSize;
    131.             uniform fixed4 _ColorScanLine1;
    132.             uniform fixed4 _ColorScanLine2;
    133.    
    134.  
    135.              fixed4 ScanlineWeights(fixed distance, fixed4 color)
    136.             {
    137.                 fixed4 width = 2.0f + 2.0f * pow(color, float4(4.0f, 4.0f, 4.0f, 4.0f));
    138.                 fixed4 weights = fixed4(distance / 0.5f, distance / 0.5f, distance / 0.5f, distance / 0.5f);
    139.                 return 1.4f * exp(-pow(weights * rsqrt(0.5f * width), width)) / (0.3f + 0.2f * width);
    140.                 }
    141.            
    142.                fixed2 RadialDistortion(fixed2 coord)
    143.             {
    144.                 coord *= _TextureSize / _InputSize;
    145.                 fixed2 cc = coord - _curvatureSet1;
    146.                 fixed dist = dot(cc, cc) * _Distortion;
    147.                 return (coord + cc * (_curvatureSet2 + dist) * dist) * _InputSize / _TextureSize;
    148.             }
    149.  
    150.  
    151.        
    152.             fixed4 frag(v2f IN) : SV_Target
    153.             {
    154.            
    155.                 _TextureSize = _ScanLineSize.xy;
    156.                 _Texcoord = IN.texcoord;
    157.            
    158.                 _One = 1.0f / _TextureSize;
    159.                 _OutputSize = _TextureSize;
    160.                 _InputSize = _TextureSize;
    161.                 _Factor = _Texcoord.x * _TextureSize.x * _OutputSize.x / _InputSize.x;
    162.                
    163.              #ifdef USEDISTORTION_ON
    164.                 fixed2 xy = RadialDistortion(_Texcoord);
    165.              #else
    166.                 fixed2 xy = _Texcoord;
    167.              #endif
    168.                 fixed2 ratio = xy * _TextureSize - fixed2(0.5f, 0.5f);
    169.                 fixed2 uvratio = frac(ratio);
    170.        
    171.                 xy.y = (floor(ratio.y) + _YExtra) / _TextureSize;
    172.                 fixed4 col = tex2D(_MainTex, xy) * IN.color;
    173.                 fixed4 col2 = tex2D(_MainTex, xy + fixed2(0.0f, _One.y)) * IN.color;
    174.        
    175.                 fixed4 weights = ScanlineWeights(uvratio.y, col);
    176.                 fixed4 weights2 = ScanlineWeights(1.0f - uvratio.y, col2);
    177.                 fixed3 res = (col * weights + col2 * weights2).rgb;
    178.              #ifdef USEINDIVIDUALCOLORCHANNELS1_ON
    179.                 fixed3 rgb1 = float3(_rgb1R, _rgb1G, _rgb1B);
    180.              #else
    181.                   fixed3 rgb1 = _ColorScanLine1;
    182.               #endif
    183.              
    184.               #ifdef USEINDIVIDUALCOLORCHANNELS2_ON
    185.                 fixed3 rgb2 = float3(_rgb2R, _rgb2G, _rgb2B);
    186.              #else
    187.                   fixed3 rgb2 = _ColorScanLine2;
    188.               #endif
    189.        
    190.                   fixed3 dotMaskWeights = lerp(rgb1, rgb2, floor(fmod(_Factor, _dotWeight)));
    191.                   res *= dotMaskWeights;
    192.                
    193.                 return fixed4(pow(res, fixed3(1.0f / _Gamma, 1.0f / _Gamma, 1.0f / _Gamma)), col.a) * col.a;
    194.             //return float4(pow(res, float3(1.0f / ScreenGamma.x, 1.0f / ScreenGamma.y, 1.0f / ScreenGamma.z)), 1.0f);
    195.             }
    196.         ENDCG
    197.         }
    198.     }
    199. }
    example:


    Distortion doesn't work as in the image effect shader, but can still be used for cool effects. Like a screen that boots up.
     
    Last edited: Jun 20, 2015
    Numonic and SeinmFraoch like this.
  15. b005t3r

    b005t3r

    Joined:
    Dec 29, 2016
    Posts:
    46
    This topic is a bit old, but it's the first one that pops up on Google, so hopefully someone will find my reply useful :)

    I recently published a full screen CRT post-process which can simulate various types of displays. I'll say it's probably the best such effect available currently. It's $30 USD and it's available on Asset Store:

    https://www.assetstore.unity3d.com/en/#!/content/80048

    closeUp0.png comp2.png
     
  16. Numonic

    Numonic

    Joined:
    Mar 22, 2009
    Posts:
    241
    Wondering if this will fun on Mobile like Android and Iphone?
     
    lordcohliani likes this.
  17. lordcohliani

    lordcohliani

    Joined:
    Mar 27, 2018
    Posts:
    1
    Resurrecting this from the dead. I've been trying to get it working on Android but to no avail. Just a black screen.
     
  18. mauriciofelippe

    mauriciofelippe

    Joined:
    Aug 9, 2017
    Posts:
    28
    I made some changes on fontmas C# script to remove GC.alloc

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public enum CrtScanLinesSizes {S32=32,S64=64,S128=128,S256=256,S512=512,S1024=1024,S2048=2048};
    4. [ExecuteInEditMode]
    5. public class Crt : MonoBehaviour {
    6.     #region Variables
    7.     public Shader curShader;
    8.     public float distortion = 0.1f;
    9.     public float gamma = 1.0f;
    10.     public float yExtra = 0.5f;
    11.     public float curvatureSet1 = 0.5f;
    12.     public float curvatureSet2 = 1.0f;
    13.     public float dotWeight = 1.0f;
    14.  
    15.     private CrtScanLinesSizes ScanSize
    16.     {
    17.         set => scanSizeVector = new Vector2((float)value,(float)value);
    18.     }
    19.     private Vector2 scanSizeVector;
    20.    
    21.     public Color rgb1 = Color.white;
    22.     public Color rgb2 = Color.white;
    23.     private Material curMaterial;
    24.    
    25.     private static readonly int Distortion = Shader.PropertyToID("_Distortion");
    26.     private static readonly int Gamma = Shader.PropertyToID("_Gamma");
    27.     private static readonly int CurvatureSet1 = Shader.PropertyToID("_curvatureSet1");
    28.     private static readonly int CurvatureSet2 = Shader.PropertyToID("_curvatureSet2");
    29.     private static readonly int YExtra = Shader.PropertyToID("_YExtra");
    30.     private static readonly int Rgb1R = Shader.PropertyToID("_rgb1R");
    31.     private static readonly int Rgb1G = Shader.PropertyToID("_rgb1G");
    32.     private static readonly int Rgb1B = Shader.PropertyToID("_rgb1B");
    33.     private static readonly int Rgb2R = Shader.PropertyToID("_rgb2R");
    34.     private static readonly int Rgb2G = Shader.PropertyToID("_rgb2G");
    35.     private static readonly int Rgb2B = Shader.PropertyToID("_rgb2B");
    36.     private static readonly int DotWeight = Shader.PropertyToID("_dotWeight");
    37.     private static readonly int TextureSize = Shader.PropertyToID("_TextureSize");
    38.  
    39.     #endregion
    40.  
    41.     #region Properties
    42.  
    43.     private Material Material
    44.     {
    45.         get
    46.         {
    47.             if (curMaterial != null) return curMaterial;
    48.             curMaterial = new Material(curShader) {hideFlags = HideFlags.HideAndDontSave};
    49.             return curMaterial;
    50.         }
    51.     }
    52.     #endregion
    53.  
    54.     private void Awake()
    55.     {
    56.         ScanSize = CrtScanLinesSizes.S1024;
    57.     }
    58.  
    59.  
    60.     private void Start ()
    61.     {
    62.         if (SystemInfo.supportsImageEffects) return;
    63.         enabled = false;
    64.        
    65.     }
    66.  
    67.     private void OnRenderImage (RenderTexture sourceTexture, RenderTexture destTexture)
    68.     {
    69.         if(curShader != null)
    70.         {
    71.             Material.SetFloat(Distortion, distortion);
    72.             Material.SetFloat(Gamma, gamma);
    73.             Material.SetFloat(CurvatureSet1, curvatureSet1);
    74.             Material.SetFloat(CurvatureSet2, curvatureSet2);
    75.             Material.SetFloat(YExtra, yExtra);
    76.             Material.SetFloat(Rgb1R, rgb1.r);
    77.             Material.SetFloat(Rgb1G, rgb1.g);
    78.             Material.SetFloat(Rgb1B, rgb1.b);
    79.             Material.SetFloat(Rgb2R, rgb2.r);
    80.             Material.SetFloat(Rgb2G, rgb2.g);
    81.             Material.SetFloat(Rgb2B, rgb2.b);
    82.             Material.SetFloat(DotWeight,dotWeight);
    83.             Material.SetVector(TextureSize, scanSizeVector);
    84.             Graphics.Blit(sourceTexture, destTexture, Material);
    85.         }
    86.         else
    87.         {
    88.             Graphics.Blit(sourceTexture, destTexture);
    89.         }
    90.     }
    91.  
    92.     private void OnDisable ()
    93.     {
    94.         if(curMaterial)
    95.         {
    96.             DestroyImmediate(curMaterial);
    97.         }
    98.     }
    99.  
    100.  
    101. }