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