您当前所在位置: > 爆料站 > 君子堂

高品质后处理:十种故障艺术(Glitch Art)算法的总结与实现

时间:2020-06-18 16:12:04  来源:  作者:网络

故障艺术(Glitch Art),作为赛博朋克(Cyberpunk)艺术风格的核心元素之一,是一种是将数字设备的软硬件故障引起的破碎变形图像,经过艺术加工而成的一种先锋视觉艺术表现形式。近年来,故障艺术已经成为了赛博朋克风格的电影和游戏作品中主要的艺术风格之一。

图 《赛博朋克 2077》 带有强烈故障艺术风格的Logo @ CD Projekt @2019 E3展

而本文,对十种主流故障艺术(Glitch Art)系列后处理算法的原理和实现方式进行了总结,对故障艺术风格的算法实现要点进行了提炼,并提供了对应算法在Unity引擎下的一个或多个版本的实现源码。

这十种故障艺术(Glitch Art)后处理特效分别为:

  • RGB颜色分离故障(RGB Split Glitch)
  • 错位图块故障(Image Block Glitch)
  • 错位线条故障(Line Block Glitch)
  • 图块抖动故障(Tile Jitter Glitch)
  • 扫描线抖动故障(Scan Line Jitter Glitch)
  • 数字条纹故障(Digital Stripe Glitch)
  • 模拟噪点故障(Analog Noise Glitch)
  • 屏幕跳跃故障(Screen Jump Glitch)
  • 屏幕抖动故障(Screen Shake Glitch)
  • 波动抖动故障(Wave Jitter Glitch)


另外,本文涉及的十种故障艺术(Glitch Art)后处理的实现源码,都已收录于本人开源的后处理算法库XPL中。

关于XPL : Unity引擎的高品质后处理库

X-PostProcessing Libray,简称XPL,是本人开发的Unity引擎下的高品质开源后处理算法库,旨在提供业界主流的高品质后处理特效的完整解决方案,目前已完美支持Unity Post-processing Stack v2。后续也将提供对Unity引擎URP/LWRP/HDRP的兼容支持。

【GitHub地址】:
https://github.com/QianMo/X-PostProcessing-Library


截止本文发表,目前已以开源的形式放出了17种图像模糊型后处理算法、10种像素化型后处理算法、9种边缘检测型后处理算法、17种故障艺术型后处理算法。而随着后续更多内容的公开,X-PostProcessing Libray将成型为一个具有100+种后处理特效的高品质后处理开源算法库。

在开始正文之前,不妨先简单认识一下赛博朋克与故障艺术这两种带有强烈科技感的艺术风格,以及他们在电影和游戏行业中的应用情况。

零、赛博朋克与故障艺术

赛博朋克(Cyberpunk),最早起源于上世纪六七十年代,作为未来主义科幻小说/电影/游戏的一个品类,核心理念在于低端生活与高等科技的结合。人工智能、虚拟现实、基因工程、黑客技术、反乌托邦、电脑生化、都市与贫民窟、故障艺术、霓虹灯等都是赛博朋克的主流艺术表现形式。

故障艺术(Glitch Art),一种是将数字设备的软硬件故障引起的破碎变形图像,经过艺术加工而成的一种先锋视觉艺术表现。故障艺术的艺术表现核心形式在于图像的失真、破碎、错位、形变,以及颜色的失真、错位,并伴有条纹图形的辅助。

无论是电影领域的《黑客帝国》、《银翼杀手》、《银翼杀手2077》、《攻壳机动队》等作品,还是游戏领域的《赛博朋克2077》,《杀出重围》等作品,都带有非常浓厚的赛博朋克风格。而在这些作品中,都能找到故障艺术的身影。

图 电影《攻壳机动队》中的故障艺术表现形式

图 电影《银翼杀手2049》中的故障艺术表现形式

图《赛博朋克2077》中的故障艺术表现形式 @ CD Projekt

图 《看门狗2》中的故障艺术表现形式 @ Ubisoft

这里也放一段包含多种故障艺术(Glitch Art)元素的《赛博朋克2077》 2019 E3展预告片段:


《赛博朋克2077》 2019 E3展预告片段


以及一个发布于2013年的《赛博朋克2077》早期宣传片:


《赛博朋克2077》 2013预告片


OK,下面开始正文,对10种主流故障艺术(Glitch Art)后处理的算法以及原理进行总结。

一、RGB颜色分离故障(RGB Split Glitch)

RGB颜色分离故障(RGB Split Glitch),也称颜色偏移故障(Color Shift Glitch),是故障艺术中比较常见的表达形式之一。例如,抖音短视频App的Icon,即是RGB颜色分离故障艺术风格影响下的作品,给整体产品带来了潮流与年轻的气息:


RGB颜色分离故障(RGB Split Glitch),实现算法的主要要点在于红绿蓝三个通道采用不同的uv偏移值进行分别采样。一般而言,会在RGB三个颜色通道中,选取一个通道采用原始uv值,另外两个通道进行uv抖动后再进行采样。一个经过性能优化的实现版本Shader代码如下:

  1. float randomNoise(float x, float y)
  2. {
  3.     return frac(sin(dot(float2(x, y), float2(12.9898, 78.233))) * 43758.5453);
  4. }

  5. half4 Frag_Horizontal(VaryingsDefault i) : SV_Target
  6. {
  7.     float splitAmount = _Indensity * randomNoise(_TimeX, 2);

  8.     half4 ColorR = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, float2(i.texcoord.x + splitAmount, i.texcoord.y));
  9.     half4 ColorG = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.texcoord);
  10.     half4 ColorB = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, float2(i.texcoord.x - splitAmount, i.texcoord.y));

  11.     return half4(ColorR.r, ColorG.g, ColorB.b, 1);
  12. }
复制代码


上述代码中的randomNoise函数在之前的文章《高品质后处理:十种图像模糊算法的总结与实现》的粒状模糊(Grainy Blur)中有提到一个简化版的实现。本文在则采用了基于frac方法(返回输入数值的小数部分)和三角函数,配合dot方法的封装实现。

上述代码,得到的渲染表现如下:


详细实现源码可见:
https://github.com/QianMo/X-PostProcessing-Library/tree/master/Assets/X-PostProcessing/Effects/GlitchRGBSplitV4

另外,可以基于三角函数和pow方法控制抖动的间隔、幅度,以及抖动的曲线:

  1. half4 Frag_Horizontal(VaryingsDefault i): SV_Target
  2. {
  3.     float splitAmout = (1.0 + sin(_TimeX * 6.0)) * 0.5;
  4.     splitAmout *= 1.0 + sin(_TimeX * 16.0) * 0.5;
  5.     splitAmout *= 1.0 + sin(_TimeX * 19.0) * 0.5;
  6.     splitAmout *= 1.0 + sin(_TimeX * 27.0) * 0.5;
  7.     splitAmout = pow(splitAmout, _Amplitude);
  8.     splitAmout *= (0.05 * _Amount);

  9.     half3 finalColor;
  10.     finalColor.r = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, fixed2(i.texcoord.x + splitAmout, i.texcoord.y)).r;
  11.     finalColor.g = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.texcoord).g;
  12.     finalColor.b = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, fixed2(i.texcoord.x - splitAmout, i.texcoord.y)).b;

  13.     finalColor *= (1.0 - splitAmout * 0.5);

  14.     return half4(finalColor, 1.0);
  15. }
复制代码

得到的渲染表现如下:


此版本的实现源码可见:
https://github.com/QianMo/X-PostProcessing-Library/tree/master/Assets/X-PostProcessing/Effects/GlitchRGBSplitV2

另外,在XPL(X-PostProcessing-Library)中供实现了5种不同版本的Glitch RGB Split后处理特效,以满足不同情形下RGB颜色抖动风格的需要。除了上文提到了两种,剩余三种的更多细节,篇幅原因这里就不展开了。以下整理了一个汇总列表,若有需要,可以直接转到XPL查看具体渲染表现以及源码:

GlitchRGBSplitV1:
https://github.com/QianMo/X-PostProcessing-Library/tree/master/Assets/X-PostProcessing/Effects/GlitchRGBSplit
GlitchRGBSplitV2:
https://github.com/QianMo/X-PostProcessing-Library/tree/master/Assets/X-PostProcessing/Effects/GlitchRGBSplitV2
GlitchRGBSplitV3:
https://github.com/QianMo/X-PostProcessing-Library/tree/master/Assets/X-PostProcessing/Effects/GlitchRGBSplitV3
GlitchRGBSplitV4:
https://github.com/QianMo/X-PostProcessing-Library/tree/master/Assets/X-PostProcessing/Effects/GlitchRGBSplitV4
GlitchRGBSplitV5:
https://github.com/QianMo/X-PostProcessing-Library/tree/master/Assets/X-PostProcessing/Effects/GlitchRGBSplitV5

其中GlitchRGBSplitV1和GlitchRGBSplitV3具有相对而言较丰富可调参数:



以下是其中的一些效果图:




二、错位图块故障(Image Block Glitch)

错位图块故障(Image Block Glitch)的核心要点在于生成随机强度且横纵交错的图块,随后基于图块的强度,进行uv的抖动采样,并可以加上RGB Split等元素提升渲染表现。


2.1 基础版本的错位图块故障(Image Block Glitch)

对于基础版本的实现,第一步,基于uv和噪声函数生成方格块。可以使用floor方法(对输入参数向下取整)以及低成本的噪声生成函数randomNoise进行实现,代码仅需一句:

  1. half2 block = randomNoise(floor(i.texcoord * _BlockSize));
复制代码

基于这句代码可以生成随机强度的均匀Block图块:


第二步,基于第一步得到的均匀Block图块强度值做强度的二次筛选,增加随机性,代码如下:

  1. half displaceNoise = pow(block.x, 8.0) * pow(block.x, 3.0);
复制代码

得到的图块强度值如下:


第三步,将经过强度二次筛选的Block图块强度值,作为噪声强度的系数,分别对G和B颜色通道进行采样。实现如下:

  1. half ColorR = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.texcoord).r;
  2. half ColorG = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.texcoord + float2(displaceNoise * 0.05 * randomNoise(7.0), 0.0)).g;
  3. half ColorB = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.texcoord - float2(displaceNoise * 0.05 * randomNoise(13.0), 0.0)).b;

  4. return half4(ColorR, ColorG, ColorB, 1.0);
复制代码

可以得到如下基础的错位图块故障(Image Block Glitch)的渲染表现:


以上基础版本的错位图块故障(Image Block Glitch)实现的完整源代码可见:
https://github.com/QianMo/X-PostProcessing-Library/tree/master/Assets/X-PostProcessing/Effects/GlitchImageBlockV3

2.2 结合RGB Split的错位图块故障(Image Block Glitch)

另外,也可以加上RGB Split的元素,得到更丰富的渲染表现,实现代码如下:

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

  5. inline float randomNoise(float seed)
  6. {
  7.     return randomNoise(float2(seed, 1.0));
  8. }

  9. half4 Frag(VaryingsDefault i) : SV_Target
  10. {
  11.     half2 block = randomNoise(floor(i.texcoord * _BlockSize));

  12.     float displaceNoise = pow(block.x, 8.0) * pow(block.x, 3.0);
  13.     float splitRGBNoise = pow(randomNoise(7.2341), 17.0);
  14.     float offsetX = displaceNoise - splitRGBNoise * _MaxRGBSplitX;
  15.     float offsetY = displaceNoise - splitRGBNoise * _MaxRGBSplitY;

  16.     float noiseX = 0.05 * randomNoise(13.0);
  17.     float noiseY = 0.05 * randomNoise(7.0);
  18.     float2 offset = float2(offsetX * noiseX, offsetY* noiseY);

  19.     half4 colorR = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.texcoord);
  20.     half4 colorG = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.texcoord + offset);
  21.     half4 colorB = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.texcoord - offset);

  22.     return half4(colorR.r , colorG.g, colorB.z, (colorR.a + colorG.a + colorB.a));
  23. }
复制代码

