Last active
January 8, 2023 19:16
-
-
Save partybusiness/9997db4b20ed88697b73fe9abf520220 to your computer and use it in GitHub Desktop.
VHS style camera
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Shader "Unlit/CircleBlur" | |
{ | |
Properties | |
{ | |
_MainTex ("Texture", 2D) = "white" {} | |
_Radius ("Radius", float) = 0.8 | |
} | |
SubShader | |
{ | |
Tags { "RenderType"="Opaque" } | |
LOD 100 | |
Pass | |
{ | |
CGPROGRAM | |
#pragma vertex vert | |
#pragma fragment frag | |
#include "UnityCG.cginc" | |
struct appdata | |
{ | |
float4 vertex : POSITION; | |
float2 uv : TEXCOORD0; | |
}; | |
struct v2f | |
{ | |
float2 uv : TEXCOORD0; | |
float4 vertex : SV_POSITION; | |
}; | |
sampler2D _MainTex; | |
float4 _MainTex_ST; | |
float4 _MainTex_TexelSize; | |
float _Radius; | |
v2f vert (appdata v) | |
{ | |
v2f o; | |
o.vertex = UnityObjectToClipPos(v.vertex); | |
o.uv = TRANSFORM_TEX(v.uv, _MainTex); | |
return o; | |
} | |
fixed4 frag (v2f i) : SV_Target | |
{ | |
fixed4 def = tex2D(_MainTex, i.uv); | |
fixed4 col = 0; | |
float tau = 6.28318530718; | |
float quality = 2.0; | |
fixed directions = 14; //if I have these two hard-coded then it can unroll the loop better | |
float scale = _Radius *_MainTex_TexelSize.x; | |
for (float d = 0.0; d<tau; d += tau / directions) { | |
for (float c = 1.0 / quality; c <= 1.0; c += 1.0 / quality) | |
{ | |
col += tex2D(_MainTex, i.uv + float2(cos(d), sin(d))*scale*c); | |
} | |
} | |
col /= directions * quality; | |
return col; | |
} | |
ENDCG | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Shader "Unlit/DrawVHSFrame" | |
{ | |
Properties | |
{ | |
_MainTex ("Texture", 2D) = "white" {} | |
_Even ("Even / Odd", int) = 0 | |
} | |
SubShader | |
{ | |
Tags { "RenderType"="Transparent" } | |
LOD 100 | |
Blend SrcAlpha OneMinusSrcAlpha | |
Pass | |
{ | |
CGPROGRAM | |
#pragma vertex vert | |
#pragma fragment frag | |
#include "UnityCG.cginc" | |
struct appdata | |
{ | |
float4 vertex : POSITION; | |
float2 uv : TEXCOORD0; | |
}; | |
struct v2f | |
{ | |
float2 uv : TEXCOORD0; | |
float4 vertex : SV_POSITION; | |
}; | |
sampler2D _MainTex; | |
float4 _MainTex_ST; | |
float4 _MainTex_TexelSize; | |
fixed _Even; | |
v2f vert (appdata v) | |
{ | |
v2f o; | |
o.vertex = UnityObjectToClipPos(v.vertex); | |
o.uv = TRANSFORM_TEX(v.uv, _MainTex); | |
return o; | |
} | |
//based on https://www.shadertoy.com/view/3lycWz | |
fixed3 rgb2yuv(fixed3 rgb) { | |
float y = 0.299*rgb.r + 0.587*rgb.g + 0.114*rgb.b; | |
return fixed3(y, 0.493*(rgb.b - y), 0.877*(rgb.r - y)); | |
} | |
fixed3 yuv2rgb(fixed3 yuv) { | |
float y = yuv.x; | |
float u = yuv.y; | |
float v = yuv.z; | |
return fixed3( | |
y + 1.0 / 0.877*v, | |
y - 0.39393*u - 0.58081*v, | |
y + 1.0 / 0.493*u | |
); | |
} | |
fixed4 frag (v2f i) : SV_Target | |
{ | |
fixed4 col = tex2D(_MainTex, i.uv); | |
//convert to YUV | |
fixed3 yuv = rgb2yuv(col.rgb); | |
//horizontal blur on chroma channels | |
fixed ts = _MainTex_TexelSize.x; | |
fixed3 blurred = col.rgb * 2.0; | |
for (int c = 1; c < 10; c++) { | |
float weight = 2.0 - c *0.1; //make further pixels have lower weight | |
blurred += ((tex2D(_MainTex, i.uv + fixed2(ts * c, 0)).rgb + tex2D(_MainTex, i.uv + fixed2(-ts * c, 0)).rgb)) * weight; | |
} | |
blurred = blurred / 20; // 9 * 2 (loop) + 2 (col) = 20 | |
fixed3 blurredYUV = rgb2yuv(blurred); | |
//convert back to RGB | |
fixed3 rgb = yuv2rgb(fixed3(yuv.r, blurredYUV.gb)); | |
//interlace | |
fixed opaque = round( ((i.uv.y * _MainTex_TexelSize.w + _Even) / 2.0) %1 ); | |
return fixed4(rgb*lerp(0.7, 1, opaque), lerp(0.1, 1, opaque)); | |
} | |
ENDCG | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
public class ForceAspectRatio : MonoBehaviour { | |
void Start () { | |
GetComponent<Camera>().aspect = 4f / 3f; //you can force 4:3 aspect ratio on a camera rendering to a render texture | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
public class Interlacing : MonoBehaviour { | |
[SerializeField] | |
private Material evenMaterial; //material that renders all even lines: DrawVHSFrame with _Even set to 1 | |
[SerializeField] | |
private Material oddMaterial; //material that renders all odd lines: DrawVHSFrame with _Even set to 0 | |
[SerializeField] | |
private RenderTexture source; //texture the in-game camera is rendering to | |
[SerializeField] | |
private RenderTexture dest; //texture you display on-screen | |
private bool evenField = false; | |
void Start () { | |
Application.targetFrameRate = 60; | |
} | |
void Update () { | |
//alternates between updating even and odd fields every frame | |
Graphics.Blit(source, dest, evenField?evenMaterial:oddMaterial, -1); | |
evenField = !evenField; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment