1 using System;
2 using
UnityEngine;
3
4 namespace
UnityStandardAssets.ImageEffects
5 {
6     
[ExecuteInEditMode]
7     
[RequireComponent (typeof(Camera))]
8     
[AddComponentMenu ("Image Effects/Rendering/Sun Shafts")]
9     
public class SunShafts : PostEffectsBase
10     {
11         
public enum SunShaftsResolution
12         {
13             Low =
0,
14             Normal =
1,
15             High =
2,
16         }
17
18         
public enum ShaftsScreenBlendMode
19         {
20             Screen =
0,
21             Add =
1,
22         }
23
24
25         
public SunShaftsResolution resolution = SunShaftsResolution.Normal;
26         
public ShaftsScreenBlendMode screenBlendMode = ShaftsScreenBlendMode.Screen;
27
28         
public Transform sunTransform;
29         
public int radialBlurIterations = 2;
30         
public Color sunColor = Color.white;
31         
public Color sunThreshold = new Color(0.87f,0.74f,0.65f);
32         
public float sunShaftBlurRadius = 2.5f;
33         
public float sunShaftIntensity = 1.15f;
34
35         
public float maxRadius = 0.75f;
36
37         
public bool useDepthTexture = true;
38
39         
public Shader sunShaftsShader;
40         
private Material sunShaftsMaterial;
41
42         
public Shader simpleClearShader;
43         
private Material simpleClearMaterial;
44
45
46         
public override bool CheckResources () {
47             CheckSupport (useDepthTexture);
48
49             sunShaftsMaterial = CheckShaderAndCreateMaterial (sunShaftsShader, sunShaftsMaterial);
50             simpleClearMaterial = CheckShaderAndCreateMaterial (simpleClearShader, simpleClearMaterial);
51
52             
if (!isSupported)
53                 ReportAutoDisable ();
54             
return isSupported;
55         }
56
57         
void OnRenderImage (RenderTexture source, RenderTexture destination) {
58             
if (CheckResources()==false) {
59                 Graphics.Blit (source, destination);
60                 
return;
61             }
62
63             
// we actually need to check this every frame
64             
if (useDepthTexture)
65                 GetComponent<Camera>().depthTextureMode |= DepthTextureMode.Depth;
66
67             
int divider = 4;
68             
if (resolution == SunShaftsResolution.Normal)
69                 divider =
2;
70             
else if (resolution == SunShaftsResolution.High)
71                 divider =
1;
72
73             Vector3 v = Vector3.one *
0.5f;
74             
if (sunTransform)
75                 v = GetComponent<Camera>().WorldToViewportPoint (sunTransform.position);
76             
else
77                 v =
new Vector3(0.5f, 0.5f, 0.0f);
78
79             
int rtW = source.width / divider;
80             
int rtH = source.height / divider;
81
82             RenderTexture lrColorB;
83             RenderTexture lrDepthBuffer = RenderTexture.GetTemporary (rtW, rtH,
0);
84
85             
// mask out everything except the skybox
86             
// we have 2 methods, one of which requires depth buffer support, the other one is just comparing images
87
88             sunShaftsMaterial.SetVector (
"_BlurRadius4", new Vector4 (1.0f, 1.0f, 0.0f, 0.0f) * sunShaftBlurRadius );
89             sunShaftsMaterial.SetVector (
"_SunPosition", new Vector4 (v.x, v.y, v.z, maxRadius));
90             sunShaftsMaterial.SetVector (
"_SunThreshold", sunThreshold);
91
92             
if (!useDepthTexture) {
93                 
var format= GetComponent<Camera>().hdr ? RenderTextureFormat.DefaultHDR: RenderTextureFormat.Default;
94                 RenderTexture tmpBuffer = RenderTexture.GetTemporary (source.width, source.height,
0, format);
95                 RenderTexture.active = tmpBuffer;
96                 GL.ClearWithSkybox (
false, GetComponent<Camera>());
97
98                 sunShaftsMaterial.SetTexture (
"_Skybox", tmpBuffer);
99                 Graphics.Blit (source, lrDepthBuffer, sunShaftsMaterial,
3);
100                 RenderTexture.ReleaseTemporary (tmpBuffer);
101             }
102             
else {
103                 Graphics.Blit (source, lrDepthBuffer, sunShaftsMaterial,
2);
104             }
105
106             
// paint a small black small border to get rid of clamping problems
107             DrawBorder (lrDepthBuffer, simpleClearMaterial);
108
109             
// radial blur:
110
111             radialBlurIterations = Mathf.Clamp (radialBlurIterations,
1, 4);
112
113             
float ofs = sunShaftBlurRadius * (1.0f / 768.0f);
114
115             sunShaftsMaterial.SetVector (
"_BlurRadius4", new Vector4 (ofs, ofs, 0.0f, 0.0f));
116             sunShaftsMaterial.SetVector (
"_SunPosition", new Vector4 (v.x, v.y, v.z, maxRadius));
117
118             
for (int it2 = 0; it2 < radialBlurIterations; it2++ ) {
119                 
// each iteration takes 2 * 6 samples
120                 
// we update _BlurRadius each time to cheaply get a very smooth look
121
122                 lrColorB = RenderTexture.GetTemporary (rtW, rtH,
0);
123                 Graphics.Blit (lrDepthBuffer, lrColorB, sunShaftsMaterial,
1);
124                 RenderTexture.ReleaseTemporary (lrDepthBuffer);
125                 ofs = sunShaftBlurRadius * (((it2 *
2.0f + 1.0f) * 6.0f)) / 768.0f;
126                 sunShaftsMaterial.SetVector (
"_BlurRadius4", new Vector4 (ofs, ofs, 0.0f, 0.0f) );
127
128                 lrDepthBuffer = RenderTexture.GetTemporary (rtW, rtH,
0);
129                 Graphics.Blit (lrColorB, lrDepthBuffer, sunShaftsMaterial,
1);
130                 RenderTexture.ReleaseTemporary (lrColorB);
131                 ofs = sunShaftBlurRadius * (((it2 *
2.0f + 2.0f) * 6.0f)) / 768.0f;
132                 sunShaftsMaterial.SetVector (
"_BlurRadius4", new Vector4 (ofs, ofs, 0.0f, 0.0f) );
133             }
134
135             
// put together:
136
137             
if (v.z >= 0.0f)
138                 sunShaftsMaterial.SetVector (
"_SunColor", new Vector4 (sunColor.r, sunColor.g, sunColor.b, sunColor.a) * sunShaftIntensity);
139             
else
140                 sunShaftsMaterial.SetVector (
"_SunColor", Vector4.zero); // no backprojection !
141             sunShaftsMaterial.SetTexture (
"_ColorBuffer", lrDepthBuffer);
142             Graphics.Blit (source, destination, sunShaftsMaterial, (screenBlendMode == ShaftsScreenBlendMode.Screen) ?
0 : 4);
143
144             RenderTexture.ReleaseTemporary (lrDepthBuffer);
145         }
146     }
147 }