├── imgsForReadme
├── pp.png
├── scene.png
├── pp setup.png
└── renderer.png
├── LowRes.cs
├── LowResRenderFeature.cs
├── README.md
├── LowRes.shader
└── LowResPass.cs
/imgsForReadme/pp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dener1111/LowRes/HEAD/imgsForReadme/pp.png
--------------------------------------------------------------------------------
/imgsForReadme/scene.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dener1111/LowRes/HEAD/imgsForReadme/scene.png
--------------------------------------------------------------------------------
/imgsForReadme/pp setup.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dener1111/LowRes/HEAD/imgsForReadme/pp setup.png
--------------------------------------------------------------------------------
/imgsForReadme/renderer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dener1111/LowRes/HEAD/imgsForReadme/renderer.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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------