对应的渲染表现如下:


实现的完整源代码可见:
https://github.com/QianMo/X-PostProcessing-Library/tree/master/Assets/X-PostProcessing/Effects/GlitchImageBlockV4

2.3 进阶版的错位图块故障(Image Block Glitch)

进阶版的Image Block Glitch,核心要点在于双层blockLayer的生成,以及配合噪声生成函数randomNoise进行双层强度的二次筛选,对应的实现代码如下:

float2 blockLayer1 = floor(uv * float2(_BlockLayer1_U, _BlockLayer1_V));
float2 blockLayer2 = floor(uv * float2(_BlockLayer2_U, _BlockLayer2_V));

float lineNoise1 = pow(randomNoise(blockLayer1), _BlockLayer1_Indensity);
float lineNoise2 = pow(randomNoise(blockLayer2), _BlockLayer2_Indensity);
float RGBSplitNoise = pow(randomNoise(5.1379), 7.1) * _RGBSplit_Indensity;
float lineNoise = lineNoise1 * lineNoise2 * _Offset  - RGBSplitNoise;

上述代码可以得到更加丰富的Block图块强度:


最后,基于此Block强度进行RGB通道的分别采样,可以得到更加多样的错位图块故障(Image Block Glitch)渲染表现:


上述完整的实现代码可见:
https://github.com/QianMo/X-PostProcessing-Library/tree/master/Assets/X-PostProcessing/Effects/GlitchImageBlock

此版本的Image Block Glitch参数也较为丰富,可以根据需要,调出各种风格的Image Block渲染表现:


同样,在XPL(X-PostProcessing-Library)中分别实现了4种不同版本的Glitch Image Block后处理特效,以满足不同情形下的需要。部分算法的源码实现链接上文中已经有贴出一部分,这里是一个汇总列表:

Glitch Image Block V1:
https://github.com/QianMo/X-PostProcessing-Library/tree/master/Assets/X-PostProcessing/Effects/GlitchImageBlock
Glitch Image Block V2:
https://github.com/QianMo/X-PostProcessing-Library/tree/master/Assets/X-PostProcessing/Effects/GlitchImageBlockV2
Glitch Image Block V3:
https://github.com/QianMo/X-PostProcessing-Library/tree/master/Assets/X-PostProcessing/Effects/GlitchImageBlockV3
Glitch Image Block V4:
https://github.com/QianMo/X-PostProcessing-Library/tree/master/Assets/X-PostProcessing/Effects/GlitchImageBlockV4

三、错位线条故障(Line Block Glitch)

错位线条故障(Line Block Glitch)具有较强的表现力,在Glitch系列特效中的出镜率也较高。




该算法的实现思路在于随机宽度线条的生成。我们一步一步来,先从生成均匀宽度线条开始:

  1. float trunc(float x, float num_levels)
  2. {
  3.     return floor(x * num_levels) / num_levels;
  4. }

  5. //生成随机强度梯度线条
  6. float truncTime = trunc(_TimeX, 4.0);      
  7. float uv_trunc = randomNoise(trunc(uv.yy, float2(8, 8)) + 100.0 * truncTime);
复制代码


基于trunc函数以及randomNoise函数,配合上述调用代码,即可得到如下均匀宽度线条:


接着,使用如下代码,将均匀渐变线条转为随机梯度的等宽线条:

  1. float uv_randomTrunc = 6.0 * trunc(_TimeX, 24.0 * uv_trunc);
复制代码



然后,将随机梯度的等宽线条,经过多次randomNoise操作,转换为随机梯度的非等宽线条:

  1. //生成随机梯度的非等宽线条
  2. float blockLine_random = 0.5 * randomNoise(trunc(uv.yy + uv_randomTrunc, float2(8 * _LinesWidth, 8 * _LinesWidth)));
  3. blockLine_random += 0.5 * randomNoise(trunc(uv.yy + uv_randomTrunc, float2(7, 7)));
  4. blockLine_random = blockLine_random * 2.0 - 1.0;   
  5. blockLine_random = sign(blockLine_random) * saturate((abs(blockLine_random) - _Amount) / (0.4));
  6. blockLine_random = lerp(0, blockLine_random, _Offset);
复制代码


可以得到如下的渲染表现:


接着,通过随机梯度的非等宽线条,去抖动uv采样生成源色调的blockLine Glitch:

  1. // 生成源色调的blockLine Glitch
  2. float2 uv_blockLine = uv;
  3. uv_blockLine = saturate(uv_blockLine + float2(0.1 * blockLine_random, 0));
  4. float4 blockLineColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, abs(uv_blockLine));
复制代码

对应的渲染表现如下:


最终,将RGB颜色转换到YUV空间,进行色度(Chrominance)和浓度(Chroma)的偏移,得到最终的渲染表现:

  1. // 将RGB转到YUV空间,并做色调偏移
  2. // RGB -> YUV
  3. float3 blockLineColor_yuv = rgb2yuv(blockLineColor.rgb);
  4. // adjust Chrominance | 色度
  5. blockLineColor_yuv.y /= 1.0 - 3.0 * abs(blockLine_random) * saturate(0.5 - blockLine_random);
  6. // adjust Chroma | 浓度
  7. blockLineColor_yuv.z += 0.125 * blockLine_random * saturate(blockLine_random - 0.5);
  8. float3 blockLineColor_rgb = yuv2rgb(blockLineColor_yuv);

  9. // 与源场景图进行混合
  10. float4 sceneColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.texcoord);
  11. return lerp(sceneColor, float4(blockLineColor_rgb, blockLineColor.a), _Alpha);
复制代码

最终的渲染表现如下:


除了水平方向的Line Block,竖直方向的表现也独具特色:


当然,也可以将上述渲染效果与原始场景图进行插值混合,得到不同强度的渲染表现。

XPL中实现的错位线条故障(Line Block Glitch)后处理,有7个可供定制调节的参数:


错位线条故障(Line Block Glitch)的完整的源代码实现可见:
https://github.com/QianMo/X-PostProcessing-Library/tree/master/Assets/X-PostProcessing/Effects/GlitchLineBlock

