Skip to content
This repository was archived by the owner on Nov 30, 2020. It is now read-only.

Commit ed86900

Browse files
committed
Reworked the grain effect; defaults have changed !
1 parent 0f1237e commit ed86900

5 files changed

Lines changed: 73 additions & 117 deletions

File tree

PostProcessing/Editor/Models/GrainModelEditor.cs

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,13 @@ public class GrainModelEditor : PostProcessingModelEditor
99
{
1010
SerializedProperty m_Colored;
1111
SerializedProperty m_Intensity;
12-
SerializedProperty m_WeightR;
13-
SerializedProperty m_WeightG;
14-
SerializedProperty m_WeightB;
1512
SerializedProperty m_Size;
1613
SerializedProperty m_LuminanceContribution;
1714

1815
public override void OnEnable()
1916
{
2017
m_Colored = FindSetting((Settings x) => x.colored);
2118
m_Intensity = FindSetting((Settings x) => x.intensity);
22-
m_WeightR = FindSetting((Settings x) => x.weightR);
23-
m_WeightG = FindSetting((Settings x) => x.weightG);
24-
m_WeightB = FindSetting((Settings x) => x.weightB);
2519
m_Size = FindSetting((Settings x) => x.size);
2620
m_LuminanceContribution = FindSetting((Settings x) => x.luminanceContribution);
2721
}
@@ -32,18 +26,6 @@ public override void OnInspectorGUI()
3226
EditorGUILayout.PropertyField(m_LuminanceContribution);
3327
EditorGUILayout.PropertyField(m_Size);
3428
EditorGUILayout.PropertyField(m_Colored);
35-
36-
if (m_Colored.boolValue)
37-
{
38-
EditorGUILayout.Space();
39-
EditorGUILayout.LabelField("Channel Weights", EditorStyles.boldLabel);
40-
41-
EditorGUI.indentLevel++;
42-
EditorGUILayout.PropertyField(m_WeightR, EditorGUIHelper.GetContent("Red"));
43-
EditorGUILayout.PropertyField(m_WeightG, EditorGUIHelper.GetContent("Green"));
44-
EditorGUILayout.PropertyField(m_WeightB, EditorGUIHelper.GetContent("Blue"));
45-
EditorGUI.indentLevel--;
46-
}
4729
}
4830
}
4931
}

PostProcessing/Resources/Shaders/GrainGen.shader

Lines changed: 50 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,78 @@
1-
Shader "Hidden/Post FX/Grain Generator"
1+
Shader "Hidden/Post FX/Grain Generator"
22
{
33
CGINCLUDE
4-
4+
5+
#pragma exclude_renderers d3d11_9x
6+
#pragma target 3.0
57
#include "UnityCG.cginc"
68
#include "Common.cginc"
79

8-
float4 _Params; // x: size, y: time, z: cos_angle, w: sin_angle
10+
float _Phase;
911

10-
float3 Rnm(float2 tc, float time)
12+
// Implementation based on Timothy Lottes' "Large Grain"
13+
// Reference code: https://www.shadertoy.com/view/4sSXDW
14+
// Other article of interest: http://devlog-martinsh.blogspot.fr/2013/05/image-imperfections-and-film-grain-post.html
15+
float Noise(float2 n, float x)
1116
{
12-
float noise = sin(dot(tc + time.xx, float2(12.9898, 78.233))) * 43758.5453;
13-
return frac(noise.xxx * float3(1.0, 1.2154, 1.3647)) * 2.0 - 1.0;
17+
n += x;
18+
return frac(sin(dot(n.xy, float2(12.9898, 78.233))) * 43758.5453);
1419
}
1520

16-
float Fade(float t)
21+
float Step1(float2 uv, float n)
1722
{
18-
return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);
23+
float b = 2.0, c = -12.0;
24+
return (1.0 / (4.0 + b * 4.0 + abs(c))) * (
25+
Noise(uv + float2(-1.0, -1.0), n) +
26+
Noise(uv + float2( 0.0, -1.0), n) * b +
27+
Noise(uv + float2( 1.0, -1.0), n) +
28+
Noise(uv + float2(-1.0, 0.0), n) * b +
29+
Noise(uv + float2( 0.0, 0.0), n) * c +
30+
Noise(uv + float2( 1.0, 0.0), n) * b +
31+
Noise(uv + float2(-1.0, 1.0), n) +
32+
Noise(uv + float2( 0.0, 1.0), n) * b +
33+
Noise(uv + float2( 1.0, 1.0), n)
34+
);
1935
}
2036

