Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

CRT shader?

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

  1. laurentlavigne

    laurentlavigne

    Joined:
    Aug 16, 2012
    Posts:
    5,444
    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,821
    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:
    7
    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:
    12
    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:
    41
    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:
    26
    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. }
     
unityunity