四、图块抖动故障(Tile Jitter Glitch)

图块抖动故障 (Tile Jitter Glitch)模拟了屏幕信号的块状抖动故障。


其核心算法思路在于基于uv的分层抖动。可以采用取余数的形式(fmod(x,y)方法可返回x/y的余数)来对uv进行分层,且对于层内的uv数值,进行三角函数形式的抖动。

核心实现Shader代码如下:


  1.     #if USING_FREQUENCY_INFINITE
  2.         strength = 1;
  3.     #else
  4.         strength = 0.5 + 0.5 * cos(_Time.y * _Frequency);
  5.     #endif
  6.     if(fmod(uv.y * _SplittingNumber, 2) < 1.0)
  7.     {
  8.         #if JITTER_DIRECTION_HORIZONTAL
  9.             uv.x += pixelSizeX * cos(_Time.y * _JitterSpeed) * _JitterAmount * strength;
  10.         #else
  11.             uv.y += pixelSizeX * cos(_Time.y * _JitterSpeed) * _JitterAmount * strength;
  12.         #endif
  13.     }
复制代码

上述代码经过计算后,得到的uv强度值如下:


得到上述分块抖动的uv后,便可以作为uv输入,对最终的场景图进行采样:

  1. half4 sceneColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv);
复制代码



上图为左右抖动的表现,这边也有上下抖动的表现,以及左右分层+上下抖动,左右分层+左右抖动的各种不同表现:




图块抖动故障 ( Glitch Tile Jitter) 后处理特效可调的参数同样也比较丰富,XPL内实现的此特效的可调参数面板如下:


图块抖动故障 ( Glitch Tile Jitter)完整的实现源代码可见:
https://github.com/QianMo/X-PostProcessing-Library/tree/master/Assets/X-PostProcessing/Effects/GlitchTileJitter

五、扫描线抖动故障(Scan Line Jitter Glitch)

扫描线抖动故障(Scan Line Jitter Glitch)算法较简单,但是得到的渲染表现却非常具有冲击力:


一个比较直接的实现是直接对横向或者纵向UV进行基于noise的抖动,Shader实现代码如下:

  1. float randomNoise(float x, float y)
  2. {
  3.     return frac(sin(dot(float2(x, y), float2(12.9898, 78.233))) * 43758.5453);
  4. }

  5. half4 Frag_Horizontal(VaryingsDefault i): SV_Target
  6. {

  7.     float jitter = randomNoise(i.texcoord.y, _Time.x) * 2 - 1;
  8.     jitter *= step(_ScanLineJitter.y, abs(jitter)) * _ScanLineJitter.x;

  9.     half4 sceneColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, frac(i.texcoord + float2(jitter, 0)));

  10.     return sceneColor;
  11. }
复制代码


得到的渲染表现如下:


也可以从竖直方向进行uv的抖动:


扫描线抖动故障(Scan Line Jitter Glitch)完整的实现源代码可见:
https://github.com/QianMo/X-PostProcessing-Library/tree/master/Assets/X-PostProcessing/Effects/GlitchScanLineJitter

六、数字条纹故障(Digital Stripe Glitch)

数字条纹故障(Digital Stripe Glitch)同样是出镜率较高的Glitch系后处理特效之一。例如在《赛博朋克2077》的gameplay中,就可以到它的身影:

图 《赛博朋克2077》中的数字条纹故障(Digital Stripe Glitch)特效 @ CD Projekt

数字条纹故障(Digital Stripe Glitch)需在Runtime层完成noise Texture的生成,然后传入GPU中进行最终的运算和渲染呈现。

Runtime的核心思路为基于随机数进行随机颜色条纹贴图的生成,实现代码如下:

  1. for (int y = 0; y < _noiseTexture.height; y++)
  2. {
  3.     for (int x = 0; x < _noiseTexture.width; x++)
  4.     {
  5.         //随机值若大于给定strip随机阈值,重新随机颜色
  6.         if (UnityEngine.Random.value > stripLength)
  7.         {
  8.             color = XPostProcessingUtility.RandomColor();
  9.         }
  10.         //设置贴图像素值
  11.         _noiseTexture.SetPixel(x, y, color);
  12.     }
  13. }
复制代码

生成的图片如下:


Shader层面的实现则分为两个主要部分,分别是uv偏移,以及可选的基于废弃帧的插值不足:

  1. half4 Frag(VaryingsDefault i): SV_Target
  2. {
  3.     // 基础数据准备
  4.      half4 stripNoise = SAMPLE_TEXTURE2D(_NoiseTex, sampler_NoiseTex, i.texcoord);
  5.      half threshold = 1.001 - _Indensity * 1.001;

  6.     // uv偏移
  7.     half uvShift = step(threshold, pow(abs(stripNoise.x), 3));
  8.     float2 uv = frac(i.texcoord + stripNoise.yz * uvShift);
  9.     half4 source = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv);

  10.     #ifndef NEED_TRASH_FRAME
  11.         return source;
  12.     #endif

  13.     // 基于废弃帧插值
  14.     half stripIndensity = step(threshold, pow(abs(stripNoise.w), 3)) * _StripColorAdjustIndensity;
  15.     half3 color = lerp(source, _StripColorAdjustColor, stripIndensity).rgb;
  16.     return float4(color, source.a);
  17. }
复制代码


得到的不进行废弃帧插值的渲染表现如下:


进行废弃帧插值的渲染表现如下。除了下图中采用的类似反色的偏移颜色,也可以实现出基于RGB颜色随机,或者进行颜色空间转换后的色度校正后的偏移颜色:


数字条纹故障(Digital Stripe Glitch)后处理完整的实现源码可见:
https://github.com/QianMo/X-PostProcessing-Library/tree/master/Assets/X-PostProcessing/Effects/GlitchDigitalStripe

七、模拟噪点故障(Analog Noise Glitch)


模拟噪点故障(Analog Noise Glitch)的主要思路,在于用noise去扰动原先场景图的颜色值。一种常规实现的核心代码如下:

  1. float noiseX = randomNoise(_TimeX * _Speed + i.texcoord / float2(-213, 5.53));
  2. float noiseY = randomNoise(_TimeX * _Speed - i.texcoord / float2(213, -5.53));
  3. float noiseZ = randomNoise(_TimeX * _Speed + i.texcoord / float2(213, 5.53));

  4. sceneColor.rgb += 0.25 * float3(noiseX,noiseY,noiseZ) - 0.125;
复制代码


需要注意,0.25 * float3(noiseX,noiseY,noiseZ) - 0.125这句代码中的系数0.25和-0.125的作用,是让noise扰动后的画面的平均亮度和原先场景场景图相同,不能省略。但0.25和0.125两个系数可以进行合适的等幅度缩放,相对比例不变即可。

通过以上代码,可以得到如下带非均匀噪声的渲染表现:


另外,还可以加入greyScale灰度抖动,当某一刻的随机强度值大于亮度抖动阈值时,将原先的RGB颜色对应的luminance强度,呈现出黑白灰度的表现。

  1. half luminance = dot(noiseColor.rgb, fixed3(0.22, 0.707, 0.071));
  2. if (randomNoise(float2(_TimeX * _Speed, _TimeX * _Speed)) > _LuminanceJitterThreshold)
  3. {
  4.     noiseColor = float4(luminance, luminance, luminance, luminance);
  5. }
复制代码

最终,将noise扰动和随机灰度抖动两个特性相结合,得到Glitch Analog Noise最终的渲染表现:


模拟噪点故障(Analog Noise Glitch)完整的实现源码可见:
https://github.com/QianMo/X-PostProcessing-Library/tree/master/Assets/X-PostProcessing/Effects/GlitchAnalogNoise

八、屏幕跳跃故障(Screen Jump Glitch)



屏幕跳跃故障(Screen Jump Glitch)的算法原理在于取经过时间校正后的uv数值的小数部分,并于原始uv插值,得到均匀梯度式扰动屏幕空间uv,再用此uv进行采样即可得到跳动画面的表现。核心实现Shader代码如下:

  1. half4 Frag_Vertical(VaryingsDefault i): SV_Target
  2. {

  3.     float jump = lerp(i.texcoord.y, frac(i.texcoord.y + _JumpTime), _JumpIndensity);        
  4.     half4 sceneColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, frac(float2(i.texcoord.x, jump)));   
  5.     return sceneColor;
  6. }
复制代码

其中,扰动后的uv强度分布,随时间变化的数值如下:


基于此uv进行采样,得到的渲染表现如下:


以上为竖直方向的阶梯式uv采样,当然,我们也可以进行水平方向的阶梯式采样:

  1. half4 Frag_Horizontal(VaryingsDefault i): SV_Target
  2. {      
  3.     float jump = lerp(i.texcoord.x, frac(i.texcoord.x + _JumpTime), _JumpIndensity);   
  4.     half4 sceneColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, frac(float2(jump, i.texcoord.y)));      
  5.     return sceneColor;
  6. }
复制代码

水平方向的阶梯式采样,得到的渲染表现如下:


屏幕跳跃故障(Screen Jump Glitch)详细的实现源码可见:
https://github.com/QianMo/X-PostProcessing-Library/tree/master/Assets/X-PostProcessing/Effects/GlitchScreenJump

九、屏幕抖动故障(Screen Shake Glitch)


类似上文的Screen Jump,Screen Shake屏幕抖动的算法原理也在于对屏幕空间uv的抖动,但不同的是,Screen Shake屏幕抖动需采用noise噪声函数来随机扰动uv,而不是均匀梯度式的形式。核心实现代码如下:

  1. half4 Frag_Horizontal(VaryingsDefault i): SV_Target
  2. {
  3.     float shake = (randomNoise(_Time.x, 2) - 0.5) * _ScreenShake;

  4.     half4 sceneColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, frac(float2(i.texcoord.x + shake, i.texcoord.y)));

  5.     return sceneColor;
  6. }
复制代码

得到扰动uv的可视化强度值如下:


渲染表现则如下:


同样,也可以做竖直方向的抖动:

  1. half4 Frag_Vertical(VaryingsDefault i): SV_Target
  2. {

  3.     float shake = (randomNoise(_Time.x, 2) - 0.5) * _ScreenShake;

  4.     half4 sceneColor = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, frac(float2(i.texcoord.x, i.texcoord.y + shake)));

  5.     return sceneColor;
  6. }
复制代码



屏幕抖动故障(Screen Shake Glitch)完整的实现源码可见:
https://github.com/QianMo/X-PostProcessing-Library/tree/master/Assets/X-PostProcessing/Effects/GlitchScreenShake

十、波动抖动故障(Wave Jitter Glitch)

波动抖动故障(Wave Jitter Glitch)相较于上述的9种Glitch算法而言,用到了更为复杂的噪声生成函数。


10.1 噪声生成函数库 XNoiseLibrary

对此,XPL参考了paper《Simplex noise demystified 》[1]、webgl-noise库[2]和NoiseShader库[3],实现一个单文件版的多维度噪声生成库 [XNoiseLibrary][4]。

XNoiseLibrary具有如下三种类型的Noise噪声生成函数:

2D/3D/4D Simplex Noise
2D/3D textureless classic Noise
Re-oriented 4 / 8-Point BCC Noise

XNoiseLibrary的优势在于使用较为方便,直接include单个文件XNoiseLibrary.hlsl即可进行其中封装的多版本噪声函数的调用。

XNoiseLibrary的实现源码可见:
https://github.com/QianMo/X-PostProcessing-Library/blob/master/Assets/X-PostProcessing/Shaders/XNoiseLibrary.hlsl

10.2 波动抖动故障(Wave Jitter Glitch)的实现算法

OK,回到我们的波动抖动故障(Wave Jitter Glitch)后处理中来。

波动抖动故障(Wave Jitter Glitch)后处理的核心思路是用双层的noise实现波浪形扭动uv,核心代码如下:

  1. float uv_y = i.texcoord.y * _Resolution.y;
  2. float noise_wave_1 = snoise(float2(uv_y * 0.01, _Time.y * _Speed * 20)) * (strength * _Amount * 32.0);
  3. float noise_wave_2 = snoise(float2(uv_y * 0.02, _Time.y * _Speed * 10)) * (strength * _Amount * 4.0);
  4. float noise_wave_x = noise_wave_1 / _Resolution.x;
  5. float uv_x = i.texcoord.x + noise_wave_x;

  6. float4 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, float2(uv_x, i.texcoord.y));
复制代码


若是单层的noise波浪,表现力会稍弱,具体表现如下:


而双层的noise波浪,表现力更强,具体表现如下:


所以XPL中的Wave Jitter实现,采用了双层的形式。

有了基于双层noise的Wave Jitter Glitch表现,还可以加上RGB Split算法,进一步提升表现力:

  1. float4 Frag_Horizontal(VaryingsDefault i): SV_Target
  2. {
  3.     half strength = 0.0;
  4.     #if USING_FREQUENCY_INFINITE
  5.         strength = 1;
  6.     #else
  7.         strength = 0.5 + 0.5 *cos(_Time.y * _Frequency);
  8.     #endif

  9.     // Prepare UV
  10.     float uv_y = i.texcoord.y * _Resolution.y;
  11.     float noise_wave_1 = snoise(float2(uv_y * 0.01, _Time.y * _Speed * 20)) * (strength * _Amount * 32.0);
  12.     float noise_wave_2 = snoise(float2(uv_y * 0.02, _Time.y * _Speed * 10)) * (strength * _Amount * 4.0);
  13.     float noise_wave_x = noise_wave_1 * noise_wave_2 / _Resolution.x;
  14.     float uv_x = i.texcoord.x + noise_wave_x;

  15.     float rgbSplit_uv_x = (_RGBSplit * 50 + (20.0 * strength + 1.0)) * noise_wave_x / _Resolution.x;

  16.     // Sample RGB Color
  17.     half4 colorG = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, float2(uv_x, i.texcoord.y));
  18.     half4 colorRB = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, float2(uv_x + rgbSplit_uv_x, i.texcoord.y));

  19.     return  half4(colorRB.r, colorG.g, colorRB.b, colorRB.a + colorG.a);
  20. }
复制代码


得到的渲染表现如下:


当然,除了横向的Wave Jitter,纵向的Wave Jitter也具有不错的效果:


波动抖动故障(Wave Jitter Glitch)后处理特效可调参数也比较丰富,XPL内实现的此特效的可调参数面板如下:


波动抖动故障(Wave Jitter Glitch)详细的实现源码,可见:
https://github.com/QianMo/X-PostProcessing-Library/tree/master/Assets/X-PostProcessing/Effects/GlitchWaveJitter

总结

故障艺术追求“故障”带来的独特美感。近年来,故障艺术已经成为了赛博朋克风格电影和游戏作品中的核心艺术风格之一。而随着各种相关影视作品和游戏作品的不断发布,故障艺术的表现风格也引起了电商、综艺、快消等行业的广泛效仿。

在看完上述十种不同的故障艺术算法后,我们可以提炼一下,若要在屏幕空间实现故障艺术风格的渲染表现,算法核心在于四点:

噪声函数的选择:噪声函数是生成各式的干扰信号的源头。
uv抖动方式的选择:将噪声函数作用于屏幕空间uv后,基于新的uv进行采样,以产生故障的抖动表现。
采样通道的选择:对RGB分别采样,或者选取特定通道进行采样,以实现多种风格的故障表现。
颜色空间的转换:善用YUV、CMY、HSV、YIQ、YCbCr 、YC1C2等空间与RGB空间之间的转换,以实现多种风格的故障表现。

熟知上述四种故障艺术的算法要点,加上一点创意,配合周边算法,则可以创造出更多富有表现力的故障艺术特效。

Reference
[1] http://weber.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf
[2] https://github.com/ashima/webgl-noise
[3] https://github.com/keijiro/NoiseShader
[4] https://github.com/QianMo/X-PostProcessing-Library/blob/master/Assets/X-PostProcessing/Shaders/XNoiseLibrary.hlsl
[5] Jackson R. The Glitch Aesthetic[J]. 2011. https://scholarworks.gsu.edu/cgi/viewcontent.cgi?article=1081&context=communication_theses
[6] den Heijer E. Evolving glitch art[C]//International Conference on Evolutionary and Biologically Inspired Music and Art. Springer, Berlin, Heidelberg, 2013: 109-120
[7] https://en.wikipedia.org/wiki/Cyberpunk
[8] https://github.com/keijiro/KinoGlitch
[9] https://wallpaperswise.com/new-20-blade-runner-wallpapers/
[10] 封面图来自《Cyberpunk 2077》

作者:毛星云
专栏地址:https://zhuanlan.zhihu.com/p/148256756


相关下载

玩家评论

7月新赛季开启,至少8款高品质皮肤上线,没冰封战神的玩家稳赚

近期的新上线的内容也是非常给力的,很多玩家都非常满意,因为战令系统里显示着6月25号就结束了,所以S19赛季也是已经接近尾声了,而S20赛季估计会在7月详情>>

阅读: 3
日期: 2020-06-17
如何设置调节Realtek音频管理器?拥有高品质电脑音效

详情>>

阅读: 20
日期: 2020-06-05
《桥梁建造师2》Steam特别好评 延续了一代的高品质

昨日,模拟建造游戏《桥梁建造师2》正式上架Steam。本作目前有121个评价,游戏好评率为97%,整体评价为“特别好评”。大多数玩家认为该作关卡内详情>>

阅读: 5
日期: 2020-06-01
《桥梁建造师2》Steam特别好评延续了一代的高品质

《桥梁建造师2》Steam特别好评 延续了一代的高品质 2020-05-30 15:46:45来源:游戏下载编辑:松鼠骑士评论(0) 详情>>

阅读: 16
日期: 2020-06-01
《乱世无双(百抽特权)》视频分享:玩法多样、元素丰富的高品质武侠世界

  《乱世无双(百抽特权)》以宋代锦衣卫时期的历史故事为蓝本,采用3D表现出色的Unity3D引擎打造,拥有丰富的玩法、成长系统详情>>

