NoiseAndGrain.cs 7.2 KB

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