1 using System;
2 using UnityEngine;
3 using Random = UnityEngine.Random;
4
5 namespace UnityStandardAssets.ImageEffects
6 {
7 [ExecuteInEditMode]
8 [RequireComponent (typeof(Camera))]
9 [AddComponentMenu ("Image Effects/Noise/Noise And Grain (Filmic)")]
10 public class NoiseAndGrain : PostEffectsBase
11 {
12
13 public float intensityMultiplier = 0.25f;
14
15 public float generalIntensity = 0.5f;
16 public float blackIntensity = 1.0f;
17 public float whiteIntensity = 1.0f;
18 public float midGrey = 0.2f;
19
20 public bool dx11Grain = false;
21 public float softness = 0.0f;
22 public bool monochrome = false;
23
24 public Vector3 intensities = new Vector3(1.0f, 1.0f, 1.0f);
25 public Vector3 tiling = new Vector3(64.0f, 64.0f, 64.0f);
26 public float monochromeTiling = 64.0f;
27
28 public FilterMode filterMode = FilterMode.Bilinear;
29
30 public Texture2D noiseTexture;
31
32 public Shader noiseShader;
33 private Material noiseMaterial = null;
34
35 public Shader dx11NoiseShader;
36 private Material dx11NoiseMaterial = null;
37
38 private static float TILE_AMOUNT = 64.0f;
39
40
41 public override bool CheckResources ()
42 {
43 CheckSupport (false);
44
45 noiseMaterial = CheckShaderAndCreateMaterial (noiseShader, noiseMaterial);
46
47 if (dx11Grain && supportDX11)
48 {
49 #if UNITY_EDITOR
50 dx11NoiseShader = Shader.Find("Hidden/NoiseAndGrainDX11");
51 #endif
52 dx11NoiseMaterial = CheckShaderAndCreateMaterial (dx11NoiseShader, dx11NoiseMaterial);
53 }
54
55 if (!isSupported)
56 ReportAutoDisable ();
57 return isSupported;
58 }
59
60 void OnRenderImage (RenderTexture source, RenderTexture destination)
61 {
62 if (CheckResources()==false || (null==noiseTexture))
63 {
64 Graphics.Blit (source, destination);
65 if (null==noiseTexture) {
66 Debug.LogWarning("Noise & Grain effect failing as noise texture is not assigned. please assign.", transform);
67 }
68 return;
69 }
70
71 softness = Mathf.Clamp(softness, 0.0f, 0.99f);
72
73 if (dx11Grain && supportDX11)
74 {
75 // We have a fancy, procedural noise pattern in this version, so no texture needed
76
77 dx11NoiseMaterial.SetFloat("_DX11NoiseTime", Time.frameCount);
78 dx11NoiseMaterial.SetTexture ("_NoiseTex", noiseTexture);
79 dx11NoiseMaterial.SetVector ("_NoisePerChannel", monochrome ? Vector3.one : intensities);
80 dx11NoiseMaterial.SetVector ("_MidGrey", new Vector3(midGrey, 1.0f/(1.0f-midGrey), -1.0f/midGrey));
81 dx11NoiseMaterial.SetVector ("_NoiseAmount", new Vector3(generalIntensity, blackIntensity, whiteIntensity) * intensityMultiplier);
82
83 if (softness > Mathf.Epsilon)
84 {
85 RenderTexture rt = RenderTexture.GetTemporary((int) (source.width * (1.0f-softness)), (int) (source.height * (1.0f-softness)));
86 DrawNoiseQuadGrid (source, rt, dx11NoiseMaterial, noiseTexture, monochrome ? 3 : 2);
87 dx11NoiseMaterial.SetTexture("_NoiseTex", rt);
88 Graphics.Blit(source, destination, dx11NoiseMaterial, 4);
89 RenderTexture.ReleaseTemporary(rt);
90 }
91 else
92 DrawNoiseQuadGrid (source, destination, dx11NoiseMaterial, noiseTexture, (monochrome ? 1 : 0));
93 }
94 else
95 {
96 // normal noise (DX9 style)
97
98 if (noiseTexture) {
99 noiseTexture.wrapMode = TextureWrapMode.Repeat;
100 noiseTexture.filterMode = filterMode;
101 }
102
103 noiseMaterial.SetTexture ("_NoiseTex", noiseTexture);
104 noiseMaterial.SetVector ("_NoisePerChannel", monochrome ? Vector3.one : intensities);
105 noiseMaterial.SetVector ("_NoiseTilingPerChannel", monochrome ? Vector3.one * monochromeTiling : tiling);
106 noiseMaterial.SetVector ("_MidGrey", new Vector3(midGrey, 1.0f/(1.0f-midGrey), -1.0f/midGrey));
107 noiseMaterial.SetVector ("_NoiseAmount", new Vector3(generalIntensity, blackIntensity, whiteIntensity) * intensityMultiplier);
108
109 if (softness > Mathf.Epsilon)
110 {
111 RenderTexture rt2 = RenderTexture.GetTemporary((int) (source.width * (1.0f-softness)), (int) (source.height * (1.0f-softness)));
112 DrawNoiseQuadGrid (source, rt2, noiseMaterial, noiseTexture, 2);
113 noiseMaterial.SetTexture("_NoiseTex", rt2);
114 Graphics.Blit(source, destination, noiseMaterial, 1);
115 RenderTexture.ReleaseTemporary(rt2);
116 }
117 else
118 DrawNoiseQuadGrid (source, destination, noiseMaterial, noiseTexture, 0);
119 }
120 }
121
122 static void DrawNoiseQuadGrid (RenderTexture source, RenderTexture dest, Material fxMaterial, Texture2D noise, int passNr)
123 {
124 RenderTexture.active = dest;
125
126 float noiseSize = (noise.width * 1.0f);
127 float subDs = (1.0f * source.width) / TILE_AMOUNT;
128
129 fxMaterial.SetTexture ("_MainTex", source);
130
131 GL.PushMatrix ();
132 GL.LoadOrtho ();
133
134 float aspectCorrection = (1.0f * source.width) / (1.0f * source.height);
135 float stepSizeX = 1.0f / subDs;
136 float stepSizeY = stepSizeX * aspectCorrection;
137 float texTile = noiseSize / (noise.width * 1.0f);
138
139 fxMaterial.SetPass (passNr);
140
141 GL.Begin (GL.QUADS);
142
143 for (float x1 = 0.0f; x1 < 1.0f; x1 += stepSizeX)
144 {
145 for (float y1 = 0.0f; y1 < 1.0f; y1 += stepSizeY)
146 {
147 float tcXStart = Random.Range (0.0f, 1.0f);
148 float tcYStart = Random.Range (0.0f, 1.0f);
149
150 //Vector3 v3 = Random.insideUnitSphere;
151 //Color c = new Color(v3.x, v3.y, v3.z);
152
153 tcXStart = Mathf.Floor(tcXStart*noiseSize) / noiseSize;
154 tcYStart = Mathf.Floor(tcYStart*noiseSize) / noiseSize;
155
156 float texTileMod = 1.0f / noiseSize;
157
158 GL.MultiTexCoord2 (0, tcXStart, tcYStart);
159 GL.MultiTexCoord2 (1, 0.0f, 0.0f);
160 //GL.Color( c );
161 GL.Vertex3 (x1, y1, 0.1f);
162 GL.MultiTexCoord2 (0, tcXStart + texTile * texTileMod, tcYStart);
163 GL.MultiTexCoord2 (1, 1.0f, 0.0f);
164 //GL.Color( c );
165 GL.Vertex3 (x1 + stepSizeX, y1, 0.1f);
166 GL.MultiTexCoord2 (0, tcXStart + texTile * texTileMod, tcYStart + texTile * texTileMod);
167 GL.MultiTexCoord2 (1, 1.0f, 1.0f);
168 //GL.Color( c );
169 GL.Vertex3 (x1 + stepSizeX, y1 + stepSizeY, 0.1f);
170 GL.MultiTexCoord2 (0, tcXStart, tcYStart + texTile * texTileMod);
171 GL.MultiTexCoord2 (1, 0.0f, 1.0f);
172 //GL.Color( c );
173 GL.Vertex3 (x1, y1 + stepSizeY, 0.1f);
174 }
175 }
176
177 GL.End ();
178 GL.PopMatrix ();
179 }
180 }
181 }