【URP】Unity[后处理]胶片颗粒FilmGrain
【从UnityURP开始探索游戏渲染】专栏-直达Film Grain的定义与作用
Film Grain是一种模拟传统摄影胶片颗粒感的后期处理效果,通过添加随机噪点纹理增强画面的艺术表现力。其核心用途包括:
[*]复古风格模拟:重现胶片摄影的颗粒质感,增强怀旧氛围
[*]画面细节强化:掩盖低分辨率纹理的瑕疵,提升视觉丰富度
[*]电影感塑造:配合色调映射、色差等效果构建电影级视觉风格
发展历史
[*]传统胶片时代:物理银盐颗粒形成的自然噪点
[*]数字时代初期:通过简单噪声算法模拟(如Perlin噪声)
[*]现代游戏引擎:HDRP/URP等管线集成预设化系统,支持物理准确的颗粒分布模型(如Kodak系列预设)
原理
Unity URP中的Film Grain效果通过噪声纹理叠加和亮度响应曲线实现胶片颗粒模拟.
噪声生成机制
[*]预设纹理采样:内置Kodak/Agfa等胶片颗粒的预烘焙LUT纹理(64x64分辨率),通过屏幕UV坐标进行双线性采样
[*]动态噪声合成:当选择"Custom"模式时,使用Simplex噪声算法实时生成3D噪声场,通过时间参数实现动态流动效果
[*]色彩空间转换:噪声值在YCoCg色彩空间进行混合,避免RGB通道直接叠加导致的色偏问题
亮度响应系统
hlsl
float grainIntensity = intensity * (1 - smoothstep(0.5, 1.0, luminance));该公式根据像素亮度动态调节颗粒强度,使暗部保留更多噪点(响应曲线参数控制过渡斜率)
实现示例
该Shader实现包含噪声纹理平铺、亮度自适应调节和色彩安全混合三个关键技术点
[*]Filmgrain.shader
Shader "PostProcessing/FilmGrain"
{
Properties {
_GrainTex ("Noise Texture", 2D) = "white" {}
_Intensity ("Intensity", Range(0,1)) = 0.5
_Response ("Response", Range(0,1)) = 0.8
}
SubShader {
Pass {
HLSLPROGRAM
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
TEXTURE2D(_GrainTex);
SAMPLER(sampler_GrainTex);
float _Intensity;
float _Response;
float4 Frag(Varyings input) : SV_Target {
float2 uv = input.uv * float2(80,45); // 平铺噪声
float3 grain = SAMPLE_TEXTURE2D(_GrainTex,sampler_GrainTex,uv).rgb;
float luminance = Luminance(SceneColor.rgb);
float adaptive = lerp(1.0, 1.0-luminance, _Response);
return SceneColor * (1.0 + grain * _Intensity * adaptive);
}
ENDHLSL
}
}
}
管线集成流程
[*]渲染阶段:在URP的PostProcessingStack中插入FilmGrainPass,执行顺序在Tonemapping之后、FXAA之前
[*]性能优化:采用1/4分辨率渲染噪声纹理,通过硬件线性滤波降低带宽消耗
[*]移动端适配:使用ARM NEON指令集加速噪声计算,在GPU Tile-Based架构下减少内存访问次数
URP实现流程
[*]FilmGrainExample.cs
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
public class CustomFilmGrain : VolumeComponent, IPostProcessComponent {
public FilmGrainLookupParameter type = new FilmGrainLookupParameter(FilmGrainLookup.Kodak_200);
public ClampedFloatParameter intensity = new ClampedFloatParameter(0f, 0f, 1f);
public ClampedFloatParameter response = new ClampedFloatParameter(0.8f, 0f, 1f);
public bool IsActive() => intensity.value > 0f;
public bool IsTileCompatible() => false;
}
[*]FilmGrainRenderer.cs
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
public class FilmGrainRenderer : ScriptableRendererFeature {
class CustomPass : ScriptableRenderPass {
// 渲染逻辑实现...
}
public override void Create() {
// 初始化代码...
}
}
参数详解与用例
参数类型说明典型用例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开始探索游戏渲染】专栏-直达
(欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! 谢谢分享,试用一下 过来提前占个楼 谢谢分享,辛苦了 感谢发布原创作品,程序园因你更精彩
页:
[1]