ScreenSpaceAmbientObscurance.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. using System;
  2. using UnityEngine;
  3. namespace UnityStandardAssets.ImageEffects
  4. {
  5. [ ExecuteInEditMode]
  6. [RequireComponent (typeof(Camera))]
  7. [AddComponentMenu ("Image Effects/Rendering/Screen Space Ambient Obscurance")]
  8. class ScreenSpaceAmbientObscurance : PostEffectsBase {
  9. [Range (0,3)]
  10. public float intensity = 0.5f;
  11. [Range (0.1f,3)]
  12. public float radius = 0.2f;
  13. [Range (0,3)]
  14. public int blurIterations = 1;
  15. [Range (0,5)]
  16. public float blurFilterDistance = 1.25f;
  17. [Range (0,1)]
  18. public int downsample = 0;
  19. public Texture2D rand = null;
  20. public Shader aoShader= null;
  21. private Material aoMaterial = null;
  22. public override bool CheckResources () {
  23. CheckSupport (true);
  24. aoMaterial = CheckShaderAndCreateMaterial (aoShader, aoMaterial);
  25. if (!isSupported)
  26. ReportAutoDisable ();
  27. return isSupported;
  28. }
  29. void OnDisable () {
  30. if (aoMaterial)
  31. DestroyImmediate (aoMaterial);
  32. aoMaterial = null;
  33. }
  34. [ImageEffectOpaque]
  35. void OnRenderImage (RenderTexture source, RenderTexture destination) {
  36. if (CheckResources () == false) {
  37. Graphics.Blit (source, destination);
  38. return;
  39. }
  40. Matrix4x4 P = GetComponent<Camera>().projectionMatrix;
  41. var invP= P.inverse;
  42. Vector4 projInfo = new Vector4
  43. ((-2.0f / (Screen.width * P[0])),
  44. (-2.0f / (Screen.height * P[5])),
  45. ((1.0f - P[2]) / P[0]),
  46. ((1.0f + P[6]) / P[5]));
  47. aoMaterial.SetVector ("_ProjInfo", projInfo); // used for unprojection
  48. aoMaterial.SetMatrix ("_ProjectionInv", invP); // only used for reference
  49. aoMaterial.SetTexture ("_Rand", rand); // not needed for DX11 :)
  50. aoMaterial.SetFloat ("_Radius", radius);
  51. aoMaterial.SetFloat ("_Radius2", radius*radius);
  52. aoMaterial.SetFloat ("_Intensity", intensity);
  53. aoMaterial.SetFloat ("_BlurFilterDistance", blurFilterDistance);
  54. int rtW = source.width;
  55. int rtH = source.height;
  56. RenderTexture tmpRt = RenderTexture.GetTemporary (rtW>>downsample, rtH>>downsample);
  57. RenderTexture tmpRt2;
  58. Graphics.Blit (source, tmpRt, aoMaterial, 0);
  59. if (downsample > 0) {
  60. tmpRt2 = RenderTexture.GetTemporary (rtW, rtH);
  61. Graphics.Blit(tmpRt, tmpRt2, aoMaterial, 4);
  62. RenderTexture.ReleaseTemporary (tmpRt);
  63. tmpRt = tmpRt2;
  64. // @NOTE: it's probably worth a shot to blur in low resolution
  65. // instead with a bilat-upsample afterwards ...
  66. }
  67. for (int i = 0; i < blurIterations; i++) {
  68. aoMaterial.SetVector("_Axis", new Vector2(1.0f,0.0f));
  69. tmpRt2 = RenderTexture.GetTemporary (rtW, rtH);
  70. Graphics.Blit (tmpRt, tmpRt2, aoMaterial, 1);
  71. RenderTexture.ReleaseTemporary (tmpRt);
  72. aoMaterial.SetVector("_Axis", new Vector2(0.0f,1.0f));
  73. tmpRt = RenderTexture.GetTemporary (rtW, rtH);
  74. Graphics.Blit (tmpRt2, tmpRt, aoMaterial, 1);
  75. RenderTexture.ReleaseTemporary (tmpRt2);
  76. }
  77. aoMaterial.SetTexture ("_AOTex", tmpRt);
  78. Graphics.Blit (source, destination, aoMaterial, 2);
  79. RenderTexture.ReleaseTemporary (tmpRt);
  80. }
  81. }
  82. }