├── README.md ├── gradient.png ├── rollingshutter.gif ├── maskBlit.shader ├── RollingShutter.cs └── maskBlit.mat /README.md: -------------------------------------------------------------------------------- 1 | ![preview gif](rollingshutter.gif) 2 | -------------------------------------------------------------------------------- /gradient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmacmillan/RollingShutter/HEAD/gradient.png -------------------------------------------------------------------------------- /rollingshutter.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cmacmillan/RollingShutter/HEAD/rollingshutter.gif -------------------------------------------------------------------------------- /maskBlit.shader: -------------------------------------------------------------------------------- 1 | Shader "Unlit/maskBlit" 2 | { 3 | Properties 4 | { 5 | _MainTex ("Texture", 2D) = "white" {} 6 | _MaskTex ("Mask", 2D) = "white" {} 7 | } 8 | SubShader 9 | { 10 | Tags { "RenderType"="Opaque" } 11 | LOD 100 12 | 13 | Pass 14 | { 15 | CGPROGRAM 16 | #pragma vertex vert 17 | #pragma fragment frag 18 | 19 | #include "UnityCG.cginc" 20 | 21 | struct appdata 22 | { 23 | float4 vertex : POSITION; 24 | float2 uv : TEXCOORD0; 25 | }; 26 | 27 | struct v2f 28 | { 29 | float2 uv : TEXCOORD0; 30 | float4 vertex : SV_POSITION; 31 | }; 32 | 33 | sampler2D _MainTex; 34 | sampler2D _MaskTex; 35 | float4 _MainTex_ST; 36 | float _MaskPercentage; 37 | 38 | v2f vert (appdata v) 39 | { 40 | v2f o; 41 | o.vertex = UnityObjectToClipPos(v.vertex); 42 | o.uv = TRANSFORM_TEX(v.uv, _MainTex); 43 | return o; 44 | } 45 | 46 | fixed4 frag (v2f i) : SV_Target 47 | { 48 | //fixed4 col = tex2D(_MaskTex, i.uv); 49 | //if (col.r < _MaskPercentage)//commented out to avoid issues with 8 bit per channel textures, could be fixed by using higher precision textures 50 | if (i.uv.y<_MaskPercentage) 51 | discard; 52 | return tex2D(_MainTex, i.uv); 53 | } 54 | ENDCG 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /RollingShutter.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEngine.Rendering; 5 | 6 | public class RollingShutter : MonoBehaviour 7 | { 8 | public Camera sceneCamera; 9 | public Camera compositorCamera; 10 | public Material maskMaterial; 11 | public int temporalResolution = 100; 12 | public RenderTextureFormat textureFormat = RenderTextureFormat.RGB565; 13 | 14 | private CommandBuffer commandBuffer; 15 | private List renderTextures = new List(); 16 | 17 | private void Start() 18 | { 19 | QualitySettings.vSyncCount = 2; 20 | Application.targetFrameRate = 60; 21 | int w = Screen.width; 22 | int h = Screen.height; 23 | for (int i = 0; i < temporalResolution; i++) 24 | { 25 | renderTextures.Add(new RenderTexture(w, h, 0, textureFormat, 0)); 26 | } 27 | commandBuffer = new CommandBuffer(); 28 | commandBuffer.name = "Rolling shutter effect"; 29 | compositorCamera.AddCommandBuffer(CameraEvent.AfterEverything, commandBuffer); 30 | } 31 | 32 | void Update() 33 | { 34 | renderTextures.Insert(0, renderTextures[renderTextures.Count - 1]); 35 | renderTextures.RemoveAt(renderTextures.Count - 1); 36 | sceneCamera.targetTexture=renderTextures[0]; 37 | 38 | commandBuffer.Clear(); 39 | for (int i = 0; i < temporalResolution; i++) 40 | { 41 | commandBuffer.SetGlobalFloat("_MaskPercentage",(float)i/temporalResolution); 42 | commandBuffer.Blit(renderTextures[i],BuiltinRenderTextureType.CameraTarget,maskMaterial);//the target is the screen 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /maskBlit.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: maskBlit 11 | m_Shader: {fileID: 4800000, guid: 55d805a8e3fa66946b6a5a0747de5d01, type: 3} 12 | m_ShaderKeywords: 13 | m_LightmapFlags: 4 14 | m_EnableInstancingVariants: 0 15 | m_DoubleSidedGI: 0 16 | m_CustomRenderQueue: -1 17 | stringTagMap: {} 18 | disabledShaderPasses: [] 19 | m_SavedProperties: 20 | serializedVersion: 3 21 | m_TexEnvs: 22 | - _BumpMap: 23 | m_Texture: {fileID: 0} 24 | m_Scale: {x: 1, y: 1} 25 | m_Offset: {x: 0, y: 0} 26 | - _DetailAlbedoMap: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | - _DetailMask: 31 | m_Texture: {fileID: 0} 32 | m_Scale: {x: 1, y: 1} 33 | m_Offset: {x: 0, y: 0} 34 | - _DetailNormalMap: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | - _EmissionMap: 39 | m_Texture: {fileID: 0} 40 | m_Scale: {x: 1, y: 1} 41 | m_Offset: {x: 0, y: 0} 42 | - _MainTex: 43 | m_Texture: {fileID: 0} 44 | m_Scale: {x: 1, y: 1} 45 | m_Offset: {x: 0, y: 0} 46 | - _MaskTex: 47 | m_Texture: {fileID: 2800000, guid: a115801a615d5e8459d0a7dbac24b887, type: 3} 48 | m_Scale: {x: 1, y: 1} 49 | m_Offset: {x: 0, y: 0} 50 | - _MetallicGlossMap: 51 | m_Texture: {fileID: 0} 52 | m_Scale: {x: 1, y: 1} 53 | m_Offset: {x: 0, y: 0} 54 | - _OcclusionMap: 55 | m_Texture: {fileID: 0} 56 | m_Scale: {x: 1, y: 1} 57 | m_Offset: {x: 0, y: 0} 58 | - _ParallaxMap: 59 | m_Texture: {fileID: 0} 60 | m_Scale: {x: 1, y: 1} 61 | m_Offset: {x: 0, y: 0} 62 | m_Floats: 63 | - _BumpScale: 1 64 | - _Cutoff: 0.5 65 | - _DetailNormalMapScale: 1 66 | - _DstBlend: 0 67 | - _GlossMapScale: 1 68 | - _Glossiness: 0.5 69 | - _GlossyReflections: 1 70 | - _Metallic: 0 71 | - _Mode: 0 72 | - _OcclusionStrength: 1 73 | - _Parallax: 0.02 74 | - _SmoothnessTextureChannel: 0 75 | - _SpecularHighlights: 1 76 | - _SrcBlend: 1 77 | - _UVSec: 0 78 | - _ZWrite: 1 79 | m_Colors: 80 | - _Color: {r: 1, g: 1, b: 1, a: 1} 81 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 82 | m_BuildTextureStacks: [] 83 | --------------------------------------------------------------------------------