阅读: 6
日期: 2020-05-22
《中二病拯救世界》游戏内容介绍 高品质动漫式剧情

首款动漫式剧情卡牌手游《中二病拯救世界》由中日游戏人联合打造,特邀日本美术团队、日本知名制作人、日本详情>>

阅读: 1
日期: 2020-05-06
格斗英雄高品质翅膀怎么获得

  格斗英雄高品质翅膀怎么获得是9k9k小编夏夏为大家带来的,格斗英雄高品质翅膀是小编夏夏主要分享给大家的内容,同时高品质翅膀怎么获得小编也为玩家朋友们详情>>

阅读: 4
日期: 2020-05-06
《巫师3:狂猎》高品质头部/嘴唇运动/高品质阴影MOD发布

【导读】MOD制作者“rmemr”和“Gerignak”近日发布了一个很有趣的《巫师3:狂猎》的新MOD。这个MOD为我们带来了游戏中所有NPC的高品质的头部建模,嘴唇的运动和更高品质的阴影详情>>

阅读: 3
日期: 2020-04-30
刚开播豆瓣拿下9.1分,又一部高品质韩剧诞生!_尹智秀

原标题:刚开播豆瓣拿下9.1分,又一部高品质韩剧诞生! 在一个大雪纷飞的晚上,韩在贤终于见到了念念不忘的初恋情人尹智秀,两人情不自禁就都湿润了眼眶,可详情>>

阅读: 12
日期: 2020-04-29
高品质后处理渲染技术分享:十种图像模糊算法的总结与实现

文章首发于“腾讯技术工程”,作者毛星云,GameRes授权发布 后处理(Post-Processing),在图形学和游戏开发等领域是提升最终画面呈现品质的重要渲染技术。后处理渲染技术的详情>>

阅读: 2
日期: 2020-04-27
阴阳师官方打脸?号称典藏皮都高品质要求,椒图怎么解释

阴阳师典藏皮肤168事件发生后,一时间关于典藏皮定价的话题讨论的非常火热,而这次丑出天际的泷夜叉姬典藏皮肤永夜无眠,在玩家持续几天疯狂刷屏的“168”攻势下,官方才终于服软,耗详情>>

阅读: 5
日期: 2020-04-12
共享办公空间企业复工率达90%高品质服务成关键因素

原标题:共享办公空间企业复工率达90% 高品质服务成关键因素 新冠肺炎疫情让中小企业、初创企业严重受挫的同时,也打击着物业写字楼。美国共享办公空详情>>

阅读: 3
日期: 2020-04-03
体验服快车:万化分级时代来临,高品质皮肤认知讲解

嘿,各位CFer们大家好啊,我是你们的灵狐姐!炫酷的皮肤不仅可以让我们拥有丰富的金币加成,还会给我们带来全新的视觉体验,并在潜移默化中提升武器的手感。详情>>

阅读: 14
日期: 2020-04-02
深圳自如租房高品质房源值得租吗?

非常值得的!自如的房子装修的都还不错。房间的设施也很齐全。以前租房最担心的事情就是因为各种原因不退押金。但是在自如就不用担心这个问题,最近自如还推出了“0押金”租房,详情>>

阅读: 15
日期: 2020-03-28
高品质密封产品——OTHELLO碟簧

原标题:高品质密封产品——OTHELLO碟簧 OTHELLO(奥赛罗)密封材料有限公司严格按照国际标准生产,制造,检验产品,我们为您提供的不仅仅是高品质的密封详情>>

阅读: 2
日期: 2020-03-19
许嵩音乐合集下载,31张专辑高品质分享!_歌曲

原标题:许嵩音乐合集下载,31张专辑高品质分享! 最近刷抖音 发现全是许嵩的视频 粉丝跟着他一起大合唱 唱的是我们逝去的青春 我的高中时期 也是听着详情>>

阅读: 10
日期: 2020-03-02
高品质社区,值得选择?

你,1,好,来联发藏珑大境,好,毛坯现房地铁口,嗯,好,2,好,好详情>>

阅读: 6
日期: 2020-02-27
全TM是宅男爱的福利资源,个个高品质,正好在家打发时间_地球

原标题:全TM是宅男爱的福利资源,个个高品质,正好在家打发时间 G歌地球 界面是熟悉的地球全貌 勾选左下角的“图层”中的详细配置 尤其是“3D建筑” 详情>>

阅读: 7
日期: 2020-02-02
新城控股王晓松新年致辞:反思、对标,坚持高品质发展_张晓兰

原标题:新城控股王晓松新年致辞:反思、对标,坚持高品质发展 新京报快讯(记者 张晓兰)“2019年,新城走得坚实稳健。在这个年度的日日夜夜里,新城人同心戮详情>>

阅读: 6
日期: 2020-01-01
一图看懂国行Switch,明年有望引进20款高品质游戏_续航

原标题:一图看懂国行Switch,明年有望引进20款高品质游戏 IT之家12月4日消息 今天,腾讯和任天堂发布了玩家期待已久的Switch续航增强版,售价2099元,12月详情>>

阅读: 9
日期: 2019-12-04
广州自如租房高品质房源真的好吗?

真的挺好的,广州自如的高品质房源都是经过精心装修的,一看就知道用的是好材料。房间的布局也很好,就算有的房间平数小点,看着也不拥挤。我就住在一个不太大的房间,吃土女孩想尽一详情>>

阅读: 15
日期: 2019-11-05
携程20周年宣布未来战略:“G2”聚焦高品质及全球化

原标题:携程20周年宣布未来战略:“G2”聚焦高品质及全球化 证券时报记者 梅双 10月29日,携程集团20周年庆典暨全球合作伙伴峰会召开。携程董事局主席详情>>

阅读: 9
日期: 2019-10-29
高品质动画电影《神兽魔王大作战》今日全网建档,超燃机甲2020热血来袭!

原标题:高品质动画电影《神兽魔王大作战》今日全网建档,超燃机甲2020热血来袭! 3D/2D热血冒险合家欢动画电影《神兽魔王大作战》今日宣布全网建档,该详情>>

阅读: 10
日期: 2019-10-25
高品质动画电影《神兽魔王大作战》今日全网建档,超燃机甲2020热血来袭!_影片

原标题:高品质动画电影《神兽魔王大作战》今日全网建档,超燃机甲2020热血来袭! 3D/2D热血冒险合家欢动画电影《神兽魔王大作战》今日宣布全网建档,该详情>>

阅读: 9
日期: 2019-10-25
洋河王耀:浓香型白酒企业要聚焦高品质产品

原标题:洋河王耀:浓香型白酒企业要聚焦高品质产品 新京报讯(记者 王子扬)10月19日,“中国浓香白酒高峰论坛”在酒博会期间举行。苏酒集团(洋河股份)党委详情>>

阅读: 9
日期: 2019-10-19
高品质多ip竞技手游《战争艺术》10月17日无限进化版本公测

高品质多IP竞技手游《战争艺术:无限进化》将在2019年10月17日正式开启公测。《无限进化》版本以《战争艺术:赤潮》的IP为基础,增添了更为宏大的世界观背景,详情>>

阅读: 12
日期: 2019-10-16
高品质多ip竞技手游《战争艺术》 10月17日无限进化版本公测

高品质多IP竞技手游《战争艺术:无限进化》将在2019年10月17日正式开启公测。《无限进化》版本以《战争艺术:赤潮》的IP为基础,增添了更为宏大的世界观背景,在多详情>>

阅读: 9
日期: 2019-10-16
打造五星高品质入门手机Redmi红米8系列699元起

原标题:打造五星高品质入门手机 Redmi红米8系列699元起 10月14日,Redmi正式发布两款高品质入门新品Redmi红米8和Redmi红米8A,两款产品都配备了高通八详情>>

阅读: 6
日期: 2019-10-14
雷军宣布红米8/8A定义五星级高品质入门机

原标题:雷军宣布红米8/8A定义五星级高品质入门机 IT之家10月14日消息 此前小米官方已经宣布了Redmi红米8系列发布会的消息,将于今天下午3点正式开始详情>>

阅读: 17
日期: 2019-10-14
瑞幸咖啡与路易达孚签署协议开发高品质果汁联合品牌业务

原标题:瑞幸咖啡与路易达孚签署协议 开发高品质果汁联合品牌业务 9月25日 新加坡 瑞幸咖啡今日与路易达孚集团(LDC)在新加坡签署战略合作协议,双方将详情>>

阅读: 4
日期: 2019-09-26
全十红的匠心之作,高品质的红稗饼干

原标题:全十红的匠心之作,高品质的红稗饼干 说到美容养颜,离不开的一件事就是谈到补气血。因为《黄帝内经》中多次提到“气血盛则髯美”、“气血和则详情>>

阅读: 27
日期: 2019-09-10
Xbox老大确认:正在开发大量高品质单机游戏

在本世代,单机游戏不再是Xbox的强项,Xbox One最强势的主机独占游戏都在向多人模式倾斜,包括《极限竞速》、《光环》、《战争机器》等本来就主打多人玩法的游戏,以及新的IP,像是详情>>

阅读: 19
日期: 2019-08-09
《明日之后》高品质鱼竿钓到高品质鱼概率更大,垂钓冠军科普知识_鱼饵

原标题:《明日之后》高品质鱼竿钓到高品质鱼概率更大,垂钓冠军科普知识 1、在哪里领任务 商会任务牌,如果你已经加入营地,就在每日巡逻那个NPC的牌详情>>

阅读: 37
日期: 2019-08-05
《辐射4》高品质的女性性感T恤MOD

《辐射4》高品质的女性性感T恤MOD补丁类型:游戏MOD补丁语言:简体中文更新时间:2018/10/1816:35:52补丁大小:62.6MB游戏标签:刺激冒险挑战《辐射4》高品质的女性详情>>

阅读: 6
日期: 2019-04-02
永诺财富打造高品质理财平台

永诺财富是一家具备优秀的自主研发能力的金融创新型企业,致力为个人和企业搭建一个高效、直接的投资桥梁。寻找个人和企业之间安全与效率的平衡点,推动解决利率市场化进程中投资渠详情>>

阅读: 7
日期: 2019-01-02
梦幻手游合宠技巧 技能冲突的高品质宠物不可以合成

  在梦幻西游手游当中,最粗暴的获得比较珍贵宠物的方式,就是宠物合成。在宠物合成的时候其实非常的看脸,如果玩家运气比较好的话,可能会获得非常珍贵的宠物,当然玩家如果懂得手游里面合宠的技巧的话,也会大大的提升和出高品质宠物的机会。详情>>

阅读: 13
日期: 2018-11-24
史上最高逼格、高品质的《员工手册》长这样!

如果有人问你看到过最高逼格,最高品质的员工手册吗?是哪家公司的?小编毫不犹豫的会告诉你,是Valve,这详情>>

阅读: 9
日期: 2018-11-01
太吾绘卷高品质装备怎么造 高品质装备打造方法介绍

 《太吾绘卷》中玩家获取装备的途径除了野怪掉落和绑人大法之外还可以通过锻造来获取,下面就为大家带来高品质装备打造攻略介绍 点击进入:太吾绘卷夺舍详情>>

阅读: 22
日期: 2018-10-09
高品质游戏是否该收费;叠纸氪金引热议

当今市面上对游戏的“氪金”模式讨论很是火热。赞同者和粉丝往往表示“花钱买享受是应有之义”,甚至在高品质游戏的宣传阶段表示“只要你出,多少钱我都氪”、“... 详情>>

阅读: 5
日期: 2018-09-20
镇魔曲网页版灵兽合成攻略 轻松获得高品质灵兽

灵兽作为游戏中的玩法之一,一直陪伴这玩家们的成长。而在镇魔曲网页版中,灵兽...这里强调一下,高级技能与低级技能不是同一个技能,灵兽合成时(当然也包括打书)... 详情>>

阅读: 1
日期: 2018-09-20
精彩推荐