21-
// 2d gradient noise
22-
float PNoise(float2 p, float time)
37+
float Step2(float2 uv, float n)
2338
{
24-
const float kPermTexUnit = 1.0 / 256.0;
25-
const float kPermTexUnitHalf = 0.5 / 256.0;
26-
27-
float2 pi = kPermTexUnit * floor(p) + kPermTexUnitHalf;
28-
float2 pf = frac(p);
29-
30-
float perm00 = Rnm(pi, time).z;
31-
float2 grad000 = Rnm(float2(perm00, kPermTexUnitHalf), time).xy * 4.0 - 1.0;
32-
float n000 = dot(grad000, pf);
33-
34-
float perm01 = Rnm(pi + float2(0.0, kPermTexUnit), time).z;
35-
half2 grad010 = Rnm(float2(perm01, kPermTexUnitHalf), time).xy * 4.0 - 1.0;
36-
float n010 = dot(grad010, pf - float2(0.0, 1.0));
37-
38-
float perm10 = Rnm(pi + float2(kPermTexUnit, 0.0), time).z;
39-
float2 grad100 = Rnm(float2(perm10, kPermTexUnitHalf), time).xy * 4.0 - 1.0;
40-
float n100 = dot(grad100, pf - float2(1.0, 0.0));
41-
42-
float perm11 = Rnm(pi + float2(kPermTexUnit, kPermTexUnit), time).z;
43-
float2 grad110 = Rnm(float2(perm11, kPermTexUnitHalf), time).xy * 4.0 - 1.0;
44-
float n110 = dot(grad110, pf - float2(1.0, 1.0));
45-
46-
float2 n_x = lerp(float2(n000, n010), float2(n100, n110), Fade(pf.x));
39+
float b = 2.0, c = 4.0;
40+
return (1.0 / (4.0 + b * 4.0 + abs(c))) * (
41+
Step1(uv + float2(-1.0, -1.0), n) +
42+
Step1(uv + float2( 0.0, -1.0), n) * b +
43+
Step1(uv + float2( 1.0, -1.0), n) +
44+
Step1(uv + float2(-1.0, 0.0), n) * b +
45+
Step1(uv + float2( 0.0, 0.0), n) * c +
46+
Step1(uv + float2( 1.0, 0.0), n) * b +
47+
Step1(uv + float2(-1.0, 1.0), n) +
48+
Step1(uv + float2( 0.0, 1.0), n) * b +
49+
Step1(uv + float2( 1.0, 1.0), n)
50+
);
51+
}
4752

48-
return lerp(n_x.x, n_x.y, Fade(pf.y));
53+
float Step3BW(float2 uv)
54+
{
55+
return Step2(uv, frac(_Phase));
4956
}
5057

51-
float2 CoordRot(float2 tc, float2 angle)
58+
float3 Step3(float2 uv)
5259
{
53-
float s = angle.y;
54-
float c = angle.x;
55-
tc = tc * 2.0 - 1.0;
56-
float2 rot = float2((tc.x * c) - (tc.y * s), (tc.y * c) + (tc.x * s));
57-
return rot * 0.5 + 0.5;
60+
float a = Step2(uv, 0.07 * frac(_Phase));
61+
float b = Step2(uv, 0.11 * frac(_Phase));
62+
float c = Step2(uv, 0.13 * frac(_Phase));
63+
return float3(a, b, c);
5864
}
5965

6066
float4 FragGrain(VaryingsDefault i) : SV_Target
6167
{
62-
float2 rotCoords = CoordRot(i.uv, _Params.zw);
63-
float n = PNoise(rotCoords * (192.0).xx / _Params.x, _Params.y);
64-
return n.xxxx;
68+
float grain = Step3BW(i.uv * float2(192.0, 192.0));
69+
return float4(grain.xxx, 1.0);
6570
}
6671

6772
float4 FragGrainColored(VaryingsDefault i) : SV_Target
6873
{
69-
float2 rotCoordsR = CoordRot(i.uv, _Params.zw);
70-
float2 rotCoordsG = CoordRot(i.uv + (0.1).xx, _Params.zw);
71-
float2 rotCoordsB = CoordRot(i.uv - (0.1).xx, _Params.zw);
72-
73-
float r = PNoise(rotCoordsR * (192.0).xx / _Params.x, _Params.y);
74-
float g = PNoise(rotCoordsG * (192.0).xx / _Params.x, _Params.y);
75-
float b = PNoise(rotCoordsB * (192.0).xx / _Params.x, _Params.y);
76-
77-
return float4(r, g, b, 1.0);
74+
float3 grain = Step3(i.uv * float2(192.0, 192.0));
75+
return float4(grain, 1.0);
7876
}
7977

8078
ENDCG

PostProcessing/Resources/Shaders/Uber.shader

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ Shader "Hidden/Post FX/Uber Shader"
6262
half4 _UserLut_Params; // @see _LogLut_Params
6363

6464
// Grain
65-
half4 _Grain_Params1; // x: lum_contrib, y: intensityR, z: intensityG, w: intensityB
65+
half2 _Grain_Params1; // x: lum_contrib, y: intensity
6666
half4 _Grain_Params2; // x: xscale, h: yscale, z: xoffset, w: yoffset
6767
sampler2D _GrainTex;
6868

@@ -273,17 +273,16 @@ Shader "Hidden/Post FX/Uber Shader"
273273

274274
color = saturate(color);
275275

276-
// Grain / dithering
276+
// Grain
277277
#if (GRAIN)
278278
{
279279
float3 grain = tex2D(_GrainTex, uv * _Grain_Params2.xy + _Grain_Params2.zw).rgb;
280280

281281
// Noisiness response curve based on scene luminance
282-
float luminance = lerp(0.0, saturate(AcesLuminance(color)), _Grain_Params1.x);
283-
float lum = smoothstep(0.2, 0.0, luminance) + luminance;
282+
float lum = 1.0 - sqrt(AcesLuminance(color));
283+
lum = lerp(1.0, lum, _Grain_Params1.x);
284284

285-
grain = lerp((0.0).xxx, grain, Pow4(lum).xxx);
286-
color += grain * _Grain_Params1.yzw;
285+
color += color * grain * _Grain_Params1.y * lum;
287286
}
288287
#endif
289288

PostProcessing/Runtime/Components/GrainComponent.cs

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ static class Uniforms
77
internal static readonly int _Grain_Params1 = Shader.PropertyToID("_Grain_Params1");
88
internal static readonly int _Grain_Params2 = Shader.PropertyToID("_Grain_Params2");
99
internal static readonly int _GrainTex = Shader.PropertyToID("_GrainTex");
10-
internal static readonly int _Params = Shader.PropertyToID("_Params");
10+
internal static readonly int _Phase = Shader.PropertyToID("_Phase");
1111
}
1212

1313
public override bool active
@@ -35,22 +35,21 @@ public override void Prepare(Material uberMaterial)
3535

3636
uberMaterial.EnableKeyword("GRAIN");
3737

38+
float rndOffsetX;
39+
float rndOffsetY;
40+
3841
#if POSTFX_DEBUG_STATIC_GRAIN
3942
// Chosen by a fair dice roll
4043
float time = 4f;
41-
float rndXOffset = 0f;
42-
float rndYOffset = 0f;
44+
rndOffsetX = 0f;
45+
rndOffsetY = 0f;
4346
#else
4447
float time = Time.realtimeSinceStartup;
45-
float rndXOffset = Random.value;
46-
float rndYOffset = Random.value;
48+
rndOffsetX = Random.value;
49+
rndOffsetY = Random.value;
4750
#endif
4851

