├── LowRes.cs ├── LowRes.shader ├── LowResPass.cs ├── LowResRenderFeature.cs ├── README.md └── imgsForReadme ├── pp setup.png ├── pp.png ├── renderer.png └── scene.png /LowRes.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEngine.Rendering; 3 | using UnityEngine.Rendering.Universal; 4 | 5 | public class LowRes : VolumeComponent, IPostProcessComponent 6 | { 7 | public BoolParameter on = new BoolParameter(false); 8 | 9 | public IntParameter height = new IntParameter(180); 10 | 11 | public bool IsActive() => (bool)on; 12 | 13 | public bool IsTileCompatible() => false; 14 | } 15 | -------------------------------------------------------------------------------- /LowRes.shader: -------------------------------------------------------------------------------- 1 | Shader "PostEffect/LowRes" 2 | { 3 | Properties 4 | { 5 | _MainTex("Texture", 2D) = "white" {} 6 | } 7 | 8 | SubShader 9 | { 10 | Cull Off ZWrite Off ZTest Always 11 | Tags { "RenderPipeline" = "UniversalPipeline"} 12 | Pass 13 | { 14 | CGPROGRAM 15 | #pragma vertex Vert 16 | #pragma fragment Frag 17 | 18 | sampler2D _MainTex; 19 | int _Height; 20 | int _Width; 21 | 22 | struct appdata 23 | { 24 | float4 vertex : POSITION; 25 | float2 uv : TEXCOORD0; 26 | }; 27 | 28 | struct v2f 29 | { 30 | float2 uv : TEXCOORD0; 31 | float4 vertex : SV_POSITION; 32 | }; 33 | 34 | v2f Vert(appdata v) 35 | { 36 | v2f o; 37 | o.vertex = UnityObjectToClipPos(v.vertex); 38 | o.uv = v.uv; 39 | return o; 40 | } 41 | 42 | fixed4 Frag (v2f i) : SV_Target 43 | { 44 | float2 uv = i.uv; 45 | uv.x *= _Width; 46 | uv.y *= _Height; 47 | uv.x = round(uv.x); 48 | uv.y = round(uv.y); 49 | uv.x /= _Width; 50 | uv.y /= _Height; 51 | fixed4 col = tex2D(_MainTex, uv); 52 | return col; 53 | } 54 | ENDCG 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /LowResPass.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEngine.Rendering; 5 | using UnityEngine.Rendering.LWRP; 6 | using UnityEngine.Experimental.Rendering.LWRP; 7 | using UnityEngine.Experimental.Rendering.Universal; 8 | using UnityEngine.Rendering.Universal; 9 | 10 | public class LowResPass : ScriptableRenderPass 11 | { 12 | static readonly string k_RenderTag = "Render LowRes Effects"; 13 | static readonly int MainTexId = Shader.PropertyToID("_MainTex"); 14 | static readonly int TempTargetId = Shader.PropertyToID("LowRes"); 15 | 16 | static readonly int HeightId = Shader.PropertyToID("_Height"); 17 | static readonly int WidthId = Shader.PropertyToID("_Width"); 18 | 19 | LowRes lowRes; 20 | Material lowResMaterial; 21 | RenderTargetIdentifier currentTarget; 22 | 23 | public LowResPass(RenderPassEvent evt) 24 | { 25 | renderPassEvent = evt; 26 | var shader = Shader.Find("PostEffect/LowRes"); 27 | if (shader == null) 28 | { 29 | Debug.LogError("Shader not found."); 30 | return; 31 | } 32 | lowResMaterial = CoreUtils.CreateEngineMaterial(shader); 33 | } 34 | 35 | public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) 36 | { 37 | if (lowResMaterial == null) 38 | { 39 | Debug.LogError("Material not created."); 40 | return; 41 | } 42 | 43 | if (!renderingData.cameraData.postProcessEnabled) return; 44 | 45 | var stack = VolumeManager.instance.stack; 46 | lowRes = stack.GetComponent(); 47 | if (lowRes == null) { return; } 48 | if (!lowRes.IsActive()) { return; } 49 | 50 | var cmd = CommandBufferPool.Get(k_RenderTag); 51 | Render(cmd, ref renderingData); 52 | context.ExecuteCommandBuffer(cmd); 53 | CommandBufferPool.Release(cmd); 54 | } 55 | 56 | public void Setup(in RenderTargetIdentifier currentTarget) 57 | { 58 | this.currentTarget = currentTarget; 59 | } 60 | 61 | void Render(CommandBuffer cmd, ref RenderingData renderingData) 62 | { 63 | ref var cameraData = ref renderingData.cameraData; 64 | var source = currentTarget; 65 | int destination = TempTargetId; 66 | 67 | float ratio = ((float)cameraData.camera.scaledPixelWidth) / (float)cameraData.camera.scaledPixelHeight; 68 | 69 | var w = cameraData.camera.scaledPixelWidth; 70 | var h = cameraData.camera.scaledPixelHeight; 71 | 72 | lowResMaterial.SetInt(HeightId, (int)lowRes.height); 73 | lowResMaterial.SetInt(WidthId, Mathf.RoundToInt((int)lowRes.height * ratio)); 74 | 75 | int shaderPass = 0; 76 | cmd.SetGlobalTexture(MainTexId, source); 77 | cmd.GetTemporaryRT(destination, w, h, 0, FilterMode.Point, RenderTextureFormat.Default); 78 | cmd.Blit(source, destination); 79 | cmd.Blit(destination, source, lowResMaterial, shaderPass); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /LowResRenderFeature.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine.Rendering.Universal; 2 | 3 | public class LowResRenderFeature : ScriptableRendererFeature 4 | { 5 | LowResPass lowResPass; 6 | 7 | public override void Create() 8 | { 9 | lowResPass = new LowResPass(RenderPassEvent.BeforeRenderingPostProcessing); 10 | } 11 | 12 | public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) 13 | { 14 | lowResPass.Setup(renderer.cameraColorTarget); 15 | renderer.EnqueuePass(lowResPass); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LowRes 2 | Low resolution effect for Unity URP PPv3 3 | 4 | 5 | 6 | Add LowRes RendererFeature to your forward renderer 7 | 8 | 9 | 10 | Add LowRes effect in post processing volume 11 | 12 | 13 | 14 | Height - screen height in pixels, width depends on aspect ratio 15 | 16 | 17 | 18 | You done 19 | 20 | Scene from screenshot 21 | https://assetstore.unity.com/packages/3d/environments/landscapes/rpg-poly-pack-lite-148410 22 | -------------------------------------------------------------------------------- /imgsForReadme/pp setup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dener1111/LowRes/d769ff5f668b338ca1626988f8139c5f7f43181a/imgsForReadme/pp setup.png -------------------------------------------------------------------------------- /imgsForReadme/pp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dener1111/LowRes/d769ff5f668b338ca1626988f8139c5f7f43181a/imgsForReadme/pp.png -------------------------------------------------------------------------------- /imgsForReadme/renderer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dener1111/LowRes/d769ff5f668b338ca1626988f8139c5f7f43181a/imgsForReadme/renderer.png -------------------------------------------------------------------------------- /imgsForReadme/scene.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Dener1111/LowRes/d769ff5f668b338ca1626988f8139c5f7f43181a/imgsForReadme/scene.png --------------------------------------------------------------------------------