Last active
September 23, 2023 23:00
-
-
Save joshcamas/a9e39b6401d12538a6af19a8cd79f43e to your computer and use it in GitHub Desktop.
Distant Pixelize Unity Effect
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 "Ardenfall/Effects/DistantPixelize" | |
{ | |
HLSLINCLUDE | |
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" | |
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl" | |
float _MaxPixelSize; | |
float _MinPixelSize; | |
float _MaxDistance; | |
TEXTURE2D_X(_MainTex); | |
SAMPLER(sampler_MainTex); | |
float4 _MainTex_TexelSize; | |
struct Attributes | |
{ | |
float4 positionOS : POSITION; | |
float2 uv : TEXCOORD0; | |
}; | |
struct Varyings { | |
float4 positionCS : POSITION; | |
float2 uv : TEXCOORD0; | |
}; | |
Varyings Vert(Attributes input) { | |
Varyings output; | |
UNITY_SETUP_INSTANCE_ID(input); | |
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output); | |
output.positionCS = TransformObjectToHClip(input.positionOS.xyz); | |
output.uv.xy = input.uv; | |
return output; | |
} | |
float2 CalculatePixelUV(float2 uv, float pixelSize) | |
{ | |
float aspect = _ScreenParams.y / _ScreenParams.x; | |
// Round the UV coordinates to the calculated pixel size | |
float x = round(uv.x / (pixelSize * aspect)) * (pixelSize * aspect); | |
float y = round(uv.y / pixelSize) * pixelSize; | |
return float2(x,y); | |
} | |
float CalculateLinearDepthURP(float2 depthUv) | |
{ | |
#if UNITY_REVERSED_Z | |
float depth = SampleSceneDepth(depthUv); | |
#else | |
float depth = lerp(UNITY_NEAR_CLIP_VALUE, 1, SampleSceneDepth(depthUv)); | |
#endif | |
depth = LinearEyeDepth(depth, _ZBufferParams); | |
return depth; | |
} | |
float4 Frag(Varyings i) : SV_Target | |
{ | |
//Sample depth using the largest pixel size. | |
//This does introduce some artifacts, but also fixes pixels from not being square | |
float2 depthUv = CalculatePixelUV(i.uv, _MaxPixelSize); | |
float depth = CalculateLinearDepthURP(depthUv); | |
if(depth > _MaxDistance) | |
depth = _MaxDistance; | |
//Calculate pixel size based on depth | |
float depthFactor = saturate((_MaxDistance - depth) / _MaxDistance); | |
float pixelSize = lerp(_MinPixelSize, _MaxPixelSize, depthFactor); | |
//Fix pixel size by making it a half step of the max pixel size. (If the max size is 1, then it could be 1, 0.5, 0.25, 0.125, etc) | |
//This stops pixels from looking extremely strange | |
float numHalves = log2(_MaxPixelSize / pixelSize); | |
pixelSize = _MaxPixelSize / pow(2.0, round(numHalves)); | |
//Calculate pixelized UV | |
float2 pixelUV = CalculatePixelUV(i.uv, pixelSize); | |
return SAMPLE_TEXTURE2D_X(_MainTex, sampler_MainTex, pixelUV); | |
} | |
ENDHLSL | |
SubShader | |
{ | |
Cull Off ZWrite Off ZTest Always | |
Pass | |
{ | |
Name "Pixelize" | |
HLSLPROGRAM | |
#pragma vertex Vert | |
#pragma fragment Frag | |
ENDHLSL | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment