找回密码
 立即注册
首页 业界区 业界 【URP】Unity[后处理]胶片颗粒FilmGrain

【URP】Unity[后处理]胶片颗粒FilmGrain

迎脾 2025-11-6 10:45:01
【从UnityURP开始探索游戏渲染】专栏-直达
Film Grain的定义与作用

Film Grain是一种模拟传统摄影胶片颗粒感的后期处理效果,通过添加随机噪点纹理增强画面的艺术表现力。其核心用途包括:

  • 复古风格模拟:重现胶片摄影的颗粒质感,增强怀旧氛围
  • 画面细节强化:掩盖低分辨率纹理的瑕疵,提升视觉丰富度
  • 电影感塑造:配合色调映射、色差等效果构建电影级视觉风格
发展历史


  • 传统胶片时代‌:物理银盐颗粒形成的自然噪点
  • 数字时代初期‌:通过简单噪声算法模拟(如Perlin噪声)
  • 现代游戏引擎‌:HDRP/URP等管线集成预设化系统,支持物理准确的颗粒分布模型(如Kodak系列预设)
原理

Unity URP中的Film Grain效果通过噪声纹理叠加和亮度响应曲线实现胶片颗粒模拟.
噪声生成机制


  • 预设纹理采样‌:内置Kodak/Agfa等胶片颗粒的预烘焙LUT纹理(64x64分辨率),通过屏幕UV坐标进行双线性采样
  • 动态噪声合成‌:当选择"Custom"模式时,使用Simplex噪声算法实时生成3D噪声场,通过时间参数实现动态流动效果
  • 色彩空间转换‌:噪声值在YCoCg色彩空间进行混合,避免RGB通道直接叠加导致的色偏问题
亮度响应系统
  1. hlsl
  2. float grainIntensity = intensity * (1 - smoothstep(0.5, 1.0, luminance));
复制代码
该公式根据像素亮度动态调节颗粒强度,使暗部保留更多噪点(响应曲线参数控制过渡斜率)
实现示例

该Shader实现包含噪声纹理平铺、亮度自适应调节和色彩安全混合三个关键技术点

  • Filmgrain.shader
    1. Shader "PostProcessing/FilmGrain"
    2. {
    3.     Properties {
    4.         _GrainTex ("Noise Texture", 2D) = "white" {}
    5.         _Intensity ("Intensity", Range(0,1)) = 0.5
    6.         _Response ("Response", Range(0,1)) = 0.8
    7.     }
    8.     SubShader {
    9.         Pass {
    10.             HLSLPROGRAM
    11.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
    12.             TEXTURE2D(_GrainTex);
    13.             SAMPLER(sampler_GrainTex);
    14.             float _Intensity;
    15.             float _Response;
    16.             float4 Frag(Varyings input) : SV_Target {
    17.                 float2 uv = input.uv * float2(80,45); // 平铺噪声
    18.                 float3 grain = SAMPLE_TEXTURE2D(_GrainTex,sampler_GrainTex,uv).rgb;
    19.                 float luminance = Luminance(SceneColor.rgb);
    20.                 float adaptive = lerp(1.0, 1.0-luminance, _Response);
    21.                 return SceneColor * (1.0 + grain * _Intensity * adaptive);
    22.             }
    23.             ENDHLSL
    24.         }
    25.     }
    26. }
    复制代码
管线集成流程


  • 渲染阶段‌:在URP的PostProcessingStack中插入FilmGrainPass,执行顺序在Tonemapping之后、FXAA之前
  • 性能优化‌:采用1/4分辨率渲染噪声纹理,通过硬件线性滤波降低带宽消耗
  • 移动端适配‌:使用ARM NEON指令集加速噪声计算,在GPU Tile-Based架构下减少内存访问次数
URP实现流程


  • FilmGrainExample.cs
    1. using UnityEngine;
    2. using UnityEngine.Rendering;
    3. using UnityEngine.Rendering.Universal;
    4. [VolumeComponentMenu("Post-processing/Film Grain")]
    5. public class CustomFilmGrain : VolumeComponent, IPostProcessComponent {
    6.     public FilmGrainLookupParameter type = new FilmGrainLookupParameter(FilmGrainLookup.Kodak_200);
    7.     public ClampedFloatParameter intensity = new ClampedFloatParameter(0f, 0f, 1f);
    8.     public ClampedFloatParameter response = new ClampedFloatParameter(0.8f, 0f, 1f);
    9.     public bool IsActive() => intensity.value > 0f;
    10.     public bool IsTileCompatible() => false;
    11. }
    复制代码
  • FilmGrainRenderer.cs
    1. using UnityEngine;
    2. using UnityEngine.Rendering;
    3. using UnityEngine.Rendering.Universal;
    4. public class FilmGrainRenderer : ScriptableRendererFeature {
    5.     class CustomPass : ScriptableRenderPass {
    6.         // 渲染逻辑实现...
    7.     }
    8.     public override void Create() {
    9.         // 初始化代码...
    10.     }
    11. }
    复制代码
参数详解与用例

参数类型说明典型用例TypeEnum预设颗粒类型(Kodak200/400等)选择Agfa400模拟16mm胶片Intensity0-1颗粒可见度0.3-0.5用于复古RPG游戏Response0-1亮度响应曲线0.7使亮部颗粒减弱Texture2D自定义噪点贴图制作数字故障艺术效果操作步骤(URP 2022.1+)


  • 创建Volume对象:GameObject > Volume
  • 添加Film Grain覆盖:Add Override > Film Grain
  • 配置参数示例:
    Type = Kodak500T
    Intensity = 0.4
    Response = 0.65

性能优化建议


  • 移动端使用Quarter分辨率
  • 动态调整Intensity(剧情过场时增强)
  • 禁用非必要时的Volume更新
<blockquote>
【从UnityURP开始探索游戏渲染】专栏-直达
(欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册