Unity Shader - 故障艺术之 - Glitch Art - ImageBlock + Split RGB (区块强度 + 分离通道颜色的故障效果)

文章目录

  • 思路
  • Shader
  • 运行效果
  • Back Project
  • References


参考:- 高品质后处理:十种故障艺术(Glitch Art)算法的总结与实现 - 错位图块故障(Image Block Glitch)

Image Block + Split RGB 通道只是其一一种效果


思路

基于前一篇的 Split RGB Glitch:
Split RGB 还是比较简单的

  • 现有类似 noise 的 抖动函数
  • 使用 noise 得到的值作为 R, B 通道的偏移采样

那么这一篇就是在 Unity Shader - 故障艺术之 - Glitch Art - Split RGB (分离通道颜色的故障效果) 的基础上 添加一个 ImageBlock 的强度控制即可:

float ImageBlockIntensity(v2f i)
{
    float2 size = lerp(1, _MainTex_TexelSize.xy, 1 - _BlockSize);
    size = floor((i.uv) / size);
    float noiseBlock = randomNoise(size);
    float displaceNoise = pow(noiseBlock.x, _BlockPow.x) * pow(noiseBlock.x, _BlockPow.y);
    return displaceNoise;
}

ImageBlockIntensity() 函数的值返回可以看到效果:
Unity Shader - 故障艺术之 - Glitch Art - ImageBlock + Split RGB (区块强度 + 分离通道颜色的故障效果)_第1张图片

但是有与该 noise 过于白噪

所以可以使用一个 1 维 noise 来改变整体强弱:

R 通道我们可以使用:

return randomNoise(13.0);

B 通道我们可以使用:

return randomNoise(123.0);

效果类似如下的平滑抖动的整体强度:
Unity Shader - 故障艺术之 - Glitch Art - ImageBlock + Split RGB (区块强度 + 分离通道颜色的故障效果)_第2张图片

然后两者结合:

return ImageBlockIntensity(v2f i) * randomNoise(123.0);

效果如下:
Unity Shader - 故障艺术之 - Glitch Art - ImageBlock + Split RGB (区块强度 + 分离通道颜色的故障效果)_第3张图片

然后,R,B 通道分别使用该 noise 强度来控制 Split RGB 即可得到比较好的效果


Shader

// jave.lin 2021/06/09
// 测试 图像块 故障后效
// References : 高品质后处理:十种故障艺术(Glitch Art)算法的总结与实现
// https://qianmo.blog.csdn.net/article/details/106753402

Shader "Test/PP/Glitch/ImageBlock"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _Amplitude ("Amplitude", Range(-1, 0)) = -0.15
        _Amount ("Amount", Range(-5, 5)) = 0.5
        _BlockSize ("Block Size", Range(0, 1)) = 0.05
        _Speed ("Speed", Range(0, 100)) = 10
        _BlockPow ("Block Size Pow", Vector) = (3, 3, 0, 0)
    }
    SubShader
    {
        // No culling or depth
        Cull Off ZWrite Off ZTest Always

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                float4 vertex : SV_POSITION;
            };

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = v.uv;
                return o;
            }

            sampler2D _MainTex;
            float4 _MainTex_TexelSize;
            float _Amplitude;
            float _Amount;
            float _BlockSize;
            float _Speed;
            float4 _BlockPow;

            //inline float rand(float n)
            //{
            //    return frac(sin(n) * 13758.5453123 * 0.01);
            //}

            //inline float randomNoise(float seed)
            //{
            //    return rand(float2(seed, 1.0));
            //}

            //inline float randomNoise(float x, float y)
            //{
            //    return frac(sin(dot(float2(x, y), float2(12.9898, 78.233))) * 43758.5453);
            //}

            inline float randomNoise(float2 seed)
            {
                return frac(sin(dot(seed * floor(_Time.y * _Speed), float2(17.13, 3.71))) * 43758.5453123);
            }

            float Noise()
            {
                float _TimeX = _Time.y;
                float splitAmout = (1.0 + sin(_TimeX * 6.0)) * 0.5;
                splitAmout *= 1.0 + sin(_TimeX * 16.0) * 0.5;
                splitAmout *= 1.0 + sin(_TimeX * 19.0) * 0.5;
                splitAmout *= 1.0 + sin(_TimeX * 27.0) * 0.5;
                splitAmout = pow(splitAmout, _Amplitude);
                splitAmout *= (0.05 * _Amount);
                return splitAmout;
            }

            float ImageBlockIntensity(v2f i)
            {
                //float2 block = randomNoise(floor(i.uv * _BlockSize * 100));
                //return (block.x);
                float2 size = lerp(1, _MainTex_TexelSize.xy, 1 - _BlockSize);
                size = floor((i.uv) / size);
                float noiseBlock = randomNoise(size);
                float displaceNoise = pow(noiseBlock.x, _BlockPow.x) * pow(noiseBlock.x, _BlockPow.y);
                return displaceNoise;
            }

            half4 SplitRGB(v2f i)
            {
                float splitAmout = Noise() * ImageBlockIntensity(i);
                half3 finalColor;
                finalColor.r = tex2D(_MainTex, fixed2(i.uv.x + splitAmout * randomNoise(13.0), i.uv.y)).r;
                finalColor.g = tex2D(_MainTex, i.uv).g;
                finalColor.b = tex2D(_MainTex, fixed2(i.uv.x - splitAmout * randomNoise(123.0), i.uv.y)).b;

                return half4(finalColor, 1.0);
            }

            fixed4 frag(v2f i) : SV_Target
            {
                return SplitRGB(i);
            }
            ENDCG
        }
    }
}


运行效果


Back Project

不公开项目(因设置以前公司使用的资源,就自己备份学习、回顾用)

TestingImageBlockGlitch_unity 2019.4.0f1


References

  • 高品质后处理:十种故障艺术(Glitch Art)算法的总结与实现 - 错位图块故障(Image Block Glitch)

你可能感兴趣的:(unity,unity-shader,GlitchArt,故障艺术,ImageBlock)