49-
// Used for sample rotation in Filmic mode and position offset in Fast mode
50-
const float kRotationOffset = 1.425f;
51-
float c = Mathf.Cos(time + kRotationOffset);
52-
float s = Mathf.Sin(time + kRotationOffset);
53-
52+
// Generate the grain lut for the current frame first
5453
if (m_GrainLookupRT == null || !m_GrainLookupRT.IsCreated())
5554
{
5655
GraphicsUtils.Destroy(m_GrainLookupRT);
@@ -67,24 +66,14 @@ public override void Prepare(Material uberMaterial)
6766
}
6867

6968
var grainMaterial = context.materialFactory.Get("Hidden/Post FX/Grain Generator");
70-
grainMaterial.SetVector(Uniforms._Params, new Vector4(settings.size, time / 20f, c, s));
69+
grainMaterial.SetFloat(Uniforms._Phase, time / 20f);
7170

7271
Graphics.Blit((Texture)null, m_GrainLookupRT, grainMaterial, settings.colored ? 1 : 0);
7372

73+
// Send everything to the uber shader
7474
uberMaterial.SetTexture(Uniforms._GrainTex, m_GrainLookupRT);
75-
76-
float intensity = settings.intensity * 0.1f;
77-
78-
if (!settings.colored)
79-
{
80-
uberMaterial.SetVector(Uniforms._Grain_Params1, new Vector4(settings.luminanceContribution, intensity, intensity, intensity));
81-
}
82-
else
83-
{
84-
uberMaterial.SetVector(Uniforms._Grain_Params1, new Vector4(settings.luminanceContribution, settings.weightR * intensity, settings.weightG * intensity, settings.weightB * intensity));
85-
}
86-
87-
uberMaterial.SetVector(Uniforms._Grain_Params2, new Vector4((float)context.width / (float)m_GrainLookupRT.width, (float)context.height / (float)m_GrainLookupRT.height, rndXOffset, rndYOffset));
75+
uberMaterial.SetVector(Uniforms._Grain_Params1, new Vector2(settings.luminanceContribution, settings.intensity * 20f));
76+
uberMaterial.SetVector(Uniforms._Grain_Params2, new Vector4((float)context.width / (float)m_GrainLookupRT.width / settings.size, (float)context.height / (float)m_GrainLookupRT.height / settings.size, rndOffsetX, rndOffsetY));
8877
}
8978
}
9079
}

PostProcessing/Runtime/Models/GrainModel.cs

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,7 @@ public struct Settings
1414
[Range(0f, 1f), Tooltip("Grain strength. Higher means more visible grain.")]
1515
public float intensity;
1616

17-
[Range(0f, 2f), Tooltip("Grain weight for the red channel. Higher means more visible grain.")]
18-
public float weightR;
19-
20-
[Range(0f, 2f), Tooltip("Grain weight for the green channel. Higher means more visible grain.")]
21-
public float weightG;
22-
23-
[Range(0f, 2f), Tooltip("Grain weight for the blue channel. Higher means more visible grain.")]
24-
public float weightB;
25-
26-
[Range(1.5f, 3f), Tooltip("Grain particle size in \"Filmic\" mode.")]
17+
[Range(1f, 3f), Tooltip("Grain particle size in \"Filmic\" mode.")]
2718
public float size;
2819

2920
[Range(0f, 1f), Tooltip("Controls the noisiness response curve based on scene luminance. Lower values mean less noise in dark areas.")]
@@ -35,13 +26,10 @@ public static Settings defaultSettings
3526
{
3627
return new Settings
3728
{
38-
colored = false,
39-
intensity = 0.1f,
40-
weightR = 1f,
41-
weightG = 1f,
42-
weightB = 1f,
43-
size = 1.6f,
44-
luminanceContribution = 0.1f
29+
colored = true,
30+
intensity = 0.5f,
31+
size = 1f,
32+
luminanceContribution = 0.8f
4533
};
4634
}
4735
}

0 commit comments

Comments
 (0)