3 namespace UnityEngine
.Rendering
.PostProcessing
6 /// This class holds settings for the Grain effect.
9 [PostProcess(typeof(GrainRenderer
), "Unity/Grain")]
10 public sealed class Grain
: PostProcessEffectSettings
13 /// Set to <c>true</c> to render colored grain, <c>false</c> for grayscale grain.
15 [Tooltip("Enable the use of colored grain.")]
16 public BoolParameter colored
= new BoolParameter { value = true }
;
19 /// The strength (or visibility) of the Grain effect on screen. Higher values mean more visible grain.
21 [Range(0f
, 1f
), Tooltip("Grain strength. Higher values mean more visible grain.")]
22 public FloatParameter intensity
= new FloatParameter { value = 0f }
;
25 /// The size of grain particle on screen.
27 [Range(0.3f
, 3f
), Tooltip("Grain particle size.")]
28 public FloatParameter size
= new FloatParameter { value = 1f }
;
31 /// Controls the noisiness response curve based on scene luminance. Lower values mean less noise in dark areas.
33 [Range(0f
, 1f
), DisplayName("Luminance Contribution"), Tooltip("Controls the noise response curve based on scene luminance. Lower values mean less noise in dark areas.")]
34 public FloatParameter lumContrib
= new FloatParameter { value = 0.8f }
;
37 public override bool IsEnabledAndSupported(PostProcessRenderContext context
)
40 && intensity
.value > 0f
;
44 #if POSTFX_DEBUG_STATIC_GRAIN
45 #pragma warning disable 414
47 #if UNITY_2017_1_OR_NEWER
48 [UnityEngine
.Scripting
.Preserve
]
50 internal sealed class GrainRenderer
: PostProcessEffectRenderer
<Grain
>
52 RenderTexture m_GrainLookupRT
;
54 const int k_SampleCount
= 1024;
57 public override void Render(PostProcessRenderContext context
)
59 #if POSTFX_DEBUG_STATIC_GRAIN
60 // Chosen by a fair dice roll
62 float rndOffsetX
= 0f
;
63 float rndOffsetY
= 0f
;
65 float time
= Time
.realtimeSinceStartup
;
66 float rndOffsetX
= HaltonSeq
.Get(m_SampleIndex
& 1023, 2);
67 float rndOffsetY
= HaltonSeq
.Get(m_SampleIndex
& 1023, 3);
69 if (++m_SampleIndex
>= k_SampleCount
)
73 // Generate the grain lut for the current frame first
74 if (m_GrainLookupRT
== null || !m_GrainLookupRT
.IsCreated())
76 RuntimeUtilities
.Destroy(m_GrainLookupRT
);
78 m_GrainLookupRT
= new RenderTexture(128, 128, 0, GetLookupFormat())
80 filterMode
= FilterMode
.Bilinear
,
81 wrapMode
= TextureWrapMode
.Repeat
,
83 name
= "Grain Lookup Texture"
86 m_GrainLookupRT
.Create();
89 var sheet
= context
.propertySheets
.Get(context
.resources
.shaders
.grainBaker
);
90 sheet
.properties
.Clear();
91 sheet
.properties
.SetFloat(ShaderIDs
.Phase
, time
% 10f
);
92 sheet
.properties
.SetVector(ShaderIDs
.GrainNoiseParameters
, new Vector3(12.9898f
, 78.233f
, 43758.5453f
));
94 context
.command
.BeginSample("GrainLookup");
95 context
.command
.BlitFullscreenTriangle(BuiltinRenderTextureType
.None
, m_GrainLookupRT
, sheet
, settings
.colored
.value ? 1 : 0);
96 context
.command
.EndSample("GrainLookup");
98 // Send everything to the uber shader
99 var uberSheet
= context
.uberSheet
;
100 uberSheet
.EnableKeyword("GRAIN");
101 uberSheet
.properties
.SetTexture(ShaderIDs
.GrainTex
, m_GrainLookupRT
);
102 uberSheet
.properties
.SetVector(ShaderIDs
.Grain_Params1
, new Vector2(settings
.lumContrib
.value, settings
.intensity
.value * 20f
));
103 uberSheet
.properties
.SetVector(ShaderIDs
.Grain_Params2
, new Vector4((float)context
.width
/ (float)m_GrainLookupRT
.width
/ settings
.size
.value, (float)context
.height
/ (float)m_GrainLookupRT
.height
/ settings
.size
.value, rndOffsetX
, rndOffsetY
));
106 RenderTextureFormat
GetLookupFormat()
108 if (RenderTextureFormat
.ARGBHalf
.IsSupported())
109 return RenderTextureFormat
.ARGBHalf
;
111 return RenderTextureFormat
.ARGB32
;
114 public override void Release()
116 RuntimeUtilities
.Destroy(m_GrainLookupRT
);
117 m_GrainLookupRT
= null;
122 #if POSTFX_DEBUG_STATIC_GRAIN
123 #pragma warning restore 414