图像

我刚刚开始了一项新项目,并决定采用更为老派的风格。因此,我决定在材质上贴上一个低分辨率的渲染纹理,然后将材质应用到画布上的图像元素上。问题是,当我启用我的自定义着色器时(旨在限制渲染纹理显示的颜色和其他视觉元素的数量),会产生一些奇怪的视觉艺术品。如有需要,我可以提供更多信息。以下是我的 .shader 文件内容。图像元素只是被拉伸到适应屏幕的大小,我设置了一个 1920x1080 的固定分辨率。

Shader "Custom/Bitcrush"
{
    Properties
    {
        [MainTexture] _MainTex ("Texture", 2D) = "white" {}

        _PixelSize ("Pixel Size", Range(1, 64)) = 4
        _ColorLevels ("Color Levels", Range(2, 64)) = 8

        _Brightness ("Brightness", Range(0, 2)) = 1
        _Contrast ("Contrast", Range(0, 2)) = 1
    }

    SubShader
    {
        Tags
        {
            "RenderPipeline" = "UniversalPipeline"
            "RenderType" = "Opaque"
            "Queue" = "Geometry"
        }

        Pass
        {
            Name "Bitcrush"

            HLSLPROGRAM

            #pragma vertex vert
            #pragma fragment frag

            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"

            struct Attributes
            {
                float4 positionOS : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct Varyings
            {
                float4 positionHCS : SV_POSITION;
                float2 uv : TEXCOORD0;
            };

            TEXTURE2D(_MainTex);
            SAMPLER(sampler_MainTex);

            CBUFFER_START(UnityPerMaterial)

                float4 _MainTex_ST;

                float _PixelSize;
                float _ColorLevels;

                float _Brightness;
                float _Contrast;

            CBUFFER_END


            Varyings vert(Attributes input)
            {
                Varyings output;

                output.positionHCS =
                    TransformObjectToHClip(input.positionOS.xyz);

                output.uv =
                    TRANSFORM_TEX(input.uv, _MainTex);

                return output;
            }


            half4 frag(Varyings input) : SV_Target
            {
                float2 uv = input.uv;

                float2 uvDDX = ddx(uv);
                float2 uvDDY = ddy(uv);

                float2 pixelUV =
                    floor(uv * _PixelSize) / _PixelSize;

                pixelUV += 0.5 / _PixelSize;

                half4 col = SAMPLE_TEXTURE2D_GRAD(
                    _MainTex,
                    sampler_MainTex,
                    pixelUV,
                    uvDDX,
                    uvDDY
                );

                col.rgb *= _Brightness;

                col.rgb =
                    (col.rgb - 0.5) * _Contrast + 0.5;

                col.rgb = saturate(col.rgb);

                col.rgb =
                    floor(
                        col.rgb * (_ColorLevels - 1.0) + 0.5
                    )
                    / (_ColorLevels - 1.0);


                return col;
            }

            ENDHLSL
        }
    }
}