9D-Tony / UnitySmoothPixelFiltering

A unity shader for smooth pixel filtering, based on CptPotato's smooth filtering
MIT License
80 stars 7 forks source link

JitterFreeLit Shader, just for you! #1

Open digiwombat opened 2 years ago

digiwombat commented 2 years ago

Howdy ho, neighbor.

I'm lazy and don't want to bother making a PR, but I edited the URP 2D Lit shader to include the JitterFree logic.

Free free to roll it into the repo if you want. It's working as expected for me on 2021.2.8f.

Here's the gist:
https://gist.github.com/digiwombat/1991353eadaf918291e8a199694fcc7c

9D-Tony commented 2 years ago

Thanks for this. I've tried testing this on Unity 2020.3.12f1 but there seems to be a bug with a variable SurfaceData2D. There might be a workaround to this, if not then I'd have to upgrade my unity version and require users that want to use this shader with URP to be on at least unity version 2021.2.8f.

digiwombat commented 2 years ago

I know that added Renderer features to the 2D renderer with 2021.2, so any 2021.2 version would PROBABLY work, I'd guess.

I don't have any older installs around at the moment, but I'd imagine any URP, replacing whatever SAMPLE_TEXTURE2D is doing the default processing in the first shader pass. (half4 CombinedShapeLightFragment(Varyings i) : SV_Target in the case of the 2021.2 version)

Also, you need to add a few things up in the TEXTURE2D area, since it makes a different sampler which doesn't play nice with code. They're functionizing it or something. I'm not a big shader guy.

But basically just make the first pass variable stuff look like this after the LightingUtility.hlsl include:

//TEXTURE2D(_MainTex);
//SAMPLER(sampler_MainTex);
TEXTURE2D(_MaskTex);
SAMPLER(sampler_MaskTex);
sampler2D _MainTex;
half4 _MainTex_ST;
float4 _MainTex_TexelSize;

Then drop in the code for the smoothsample and replace two lines in the combined shape frag shader.

Here's the basically untouched code, save for two lines:

half4 CombinedShapeLightFragment(Varyings i) : SV_Target
{
    const half4 main = i.color * texturePointSmooth(_MainTex, i.uv);
    const half4 mask = texturePointSmooth(_MainTex, i.uv);
    SurfaceData2D surfaceData;
    InputData2D inputData;

    InitializeSurfaceData(main.rgb, main.a, mask, surfaceData);
    InitializeInputData(i.uv, i.lightingUV, inputData);

    return CombinedShapeLightShared(surfaceData, inputData);
}

Otherwise, everything is untouched in the URP Sprite-Lit-Default.

digiwombat commented 2 years ago

For anyone else browsing through, you can also do a ShaderGraph version by just running the _MainTex and UV through the custom function.

image

float2 size;
size.x = _MainTex_TexelSize.z;
size.y = _MainTex_TexelSize.w;

float2 pixel = float2(1.0,1.0) / size;

uvs -= pixel * float2(0.5,0.5);
float2 uv_pixels = uvs * size;
float2 delta_pixel = frac(uv_pixels) - float2(0.5,0.5);

float2 ddxy = fwidth(uv_pixels);
float2 mip = log2(ddxy) - 0.5;

float2 clampedUV = uvs + (clamp(delta_pixel / ddxy, 0.0, 1.0) - delta_pixel) * pixel;
_out = tex2Dlod(tex, float4(clampedUV,0, min(mip.x, mip.y)));
Jusimito commented 2 years ago

Hello there! Im trying to implement this shader graph version but it doesnt seems to work. I'm at 2020.3.28f1 and 10.8.1 of ShaderGraph.

image

And this is the custom node function:

image

I have tried to use a HLSL file to create the function and I have check the precision properties and stuff, so any idea will be very appreciated.

9D-Tony commented 2 years ago

Hey, I believe you would have to split the the alpha like in the above example: image

Also I don't know what the texel size is doing in your shader graph, I don't think it would be used since it is already been accessed by the top lines in the custom shader:

float2 size;
size.x = _MainTex_TexelSize.z;
size.y = _MainTex_TexelSize.w;