pic
 

1.实现类似瞳孔放大的视觉扭曲效果。该效果通过组合图像拉伸、扭曲和模糊算法。

输入图像 → 横向拉伸 → 径向扭曲 → 方向模糊 → 输出图像
    ↑           ↑           ↑           ↑
  原图UV    基于距离的   正弦扭曲     4次采样
           边缘拉伸     时间动画     模糊处理

横向拉伸算法

// 计算横向距离 [-1, 1]
float distanceFromCenter = (uv.x - 0.5) * 2.0;

// 基于距离计算拉伸因子(边缘拉伸更大)
float stretchFactor = smoothstep(0.0, 1.0, abs(distanceFromCenter)) * _StretchAmount;

// 应用横向拉伸
uv.x = lerp(uv.x, 0.5 - sign(distanceFromCenter) * 0.5, stretchFactor);

// 伴随垂直微调(增强立体感)
uv.y = lerp(uv.y, sign(distanceFromCenter) * -0.01, stretchFactor);

算法特点

  • 使用smoothstep平滑边缘过渡

  • 保留中心区域不变(瞳孔位置)

  • 添加垂直方向微小偏移增强3D感

    动态扭曲效果

    float2 center = float2(0.5, 0.5);
    float dist = length(uv - center);
    
    // 基于距离的正弦扭曲 + 时间动画
    float twist = sin(dist * 10.0 + _Time.y * _twistSpeed) * 0.6 * 0.01;
    uv.x += twist * _twistAmount;

    数学原理

    • dist:像素到中心的径向距离

    • dist * 10.0:产生多个扭曲环带

    • _Time.y * _twistSpeed:随时间旋转的波动

    • * 0.6 * 0.01:限制扭曲幅度,保持视觉效果自然

      方向性模糊实现

      int sampleCount = 4;
      float2 direction = normalize(half2(0.1, 0.1)); // 45度方向模糊
      
      for (int j = 0; j < sampleCount; ++j)
      {
          float offset = (float(j) / float(sampleCount - 1) - 0.5) * _blurAmount;
          float2 offsetUV = uv + direction * offset * _MainTex_TexelSize.xy * _BlurOffset;
          col += SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, offsetUV);
      }
      col /= sampleCount;

       

 

2.模拟心跳脉搏的屏幕后处理Shader。该效果通过组合径向脉冲扩张动态扭曲色差偏移三种技术,营造出类似心脏跳动时的视觉张力感

核心技术图解

时间输入 → 心跳波形生成 → 径向扩张 → 动态扭曲 → 色差偏移 → 最终输出
    ↑           ↑            ↑          ↑           ↑
  _HeartBeatSpeed  分段函数    基于距离    正弦波动   RGB通道分离

 

效果组合逻辑

整个后处理效果按照特定顺序叠加:

  1. 拉伸阶段:改变图像的基础形貌,创造瞳孔扩张的视觉基础

  2. 扭曲阶段:添加动态波纹,模拟液体或光学的波动感

  3. 模糊阶段:柔化边缘,增强视觉冲击力

    心跳波形生成算法

    1. 分段函数设计

    hlsl
    half pulseMax = 1.0;        // 最大幅度
    half pulseMin = 0.0;         // 最小幅度
    half heartbeatDuration = 0.3; // 心跳上升+顶峰+下降总时间
    half pauseDuration = _pauseDurationTime;  // 低谷停顿时间
    
    // 计算当前时间在一个心跳周期中的进度
    float totalDuration = heartbeatDuration + pauseDuration;
    float currentTime = fmod(_Time.y * _HeartBeatSpeed, totalDuration);

    设计思路:将心跳周期分为四个阶段,模拟真实心跳波形:

    • 快速上升期(40%):心室收缩,压力骤增

    • 顶峰停顿(40%):保持收缩状态

    • 缓慢下降期(20%):心室舒张

    • 低谷停顿:心脏休息期

    2. 波形生成代码

    hlsl
    float pulse;
    if (currentTime < heartbeatDuration * 0.4) {
        // 上升阶段:线性上升
        pulse = pulseMin + (pulseMax - pulseMin) * (currentTime / (heartbeatDuration * 0.4));
    } 
    else if (currentTime < heartbeatDuration * 0.8) {
        // 顶峰停顿:保持最大
        pulse = pulseMax;
    } 
    else if (currentTime < heartbeatDuration) {
        // 下降阶段:线性下降
        float t = currentTime - (heartbeatDuration * 0.8);
        pulse = pulseMax - (pulseMax - pulseMin) * (t / (heartbeatDuration * 0.2));
    } 
    else {
        // 低谷停顿:保持最小
        pulse = pulseMin;
    }

    波形特点

    • 快速上升制造冲击感

    • 顶峰停顿强化收缩感

    • 缓慢下降模拟舒张

    • 低谷停顿形成节奏感

    核心效果实现

    1. 径向脉冲扩张

    hlsl
    float2 center = float2(0.5, 0.5);
    float dist = length(uv - center);
    
    // 径向扩张:uv向中心收缩,产生向外扩张的视觉错觉
    uv -= (uv - center) * pulse * _pulseAmount;

    数学原理

    • (uv - center):从中心指向当前像素的方向向量

    • pulse * _pulseAmount:当前时刻的脉冲强度

    • 减去方向向量×强度 → UV向中心收缩 → 图像从中心向外扩张

    视觉解释:当UV向中心收缩时,原本边缘的像素被映射到更靠近中心的位置,相当于把图像”撑开”,产生从中心向外脉冲的视觉效果。

    2. 动态扭曲增强

    hlsl
    // 基于距离的正弦扭曲
    float twist = sin(dist * 10.0 + _Time.y * 1) * 0.6 * 0.01 * pulse;
    uv.x += twist * _twistAmount;

    技术要点

    • dist * 10.0:产生多个扭曲环带,增强层次感

    • _Time.y * 1:随时间旋转的波动

    • * pulse:扭曲强度随心跳节奏变化,增强同步感

    3. 色差偏移(Chromatic Aberration)

    hlsl
    // RGB通道分离采样
    float2 uvR = uv + float2(0.01, 0.0) * pulse * _ChromaticAberrationAmount;
    float2 uvG = uv;
    float2 uvB = uv - float2(0.01, 0.0) * pulse * _ChromaticAberrationAmount;
    
    // 合并通道
    half4 colR = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uvR);
    half4 colG = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uvG);
    half4 colB = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uvB);
    half4 col = half4(colR.r, colG.g, colB.b, 1.0);

    设计原理

    • 模拟镜头色散现象,增强视觉冲击

    • 偏移量随心跳节奏变化,强化脉搏感

    • RGB通道分离方向:红右蓝左,符合物理色散规律

    • 绿通道保持不变,维持视觉中心

 

3.模拟屏幕闪白、震动和模糊的后处理Shader。该效果通过组合方向模糊高频震动曝光增强三种技术,营造出爆炸冲击、相机剧烈晃动或角色受击时的视觉冲击感。

核心技术图解

text
输入图像 → 方向模糊采样 → 高频震动偏移 → 曝光增强 → 输出图像
    ↑           ↑              ↑             ↑
  _MainTex   _SampleCount    _ShakeIntensity  _Exposure
              _BlurOffset     sin(_Time.y*100)

震动算法实现

1. 高频震动计算

hlsl
// 100Hz的超高频正弦波,产生剧烈抖动感
float shake = sin(_Time.y * 100.0) * 0.01;

// 应用到UV偏移
offsetUV += float2(shake, shake) * _ShakeIntensity;

数学原理

  • _Time.y * 100.0:100倍时间速度,产生肉眼无法追踪的超快震动

  • * 0.01:基础偏移量控制,避免过度偏移导致图像撕裂

  • * _ShakeIntensity:可调节的震动强度参数

设计思路:采用超高频(100Hz)而非普通低频(如5-10Hz)震动,模拟真实相机在剧烈冲击下的微观震颤,比普通晃动更具冲击力。

2. 频率对比分析

 
 
频率 视觉感受 适用场景
5-10Hz 明显的左右摆动 醉酒、眩晕效果
20-30Hz 轻微的抖动感 车辆行驶、手持相机
100Hz 微观震颤、冲击感 爆炸、受击、闪屏

方向模糊实现

1. 模糊采样算法

hlsl
float2 direction = normalize(half2(0.1, 0.1)); // 45度方向模糊
float blurAmount = 5 * 10.0; // 基础模糊强度

for (int j = 0; j < sampleCount; ++j)
{
    // 计算采样偏移量(-0.5到0.5均匀分布)
    float offset = (float(j) / float(sampleCount - 1) - 0.5) * blurAmount;
    
    // 应用方向、偏移和震动
    float2 offsetUV = uv + direction * offset * _MainTex_TexelSize.xy * _BlurOffset;
    offsetUV += float2(shake, shake) * _ShakeIntensity;
    
    color += SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, offsetUV);
}
color /= sampleCount;

2. 模糊参数设计

 
 
参数 作用 技术细节
_SampleCount 采样质量 2-10可调,平衡性能与效果
direction 模糊方向 45度倾斜,避免水平和垂直方向的呆板感
_BlurOffset 模糊距离 控制拖影长度
blurAmount = 50 基础强度 固定值确保足够的模糊范围

曝光增强处理

hlsl
color *= _Exposure;

作用:整体提亮画面,模拟闪光灯或爆炸瞬间的光照过曝效果。配合震动和模糊,强化视觉冲击力。

参数调节指南

 
 
参数 范围 作用 推荐值
_SampleCount 2-10 模糊采样质量 6-8(平衡性能)
_Exposure 0-20 曝光强度 1.5-3.0(轻微过曝)
_ShakeIntensity 0-2 震动强度 0.5-1.2(剧烈冲击)
_BlurOffset 0-5 模糊距离 1.0-3.0(明显拖影)

效果组合逻辑

时序设计

假设用于爆炸反馈:

  1. 瞬间:高频震动启动,模拟冲击波

  2. 同时:方向模糊增强,模拟视觉暂留

  3. 伴随:曝光增强,模拟闪光

  4. 衰减:各参数随时间归零(需C#脚本配合)

视觉层次

text
震动层:微观震颤,传递冲击感
模糊层:方向拖影,传递运动感
曝光层:整体提亮,传递能量感
 

4.模拟高速运动视觉感受的屏幕后处理Shader。该效果通过组合极坐标变换动态Voronoi噪声屏幕震动三种技术,在屏幕边缘生成动态流动的线条,配合高频抖动,营造出角色高速移动、加速冲刺或时间紧迫感的视觉体验。

核心技术图解

text
输入图像 → UV震动偏移 → 极坐标变换 → Voronoi噪声 → 速度线生成 → 颜色混合 → 输出
    ↑           ↑            ↑             ↑              ↑            ↑
  _MainTex   sin(_Time*60) 中心点(0.5)   时间动画      边缘检测    _SpeedLineColor

极坐标变换原理

1. 坐标转换算法

hlsl
void Unity_PolarCoordinates_float(float2 UV, float2 Center, float RadialScale, 
                                   float LengthScale, out float2 Out)
{
    float2 delta = UV - Center;                    // 计算相对于中心的向量
    float radius = length(delta) * 2 * RadialScale; // 极径(距离)
    float angle = atan2(delta.x, delta.y) * 1.0/6.28 * LengthScale; // 极角(角度)
    Out = float2(radius, angle);
}

数学原理

  • radius:像素到屏幕中心的距离,决定线条的径向位置

  • angle:像素的方向角,决定线条的周向位置

  • 输出坐标系:(r, θ) 将笛卡尔坐标转换为极坐标

视觉意义:将屏幕从”方形的XY网格”转换为”圆形的距离-角度”坐标系,使得在边缘生成的线条能够围绕中心自然弯曲。

2. 参数调校

hlsl
Unity_PolarCoordinates_float(uv, float2(0.5, 0.5), 0.6, 1, _PolarCoordinates);
 
 
参数 作用
Center (0.5, 0.5) 屏幕中心点
RadialScale 0.6 压缩径向范围,让线条更集中在边缘
LengthScale 1 角度缩放,保持自然

Voronoi噪声生成

1. 随机向量函数

hlsl
inline float2 Unity_Voronoi_RandomVector_float(float2 UV, float offset)
{
    float2x2 m = float2x2(15.27, 47.63, 99.41, 89.98);
    UV = frac(sin(mul(UV, m)));  // 哈希函数生成随机值
    return float2(sin(UV.y+offset)*0.5+0.5, cos(UV.x*offset)*0.5+0.5);
}

算法特点:使用固定矩阵和三角函数生成确定性随机,保证每帧计算结果一致。

2. Voronoi核心算法

hlsl
void Unity_Voronoi_float(float2 UV, float AngleOffset, float CellDensity, 
                          out float Out, out float Cells)
{
    float2 g = floor(UV * CellDensity);  // 网格坐标
    float2 f = frac(UV * CellDensity);   // 网格内偏移
    
    // 遍历相邻3x3网格,寻找最近的特征点
    for(int y=-1; y<=1; y++) {
        for(int x=-1; x<=1; x++) {
            float2 lattice = float2(x,y);
            float2 offset = Unity_Voronoi_RandomVector_float(lattice + g, AngleOffset);
            float d = distance(lattice + offset, f);
            
            if(d < res.x) {
                res = float3(d, offset.x, offset.y);
                Out = res.x;      // 最小距离
                Cells = res.y;     // 特征点信息
            }
        }
    }
}

Voronoi图原理:将空间划分为若干区域,每个区域由距离最近的特征点决定。在速度线效果中,Voronoi的最小距离值用于生成流动的纹理。

速度线生成逻辑

1. 参数配置

hlsl
// 极坐标变换
_PolarCoordinates = (r, θ)

// 仅保留径向距离用于边缘检测
_Split_PolarCoordinates = _PolarCoordinates.r

// 为Voronoi准备UV:角度作为U坐标,固定缩放创造拉伸效果
_TilingAndOffset = (_PolarCoordinates.θ, _PolarCoordinates.r) 
                   * float2(1, 200)  // 垂直方向剧烈拉伸

设计思路

  • 将角度映射到Voronoi的U方向,创造围绕中心的周向流动

  • 将径向距离放大200倍后映射到V方向,使线条垂直于半径方向

  • 结果:线条从中心向外放射,同时围绕中心旋转

2. 动态动画

hlsl
// 时间驱动的角度偏移
_Multiply_Time = _Time.y * 17.54;  // 流动速度

// 细胞密度控制
_Subtract_voronol = 3.0 - 0.06;    // ≈2.94,控制线条密度

// Voronoi计算
Unity_Voronoi_float(_TilingAndOffset, _Multiply_Time, _Subtract_voronol, 
                     _Voronoi_3, _Voronoi_4);

流动机制AngleOffset参数随时间变化,使Voronoi特征点旋转,带动线条周向运动。

3. 线条筛选

hlsl
// 径向距离与Voronoi距离相乘,让线条集中在边缘
_Multiply_Voronoi = _Split_PolarCoordinates * _Voronoi_3;

// 阈值筛选,只保留小于0.71的部分
_Step_Voronoi = step(0.71, _Multiply_Voronoi);  // 1表示内部,0表示线条

// 反转,让线条区域为1
_OneMinus_Voronoi = 1 - _Step_Voronoi;  // 1表示线条,0表示非线条

效果:只有径向距离较大(靠近边缘)且Voronoi距离较小(特征点附近)的区域被标记为速度线。

屏幕震动效果

hlsl
// 60Hz高频震动,与Voronoi动画同步
float shake = sin(_Time.y * 60.0) * 0.01;
half2 offsetUV = float2(shake, shake) * 0.3;

// 震动应用到UV采样
half4 col = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv + offsetUV);

设计意图:高频震动模拟高速运动时的视觉模糊和相机抖动,增强速度感。

颜色混合

hlsl
col.rgb = lerp(_SpeedLineColor, col, _OneMinus_Voronoi);

混合逻辑

  • _OneMinus_Voronoi == 1(线条区域):lerp返回col,保持原图

  • _OneMinus_Voronoi == 0(非线条区域):lerp返回_SpeedLineColor,显示速度线颜色

注意:当前实现中混合方向可能需要调整。通常应该是线条区域显示颜色,非线条区域保持原图。建议修改为:

hlsl
col.rgb = lerp(col, _SpeedLineColor, _OneMinus_Voronoi);

参数调节指南

 
 
参数 作用 推荐值 调节效果
RadialScale (0.6) 径向压缩 0.3-1.0 数值越大,线条越靠近中心
垂直拉伸 (200) 线条密度 50-500 数值越大,线条越密集
流动速度 (17.54) 动画速度 5-30 数值越大,线条流动越快
细胞密度 (2.94) 线条数量 1-10 数值越大,线条越多
阈值 (0.71) 线条粗细 0.3-0.9 数值越大,线条越细
震动频率 (60) 抖动速度 30-120 数值越大,抖动越快

效果组合逻辑

视觉层次

text
基础层:原图画面
震动层:高频UV抖动,模拟物理震动
速度线层:动态Voronoi线条,模拟视觉残留

时序效果

  1. 持续效果:线条持续流动,创造恒定的速度感

  2. 脉冲增强:可配合C#脚本,在加速时增强强度和密度

  3. 方向暗示:线条流动方向暗示运动方向(当前为周向)

 

5.模拟能量恢复、机体修复或逐渐显形的屏幕后处理Shader。该效果通过组合距离场计算噪声纹理采样边缘发光三种技术,实现从屏幕中心向外逐渐恢复的视觉特效,适用于角色复活、能量充能、伤势恢复等场景。

核心技术图解

text
输入图像 → 距离场计算 → 噪声采样 → 阈值判断 → 边缘检测 → 颜色混合 → 输出
    ↑           ↑           ↑           ↑           ↑           ↑
  _MainTex   uv - 0.5   _DissolveNoise  _DissolveAmount  _EdgeWidth  _DissolveEageColor
                distance    _DissolveNoiseTilling

距离场计算原理

1. 中心距离计算

hlsl
float2 uv1 = i.uv - 0.5;        // 将UV原点移动到屏幕中心
float distance = length(uv1);    // 计算像素到屏幕中心的欧几里得距离

数学意义

  • uv - 0.5:将UV坐标从[0,1]范围转换到[-0.5,0.5]范围

  • length():计算向量的模长,得到像素到中心的距离

  • 结果范围:中心点距离=0,四角距离≈0.707

视觉意义:利用距离值创建从中心向外的径向渐变,用于控制溶解的起始位置和扩散方向。

2. 距离分布特性

 
 
位置 UV坐标 距离值 溶解优先级
屏幕中心 (0.5, 0.5) 0 最晚溶解
边缘中点 (0.5, 0) 或 (0, 0.5) 0.5 中等
屏幕四角 (0,0) 或 (1,1) ≈0.707 最早溶解

设计意图:能量恢复从边缘开始向中心汇聚,符合视觉直觉——能量从外部流入核心。

噪声纹理采样

1. 噪声采样配置

hlsl
// 噪声纹理采样,支持Tilling控制
float noise = SAMPLE_TEXTURE2D(_DissolveNoise, sampler_DissolveNoise, 
                                i.uv * _DissolveNoiseTilling.xy).r;

噪声作用

  • 打破规则的圆形溶解,创造自然的不规则边缘

  • 每像素随机值,使溶解边缘呈现有机形态

  • Tilling参数控制噪声纹理的重复密度

2. 灰度值计算

hlsl
half gray = 1 - noise;  // 反转噪声,使亮部对应高溶解概率

反转目的:通常噪声纹理中白色(1)区域代表”可溶解”,黑色(0)区域代表”不可溶解”。反转后,原始噪声的暗部变为溶解区域,创造更自然的溶解效果。

溶解阈值算法

1. 核心阈值计算

hlsl
// cutoff = 溶解程度 + 距离 - 噪声*(1-溶解程度)
half cutoff = _DissolveAmount + distance - noise.r * (1 - _DissolveAmount);

数学分解

  • _DissolveAmount:基础溶解程度(0-1)

  • + distance:距离中心越远,cutoff值越大,越容易被溶解

  • - noise.r * (1 - _DissolveAmount):噪声调制,当_DissolveAmount较小时,噪声影响更大

物理意义:这个公式创建了一个动态阈值表面,其值在空间上随距离增加,在随机性上受噪声调制,整体随_DissolveAmount参数变化。

2. 阈值范围映射

hlsl
cutoff = lerp(-20.2, 10.01, cutoff);  // 将cutoff从[0,1]映射到[-20.2, 10.01]

映射目的

  • 扩展动态范围,使clip操作有明确的裁切边界

  • 负数区域保证被裁切(显示溶解效果)

  • 正数区域保证保留(显示原图)

3. 像素裁切

hlsl
half a = gray - cutoff;
clip(a);  // 如果a < 0,则丢弃该像素

裁切逻辑

  • a = gray - cutoff:比较噪声灰度值与动态阈值

  • gray < cutoff时,a < 0,像素被裁切(显示溶解)

  • gray >= cutoff时,像素保留(显示原图)

边缘发光效果

1. 边缘检测

hlsl
half edgeRate = cutoff + _EdgeWidth;        // 边缘区域的上限
half edge = step(gray, edgeRate);            // 当gray <= edgeRate时,edge=1

边缘定义:在裁切边界附近的一段区域内,gray值介于cutoffcutoff + _EdgeWidth之间的像素被标记为边缘。

2. 颜色混合

hlsl
half4 col = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv);
col = lerp(col, _DissolveEageColor, edge);   // 边缘区域混合发光颜色

混合效果

  • edge == 0(非边缘):保持原图颜色

  • edge == 1(边缘):显示发光颜色(支持HDR)

参数调节指南

 
 
参数 作用 推荐值 调节效果
_DissolveAmount 溶解程度 0-1动态变化 0=全屏原图,1=完全溶解
_EdgeWidth 边缘宽度 0.01-0.05 数值越大,发光边缘越宽
_DissolveEageColor 边缘颜色 HDR亮色(2,2,2,1) 决定边缘发光色
_DissolveNoiseTilling 噪声密度 (1,1)到(5,5) 数值越大,溶解细节越丰富

效果组合逻辑

视觉层次

text
基础层:原图画面(未溶解区域)
裁切层:完全消失区域(clip丢弃)
边缘层:发光过渡带(溶解边界)
© 版权声明
THE END
喜欢就支持一下吧
点赞9 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容