NoiseAndScratches.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  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 Scratches")]
  9. public class NoiseAndScratches : MonoBehaviour
  10. {
  11. /// Monochrome noise just adds grain. Non-monochrome noise
  12. /// more resembles VCR as it adds noise in YUV color space,
  13. /// thus introducing magenta/green colors.
  14. public bool monochrome = true;
  15. private bool rgbFallback = false;
  16. // Noise grain takes random intensity from Min to Max.
  17. [Range(0.0f,5.0f)]
  18. public float grainIntensityMin = 0.1f;
  19. [Range(0.0f, 5.0f)]
  20. public float grainIntensityMax = 0.2f;
  21. /// The size of the noise grains (1 = one pixel).
  22. [Range(0.1f, 50.0f)]
  23. public float grainSize = 2.0f;
  24. // Scratches take random intensity from Min to Max.
  25. [Range(0.0f, 5.0f)]
  26. public float scratchIntensityMin = 0.05f;
  27. [Range(0.0f, 5.0f)]
  28. public float scratchIntensityMax = 0.25f;
  29. /// Scratches jump to another locations at this times per second.
  30. [Range(1.0f, 30.0f)]
  31. public float scratchFPS = 10.0f;
  32. /// While scratches are in the same location, they jitter a bit.
  33. [Range(0.0f, 1.0f)]
  34. public float scratchJitter = 0.01f;
  35. public Texture grainTexture;
  36. public Texture scratchTexture;
  37. public Shader shaderRGB;
  38. public Shader shaderYUV;
  39. private Material m_MaterialRGB;
  40. private Material m_MaterialYUV;
  41. private float scratchTimeLeft = 0.0f;
  42. private float scratchX, scratchY;
  43. protected void Start ()
  44. {
  45. if ( shaderRGB == null || shaderYUV == null )
  46. {
  47. Debug.Log( "Noise shaders are not set up! Disabling noise effect." );
  48. enabled = false;
  49. }
  50. else
  51. {
  52. if ( !shaderRGB.isSupported ) // disable effect if RGB shader is not supported
  53. enabled = false;
  54. else if ( !shaderYUV.isSupported ) // fallback to RGB if YUV is not supported
  55. rgbFallback = true;
  56. }
  57. }
  58. protected Material material {
  59. get {
  60. if ( m_MaterialRGB == null ) {
  61. m_MaterialRGB = new Material( shaderRGB );
  62. m_MaterialRGB.hideFlags = HideFlags.HideAndDontSave;
  63. }
  64. if ( m_MaterialYUV == null && !rgbFallback ) {
  65. m_MaterialYUV = new Material( shaderYUV );
  66. m_MaterialYUV.hideFlags = HideFlags.HideAndDontSave;
  67. }
  68. return (!rgbFallback && !monochrome) ? m_MaterialYUV : m_MaterialRGB;
  69. }
  70. }
  71. protected void OnDisable() {
  72. if ( m_MaterialRGB )
  73. DestroyImmediate( m_MaterialRGB );
  74. if ( m_MaterialYUV )
  75. DestroyImmediate( m_MaterialYUV );
  76. }
  77. private void SanitizeParameters()
  78. {
  79. grainIntensityMin = Mathf.Clamp( grainIntensityMin, 0.0f, 5.0f );
  80. grainIntensityMax = Mathf.Clamp( grainIntensityMax, 0.0f, 5.0f );
  81. scratchIntensityMin = Mathf.Clamp( scratchIntensityMin, 0.0f, 5.0f );
  82. scratchIntensityMax = Mathf.Clamp( scratchIntensityMax, 0.0f, 5.0f );
  83. scratchFPS = Mathf.Clamp( scratchFPS, 1, 30 );
  84. scratchJitter = Mathf.Clamp( scratchJitter, 0.0f, 1.0f );
  85. grainSize = Mathf.Clamp( grainSize, 0.1f, 50.0f );
  86. }
  87. // Called by the camera to apply the image effect
  88. void OnRenderImage (RenderTexture source, RenderTexture destination)
  89. {
  90. SanitizeParameters();
  91. if ( scratchTimeLeft <= 0.0f )
  92. {
  93. scratchTimeLeft = Random.value * 2 / scratchFPS; // we have sanitized it earlier, won't be zero
  94. scratchX = Random.value;
  95. scratchY = Random.value;
  96. }
  97. scratchTimeLeft -= Time.deltaTime;
  98. Material mat = material;
  99. mat.SetTexture("_GrainTex", grainTexture);
  100. mat.SetTexture("_ScratchTex", scratchTexture);
  101. float grainScale = 1.0f / grainSize; // we have sanitized it earlier, won't be zero
  102. mat.SetVector("_GrainOffsetScale", new Vector4(
  103. Random.value,
  104. Random.value,
  105. (float)Screen.width / (float)grainTexture.width * grainScale,
  106. (float)Screen.height / (float)grainTexture.height * grainScale
  107. ));
  108. mat.SetVector("_ScratchOffsetScale", new Vector4(
  109. scratchX + Random.value*scratchJitter,
  110. scratchY + Random.value*scratchJitter,
  111. (float)Screen.width / (float) scratchTexture.width,
  112. (float)Screen.height / (float) scratchTexture.height
  113. ));
  114. mat.SetVector("_Intensity", new Vector4(
  115. Random.Range(grainIntensityMin, grainIntensityMax),
  116. Random.Range(scratchIntensityMin, scratchIntensityMax),
  117. 0, 0 ));
  118. Graphics.Blit (source, destination, mat);
  119. }
  120. }
  121. }