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): #<!-- # CRT-simple shader # # Copyright (C) 2011 DOLLS. Based on cgwg's CRT shader. # # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the Free # Software Foundation; either version 2 of the License, or (at your option) # any later version. # --> language: GLSL vertex: | uniform vec2 rubyInputSize; uniform vec2 rubyOutputSize; uniform vec2 rubyTextureSize; // Define some calculations that will be used in fragment shader. varying vec2 texCoord; varying vec2 one; varying float mod_factor; void main() { // Do the standard vertex processing. gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; // Precalculate a bunch of useful values we'll need in the fragment // shader. // Texture coords. texCoord = gl_MultiTexCoord0.xy; // The size of one texel, in texture-coordinates. one = 1.0 / rubyTextureSize; // Resulting X pixel-coordinate of the pixel we're drawing. mod_factor = texCoord.x * rubyTextureSize.x * rubyOutputSize.x / rubyInputSize.x; } linear: true fragment: | uniform sampler2D rubyTexture; uniform vec2 rubyInputSize; uniform vec2 rubyOutputSize; uniform vec2 rubyTextureSize; varying vec2 texCoord; varying vec2 one; varying float mod_factor; // Enable screen curvature. #define CURVATURE // Controls the intensity of the barrel distortion used to emulate the // curvature of a CRT. 0.0 is perfectly flat, 1.0 is annoyingly // distorted, higher values are increasingly ridiculous. #define distortion 0.1 // Simulate a CRT gamma of 2.4. #define inputGamma 2.4 // Compensate for the standard sRGB gamma of 2.2. #define outputGamma 2.2 // Macros. #define TEX2D(c) pow(texture2D(rubyTexture, (c)), vec4(inputGamma)) #define PI 3.141592653589 // Apply radial distortion to the given coordinate. vec2 radialDistortion(vec2 coord) { coord *= rubyTextureSize / rubyInputSize; vec2 cc = coord - 0.5; float dist = dot(cc, cc) * distortion; return (coord + cc * (1.0 + dist) * dist) * rubyInputSize / rubyTextureSize; } // Calculate the influence of a scanline on the current pixel. // // 'distance' is the distance in texture coordinates from the current // pixel to the scanline in question. // 'color' is the colour of the scanline at the horizontal location of // the current pixel. vec4 scanlineWeights(float distance, vec4 color) { // The "width" of the scanline beam is set as 2*(1 + x^4) for // each RGB channel. vec4 wid = 2.0 + 2.0 * pow(color, vec4(4.0)); // The "weights" lines basically specify the formula that gives // you the profile of the beam, i.e. the intensity as // a function of distance from the vertical center of the // scanline. In this case, it is gaussian if width=2, and // becomes nongaussian for larger widths. Ideally this should // be normalized so that the integral across the beam is // independent of its width. That is, for a narrower beam // "weights" should have a higher peak at the center of the // scanline than for a wider beam. vec4 weights = vec4(distance / 0.3); return 1.4 * exp(-pow(weights * inversesqrt(0.5 * wid), wid)) / (0.6 + 0.2 * wid); } void main() { // Here's a helpful diagram to keep in mind while trying to // understand the code: // // | | | | | // ------------------------------- // | | | | | // | 01 | 11 | 21 | 31 | <-- current scanline // | | @ | | | // ------------------------------- // | | | | | // | 02 | 12 | 22 | 32 | <-- next scanline // | | | | | // ------------------------------- // | | | | | // // Each character-cell represents a pixel on the output // surface, "@" represents the current pixel (always somewhere // in the bottom half of the current scan-line, or the top-half // of the next scanline). The grid of lines represents the // edges of the texels of the underlying texture. // Texture coordinates of the texel containing the active pixel. #ifdef CURVATURE vec2 xy = radialDistortion(texCoord); #else vec2 xy = texCoord; #endif // Of all the pixels that are mapped onto the texel we are // currently rendering, which pixel are we currently rendering? vec2 ratio_scale = xy * rubyTextureSize - vec2(0.5); vec2 uv_ratio = fract(ratio_scale); // Snap to the center of the underlying texel. xy.y = (floor(ratio_scale.y) + 0.5) / rubyTextureSize.y; // Calculate the effective colour of the current and next // scanlines at the horizontal location of the current pixel. vec4 col = TEX2D(xy); vec4 col2 = TEX2D(xy + vec2(0.0, one.y)); // Calculate the influence of the current and next scanlines on // the current pixel. vec4 weights = scanlineWeights(uv_ratio.y, col); vec4 weights2 = scanlineWeights(1.0 - uv_ratio.y, col2); vec3 mul_res = (col * weights + col2 * weights2).rgb; // dot-mask emulation: // Output pixels are alternately tinted green and magenta. vec3 dotMaskWeights = mix( vec3(1.0, 0.7, 1.0), vec3(0.7, 1.0, 0.7), floor(mod(mod_factor, 2.0)) ); mul_res *= dotMaskWeights; gl_FragColor = vec4(pow(mul_res, vec3(1.0 / outputGamma)), 1.0); }
You can find it in my "aubergines postprocess effects" pack in assetstore. Its an image effect by the way.
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
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
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...
All done! It may be some things to change etc. but im all out of time sorry! Shader: Code (csharp): //#<!-- //# CRT-simple shader //# //# Copyright (C) 2011 DOLLS. Based on cgwg's CRT shader. //# //# This program is free software; you can redistribute it and/or modify it //# under the terms of the GNU General Public License as published by the Free //# Software Foundation; either version 2 of the License, or (at your option) //# any later version. //# --> Shader "Custom/CRT" { Properties { _MainTex ("Base (RGB)", 2D) = "white" {} } SubShader { Pass { CGPROGRAM #pragma vertex vert_img #pragma fragment frag #include "UnityCG.cginc" #define CURVATURE #pragma target 3.0 #define PI 3.141592653589 uniform sampler2D _MainTex; uniform float2 _InputSize; uniform float2 _OutputSize; uniform float2 _TextureSize; uniform float2 _One; uniform float2 _Texcoord; uniform float _Factor; uniform float _Distortion; // 0.1f uniform float _InputGamma; // 2.4f uniform float _OutputGamma; //2.2f float2 RadialDistortion(float2 coord) { coord *= _TextureSize / _InputSize; float2 cc = coord - 0.5f; float dist = dot(cc, cc) * _Distortion; return (coord + cc * (1.0f + dist) * dist) * _InputSize / _TextureSize; } float4 ScanlineWeights(float distance, float4 color) { float4 width = 2.0f + 2.0f * pow(color, float4(4.0f, 4.0f, 4.0f, 4.0f)); float4 weights = float4(distance / 0.3f, distance / 0.3f, distance / 0.3f, distance / 0.3f); return 1.4f * exp(-pow(weights * rsqrt(0.5f * width), width)) / (0.6f + 0.2f * width); } float4 frag(v2f_img i) : COLOR { _Texcoord = i.uv; _One = 1.0f / _TextureSize; _OutputSize = _TextureSize; _InputSize = _TextureSize; _Factor = _Texcoord.x * _TextureSize.x * _OutputSize.x / _InputSize.x; float4 ScreenGamma = pow(tex2D(_MainTex, _Texcoord), _InputGamma); #ifdef CURVATURE float2 xy = RadialDistortion(_Texcoord); #else float2 xy = _Texcoord; #endif float2 ratio = xy * _TextureSize - float2(0.5f, 0.5f); float2 uvratio = frac(ratio); xy.y = (floor(ratio.y) + 0.5f) / _TextureSize; float4 col = tex2D(_MainTex, xy); float4 col2 = tex2D(_MainTex, xy + float2(0.0f, _One.y)); float4 weights = ScanlineWeights(uvratio.y, col); float4 weights2 = ScanlineWeights(1.0f - uvratio.y, col2); float3 res = (col * weights + col2 * weights2).rgb; float3 rgb1 = float3(1.0f, 0.7f, 1.0f); float3 rgb2 = float3(0.7f, 1.0f, 0.7f); float3 dotMaskWeights = lerp(rgb1, rgb2, floor(fmod(_Factor, 2.0f))); res *= dotMaskWeights; return float4(pow(res, float3(1.0f / _OutputGamma, 1.0f / _OutputGamma, 1.0f / _OutputGamma)), 1.0f); } ENDCG } } } C# script: Code (csharp): using UnityEngine; using System.Collections; [ExecuteInEditMode] public class CRT : MonoBehaviour { #region Variables public Shader curShader; public float Distortion = 0.1f; public float InputGamma = 2.4f; public float OutputGamma = 2.2f; private Material curMaterial; #endregion #region Properties Material material { get { if(curMaterial == null) { curMaterial = new Material(curShader); curMaterial.hideFlags = HideFlags.HideAndDontSave; } return curMaterial; } } #endregion // Use this for initialization void Start () { if(!SystemInfo.supportsImageEffects) { enabled = false; return; } } void OnRenderImage (RenderTexture sourceTexture, RenderTexture destTexture) { if(curShader != null) { material.SetFloat("_Distortion", Distortion); material.SetFloat("_InputGamma", InputGamma); material.SetFloat("_OutputGamma", OutputGamma); material.SetVector("_TextureSize", new Vector2(512.0f, 512.0f)); Graphics.Blit(sourceTexture, destTexture, material); } else { Graphics.Blit(sourceTexture, destTexture); } } // Update is called once per frame void Update () { } void OnDisable () { if(curMaterial) { DestroyImmediate(curMaterial); } } }
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): material.SetVector("_TextureSize", new Vector2(512.0f, 512.0f));
Thank you! I was having trouble getting it to work, so I sent you a PM asking if you could give me some help.
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.
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): //#<!-- //# CRT-simple shader //# //# Copyright (C) 2011 DOLLS. Based on cgwg's CRT shader. //# //# Modified by fontmas: 2015-03-06 //# //# This program is free software; you can redistribute it and/or modify it //# under the terms of the GNU General Public License as published by the Free //# Software Foundation; either version 2 of the License, or (at your option) //# any later version. //# --> Shader "Custom/CRT" { Properties { _MainTex ("Base (RGB)", 2D) = "white" {} } SubShader { Pass { CGPROGRAM #pragma vertex vert_img #pragma fragment frag #include "UnityCG.cginc" #define CURVATURE #pragma target 3.0 #define PI 3.141592653589 uniform sampler2D _MainTex; uniform float2 _InputSize; uniform float2 _OutputSize; uniform float2 _TextureSize; uniform float2 _One; uniform float2 _Texcoord; uniform float _Factor; uniform float _Distortion = 0.1f; // 0.1f uniform float _Gamma = 1.0f; // 1.0f uniform float _curvatureSet1 = 0.5f; // 0.5f uniform float _curvatureSet2 = 0.5f; // 0.5f uniform float _YExtra = 0.5f; // 0.5f; uniform float _rgb1R = 1.0f; // 1.0f uniform float _rgb1G = 1.0f; // 1.0f uniform float _rgb1B = 1.0f; // 1.0f uniform float _rgb2R = 1.0f; // 1.0f uniform float _rgb2G = 1.0f; // 1.0f uniform float _rgb2B = 1.0f; // 1.0f uniform float _dotWeight = 2.0f; // 2.0f float2 RadialDistortion(float2 coord) { coord *= _TextureSize / _InputSize; float2 cc = coord - _curvatureSet1; float dist = dot(cc, cc) * _Distortion; return (coord + cc * (_curvatureSet2 + dist) * dist) * _InputSize / _TextureSize; } float4 ScanlineWeights(float distance, float4 color) { float4 width = 2.0f + 2.0f * pow(color, float4(4.0f, 4.0f, 4.0f, 4.0f)); float4 weights = float4(distance / 0.5f, distance / 0.5f, distance / 0.5f, distance / 0.5f); return 1.4f * exp(-pow(weights * rsqrt(0.5f * width), width)) / (0.3f + 0.2f * width); } float4 frag(v2f_img i) : COLOR { _Texcoord = i.uv; _One = 1.0f / _TextureSize; _OutputSize = _TextureSize; _InputSize = _TextureSize; _Factor = _Texcoord.x * _TextureSize.x * _OutputSize.x / _InputSize.x; //float4 ScreenGamma = pow(tex2D(_MainTex, _Texcoord), _Gamma); #ifdef CURVATURE float2 xy = RadialDistortion(_Texcoord); #else float2 xy = _Texcoord; #endif float2 ratio = xy * _TextureSize - float2(0.5f, 0.5f); float2 uvratio = frac(ratio); xy.y = (floor(ratio.y) + _YExtra) / _TextureSize; float4 col = tex2D(_MainTex, xy); float4 col2 = tex2D(_MainTex, xy + float2(0.0f, _One.y)); float4 weights = ScanlineWeights(uvratio.y, col); float4 weights2 = ScanlineWeights(1.0f - uvratio.y, col2); float3 res = (col * weights + col2 * weights2).rgb; float3 rgb1 = float3(_rgb1R, _rgb1G, _rgb1B); float3 rgb2 = float3(_rgb2R, _rgb2G, _rgb2B); float3 dotMaskWeights = lerp(rgb1, rgb2, floor(fmod(_Factor, _dotWeight))); res *= dotMaskWeights; return float4(pow(res, float3(1.0f / _Gamma, 1.0f / _Gamma, 1.0f / _Gamma)), 1.0f); //return float4(pow(res, float3(1.0f / ScreenGamma.x, 1.0f / ScreenGamma.y, 1.0f / ScreenGamma.z)), 1.0f); } ENDCG } } } C# script: Code (CSharp): using UnityEngine; using System.Collections; public enum CRTScanLinesSizes {S32=32,S64=64,S128=128,S256=256,S512=512,S1024=1024}; [ExecuteInEditMode] public class CRT : MonoBehaviour { #region Variables public Shader curShader; public float Distortion = 0.1f; public float Gamma = 1.0f; public float YExtra = 0.5f; public float CurvatureSet1 = 0.5f; public float CurvatureSet2 = 1.0f; public float DotWeight = 1.0f; public CRTScanLinesSizes scanSize = CRTScanLinesSizes.S512; public Color rgb1 = Color.white; public Color rgb2 = Color.white; private Material curMaterial; #endregion #region Properties Material material { get { if(curMaterial == null) { curMaterial = new Material(curShader); curMaterial.hideFlags = HideFlags.HideAndDontSave; } return curMaterial; } } #endregion // Use this for initialization void Start () { if(!SystemInfo.supportsImageEffects) { enabled = false; return; } } void OnRenderImage (RenderTexture sourceTexture, RenderTexture destTexture) { if(curShader != null) { material.SetFloat("_Distortion", Distortion); material.SetFloat("_Gamma", Gamma); material.SetFloat("_curvatureSet1", CurvatureSet1); material.SetFloat("_curvatureSet2", CurvatureSet2); material.SetFloat("_YExtra", YExtra); material.SetFloat("_rgb1R", rgb1.r); material.SetFloat("_rgb1G", rgb1.g); material.SetFloat("_rgb1B", rgb1.b); material.SetFloat("_rgb2R", rgb2.r); material.SetFloat("_rgb2G", rgb2.g); material.SetFloat("_rgb2B", rgb2.b); material.SetFloat("_dotWeight",DotWeight); material.SetVector("_TextureSize", new Vector2((float)scanSize, (float)scanSize)); Graphics.Blit(sourceTexture, destTexture, material); } else { Graphics.Blit(sourceTexture, destTexture); } } // Update is called once per frame void Update () { } void OnDisable () { if(curMaterial) { DestroyImmediate(curMaterial); } } }
I modified the shader so it can be used on sprites and uGUI objects. Code (CSharp): //#<!-- //# CRT-simpleshader //# //# Copyright (C) 2011 DOLLS. Basedoncgwg'sCRTshader. //# //# Modified by fontmas: 2015-03-06 //# Modified by ashwinFEC: 2015-06-20 //# //# This program is free software; you can redistribute it and/or modify it //# under the terms of the GNU General Public License as published by the Free //# Software Foundation; either version 2 of the License, or (at your option) //# any later version. //# --> Shader "Sprites/CRT" { Properties { [PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {} _Color ("Tint", Color) = (1,1,1,1) [MaterialToggle] PixelSnap ("Pixel snap", Float) = 0 _ScanLineSize ("Scan line size XY", Vector ) = (256,256,0,0) _YExtra ("Y-extra", Float) = 0.5 _Gamma ("Gamma", Float) = 1.0 _ColorScanLine1("Scan lines color 1", Color) = (1,1,1,1) [MaterialToggle] UseIndividualColorChannels1 ("Use Individual Color Channels 1", Float) = 0 _rgb1R ("Color1 r", Float) = 1.0 _rgb1G("Color1 g", Float) = 1.0 _rgb1B ("Color 1 b", Float)= 1.0 _ColorScanLine2("Scan lines color 2", Color) = (1,1,1,1) [MaterialToggle] UseIndividualColorChannels2("Use Individual Color Channels 2", Float) = 0 _rgb2R ("Color2 r", Float)= 1.0 _rgb2G ("Color2 g", Float) = 1.0 _rgb2B ("Color2 b", Float)= 1.0 _dotWeight ("dot weight", Float)= 2.0 [MaterialToggle] UseDistortion("Use Distortion", Float) =0 _Distortion ("Distortion", Float) = 0.1 } SubShader { Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" "PreviewType"="Plane" "CanUseSpriteAtlas"="True" } Cull Off Lighting Off ZWrite Off Blend One OneMinusSrcAlpha Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile _ PIXELSNAP_ON #pragma multi_compile _ USEINDIVIDUALCOLORCHANNELS1_ON #pragma multi_compile _ USEINDIVIDUALCOLORCHANNELS2_ON #pragma multi_compile _ USEDISTORTION_ON #include "UnityCG.cginc" //#define CURVATURE //#pragma target 3.0 #define PI 3.141592653589 struct appdata_t { float4 vertex : POSITION; float4 color : COLOR; float2 texcoord : TEXCOORD0; }; struct v2f { float4 vertex : SV_POSITION; fixed4 color : COLOR; half2 texcoord : TEXCOORD0; }; fixed4 _Color; v2f vert(appdata_t IN) { v2f OUT; OUT.vertex = mul(UNITY_MATRIX_MVP, IN.vertex); OUT.texcoord = IN.texcoord; OUT.color = IN.color * _Color; #ifdef PIXELSNAP_ON OUT.vertex = UnityPixelSnap (OUT.vertex); #endif return OUT; } uniform sampler2D _MainTex; fixed2 _InputSize; fixed2 _OutputSize; int2 _TextureSize; fixed2 _One; half2 _Texcoord; fixed _Factor; uniform fixed _Distortion = .1f; // 0.1f uniform fixed _Gamma = 1.0f; // 1.0f uniform fixed _curvatureSet1 = 0.5f; // 0.5f uniform fixed _curvatureSet2 = 0.5f; // 0.5f uniform fixed _YExtra = 0.5f; // 0.5f; uniform fixed _rgb1R = .4f; // 1.0f uniform fixed _rgb1G = 1.0f; // 1.0f uniform fixed _rgb1B = .5f; // 1.0f uniform fixed _rgb2R = 1.0f; // 1.0f uniform fixed _rgb2G = .2f; // 1.0f uniform fixed _rgb2B = 1.0f; // 1.0f uniform fixed _dotWeight = 2.0f; // 2.0f uniform int4 _ScanLineSize; uniform fixed4 _ColorScanLine1; uniform fixed4 _ColorScanLine2; fixed4 ScanlineWeights(fixed distance, fixed4 color) { fixed4 width = 2.0f + 2.0f * pow(color, float4(4.0f, 4.0f, 4.0f, 4.0f)); fixed4 weights = fixed4(distance / 0.5f, distance / 0.5f, distance / 0.5f, distance / 0.5f); return 1.4f * exp(-pow(weights * rsqrt(0.5f * width), width)) / (0.3f + 0.2f * width); } fixed2 RadialDistortion(fixed2 coord) { coord *= _TextureSize / _InputSize; fixed2 cc = coord - _curvatureSet1; fixed dist = dot(cc, cc) * _Distortion; return (coord + cc * (_curvatureSet2 + dist) * dist) * _InputSize / _TextureSize; } fixed4 frag(v2f IN) : SV_Target { _TextureSize = _ScanLineSize.xy; _Texcoord = IN.texcoord; _One = 1.0f / _TextureSize; _OutputSize = _TextureSize; _InputSize = _TextureSize; _Factor = _Texcoord.x * _TextureSize.x * _OutputSize.x / _InputSize.x; #ifdef USEDISTORTION_ON fixed2 xy = RadialDistortion(_Texcoord); #else fixed2 xy = _Texcoord; #endif fixed2 ratio = xy * _TextureSize - fixed2(0.5f, 0.5f); fixed2 uvratio = frac(ratio); xy.y = (floor(ratio.y) + _YExtra) / _TextureSize; fixed4 col = tex2D(_MainTex, xy) * IN.color; fixed4 col2 = tex2D(_MainTex, xy + fixed2(0.0f, _One.y)) * IN.color; fixed4 weights = ScanlineWeights(uvratio.y, col); fixed4 weights2 = ScanlineWeights(1.0f - uvratio.y, col2); fixed3 res = (col * weights + col2 * weights2).rgb; #ifdef USEINDIVIDUALCOLORCHANNELS1_ON fixed3 rgb1 = float3(_rgb1R, _rgb1G, _rgb1B); #else fixed3 rgb1 = _ColorScanLine1; #endif #ifdef USEINDIVIDUALCOLORCHANNELS2_ON fixed3 rgb2 = float3(_rgb2R, _rgb2G, _rgb2B); #else fixed3 rgb2 = _ColorScanLine2; #endif fixed3 dotMaskWeights = lerp(rgb1, rgb2, floor(fmod(_Factor, _dotWeight))); res *= dotMaskWeights; return fixed4(pow(res, fixed3(1.0f / _Gamma, 1.0f / _Gamma, 1.0f / _Gamma)), col.a) * col.a; //return float4(pow(res, float3(1.0f / ScreenGamma.x, 1.0f / ScreenGamma.y, 1.0f / ScreenGamma.z)), 1.0f); } ENDCG } } } 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.
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
Resurrecting this from the dead. I've been trying to get it working on Android but to no avail. Just a black screen.
I made some changes on fontmas C# script to remove GC.alloc Code (CSharp): using UnityEngine; public enum CrtScanLinesSizes {S32=32,S64=64,S128=128,S256=256,S512=512,S1024=1024,S2048=2048}; [ExecuteInEditMode] public class Crt : MonoBehaviour { #region Variables public Shader curShader; public float distortion = 0.1f; public float gamma = 1.0f; public float yExtra = 0.5f; public float curvatureSet1 = 0.5f; public float curvatureSet2 = 1.0f; public float dotWeight = 1.0f; private CrtScanLinesSizes ScanSize { set => scanSizeVector = new Vector2((float)value,(float)value); } private Vector2 scanSizeVector; public Color rgb1 = Color.white; public Color rgb2 = Color.white; private Material curMaterial; private static readonly int Distortion = Shader.PropertyToID("_Distortion"); private static readonly int Gamma = Shader.PropertyToID("_Gamma"); private static readonly int CurvatureSet1 = Shader.PropertyToID("_curvatureSet1"); private static readonly int CurvatureSet2 = Shader.PropertyToID("_curvatureSet2"); private static readonly int YExtra = Shader.PropertyToID("_YExtra"); private static readonly int Rgb1R = Shader.PropertyToID("_rgb1R"); private static readonly int Rgb1G = Shader.PropertyToID("_rgb1G"); private static readonly int Rgb1B = Shader.PropertyToID("_rgb1B"); private static readonly int Rgb2R = Shader.PropertyToID("_rgb2R"); private static readonly int Rgb2G = Shader.PropertyToID("_rgb2G"); private static readonly int Rgb2B = Shader.PropertyToID("_rgb2B"); private static readonly int DotWeight = Shader.PropertyToID("_dotWeight"); private static readonly int TextureSize = Shader.PropertyToID("_TextureSize"); #endregion #region Properties private Material Material { get { if (curMaterial != null) return curMaterial; curMaterial = new Material(curShader) {hideFlags = HideFlags.HideAndDontSave}; return curMaterial; } } #endregion private void Awake() { ScanSize = CrtScanLinesSizes.S1024; } private void Start () { if (SystemInfo.supportsImageEffects) return; enabled = false; } private void OnRenderImage (RenderTexture sourceTexture, RenderTexture destTexture) { if(curShader != null) { Material.SetFloat(Distortion, distortion); Material.SetFloat(Gamma, gamma); Material.SetFloat(CurvatureSet1, curvatureSet1); Material.SetFloat(CurvatureSet2, curvatureSet2); Material.SetFloat(YExtra, yExtra); Material.SetFloat(Rgb1R, rgb1.r); Material.SetFloat(Rgb1G, rgb1.g); Material.SetFloat(Rgb1B, rgb1.b); Material.SetFloat(Rgb2R, rgb2.r); Material.SetFloat(Rgb2G, rgb2.g); Material.SetFloat(Rgb2B, rgb2.b); Material.SetFloat(DotWeight,dotWeight); Material.SetVector(TextureSize, scanSizeVector); Graphics.Blit(sourceTexture, destTexture, Material); } else { Graphics.Blit(sourceTexture, destTexture); } } private void OnDisable () { if(curMaterial) { DestroyImmediate(curMaterial); } } }