Tanoda
LightShafts.Utils.cs
Go to the documentation of this file.
1using UnityEngine;
2using System.Collections;
3
5{
6 Dynamic = 0,
7 Static = 1
8}
9
10public partial class LightShafts : MonoBehaviour
11{
12 public bool directional {get{return m_LightType == LightType.Directional;}}
13 public bool spot {get{return m_LightType == LightType.Spot;}}
14
15 Bounds GetBoundsLocal()
16 {
17 if (directional)
18 return new Bounds(new Vector3(0, 0, m_Size.z*0.5f), m_Size);
19
20 Light l = m_Light;
21 Vector3 offset = new Vector3(0, 0, l.range * (m_SpotFar + m_SpotNear) * 0.5f);
22 float height = (m_SpotFar - m_SpotNear) * l.range;
23 float baseSize = Mathf.Tan(l.spotAngle * Mathf.Deg2Rad * 0.5f) * m_SpotFar * l.range * 2.0f;
24 return new Bounds(offset, new Vector3(baseSize, baseSize, height));
25 }
26
27 Matrix4x4 GetBoundsMatrix()
28 {
29 Bounds bounds = GetBoundsLocal();
30 Transform t = transform;
31 return Matrix4x4.TRS(t.position + t.forward * bounds.center.z, t.rotation, bounds.size);
32 }
33
34 float GetFrustumApex()
35 {
36 // Assuming the frustum is inscribed in a unit cube centered at 0
37 return - m_SpotNear/(m_SpotFar - m_SpotNear) - 0.5f;
38 }
39
40 void OnDrawGizmosSelected()
41 {
43
44 Gizmos.color = Color.yellow;
45 if (directional)
46 {
47 Gizmos.matrix = GetBoundsMatrix();
48 Gizmos.DrawWireCube(Vector3.zero, Vector3.one);
49 }
50 else if (spot)
51 {
52 Transform t = transform;
53 Light l = m_Light;
54 Gizmos.matrix = Matrix4x4.TRS(t.position, t.rotation, Vector3.one);
55 Gizmos.DrawFrustum(t.position, l.spotAngle, l.range * m_SpotFar, l.range * m_SpotNear, 1);
56 }
57 }
58
59 void RenderQuadSections(Vector4 lightPos)
60 {
61 for (int i = 0; i < 4; i++)
62 {
63 // Skip one or two quarters, if the light is off screen
64 if (i == 0 && lightPos.y > 1 ||
65 i == 1 && lightPos.x > 1 ||
66 i == 2 && lightPos.y < -1 ||
67 i == 3 && lightPos.x < -1)
68 continue;
69
70 // index denotes which quarter of the screen to take up,
71 // so start at -1, -0.5, 0 or 0.5
72 float top = i / 2.0f - 1.0f;
73 float bottom = top + 0.5f;
74 GL.Begin(GL.QUADS);
75 GL.Vertex3(-1, top, 0);
76 GL.Vertex3(1, top, 0);
77 GL.Vertex3(1, bottom, 0);
78 GL.Vertex3(-1, bottom, 0);
79 GL.End();
80 }
81 }
82
83 void RenderQuad()
84 {
85 GL.Begin(GL.QUADS);
86 GL.TexCoord2( 0, 0);
87 GL.Vertex3 (-1,-1, 0);
88 GL.TexCoord2( 0, 1);
89 GL.Vertex3 (-1, 1, 0);
90 GL.TexCoord2( 1, 1);
91 GL.Vertex3 ( 1, 1, 0);
92 GL.TexCoord2( 1, 0);
93 GL.Vertex3 ( 1,-1, 0);
94 GL.End();
95 }
96
97 void RenderSpotFrustum()
98 {
99 Graphics.DrawMeshNow(m_SpotMesh, transform.position, transform.rotation);
100 }
101
102 Vector4 GetLightViewportPos()
103 {
104 Vector3 lightPos = transform.position;
105 if (directional)
106 lightPos = m_CurrentCamera.transform.position + transform.forward;
107
108 Vector3 lightViewportPos3 = m_CurrentCamera.WorldToViewportPoint(lightPos);
109 return new Vector4(lightViewportPos3.x*2.0f - 1.0f, lightViewportPos3.y*2.0f - 1.0f, 0, 0);
110 }
111
112 bool IsVisible()
113 {
114 // Intersect against spot light's OBB (or light frustum's OBB), so AABB in it's space
115 Matrix4x4 lightToCameraProjection = m_CurrentCamera.projectionMatrix * m_CurrentCamera.worldToCameraMatrix * transform.localToWorldMatrix;
116 return GeometryUtility.TestPlanesAABB(GeometryUtility.CalculateFrustumPlanes(lightToCameraProjection), GetBoundsLocal());
117 }
118
119 bool IntersectsNearPlane()
120 {
121 // Lazy for now:
122 // Just check if any vertex is behind the near plane.
123 // TODO: same for directional
124 Vector3[] vertices = m_SpotMesh.vertices;
125 float nearPlaneFudged = m_CurrentCamera.nearClipPlane - 0.001f;
126 Transform t = transform;
127 for (int i = 0; i < vertices.Length; i++)
128 {
129 float z = m_CurrentCamera.WorldToViewportPoint(t.TransformPoint(vertices[i])).z;
130 if (z < nearPlaneFudged)
131 return true;
132 }
133 return false;
134 }
135
136 void SetKeyword(bool firstOn, string firstKeyword, string secondKeyword)
137 {
138 Shader.EnableKeyword(firstOn ? firstKeyword : secondKeyword);
139 Shader.DisableKeyword(firstOn ? secondKeyword : firstKeyword);
140 }
141
142 public void SetShadowmapDirty()
143 {
144 m_ShadowmapDirty = true;
145 }
146
147 void GetFrustumRays(out Matrix4x4 frustumRays, out Vector3 cameraPosLocal)
148 {
149 float far = m_CurrentCamera.farClipPlane;
150 Vector3 cameraPos = m_CurrentCamera.transform.position;
151 Matrix4x4 m = GetBoundsMatrix().inverse;
152 Vector2[] uvs = new Vector2[] {new Vector2(0, 0), new Vector2(1, 0), new Vector2(1, 1), new Vector2(0, 1)};
153 frustumRays = new Matrix4x4();
154
155 for (int i = 0; i < 4; i++)
156 {
157 Vector3 ray = m_CurrentCamera.ViewportToWorldPoint(new Vector3(uvs[i].x, uvs[i].y, far)) - cameraPos;
158 ray = m.MultiplyVector(ray);
159 frustumRays.SetRow(i, ray);
160 }
161
162 cameraPosLocal = m.MultiplyPoint3x4(cameraPos);
163 }
164
165 void SetFrustumRays(Material material)
166 {
167 Matrix4x4 frustumRays;
168 Vector3 cameraPosLocal;
169 GetFrustumRays(out frustumRays, out cameraPosLocal);
170 material.SetVector("_CameraPosLocal", cameraPosLocal);
171 material.SetMatrix("_FrustumRays", frustumRays);
172 material.SetFloat("_FrustumApex", GetFrustumApex());
173 }
174
175 float GetDepthThresholdAdjusted()
176 {
177 return m_DepthThreshold/m_CurrentCamera.farClipPlane;
178 }
179
180 bool CheckCamera()
181 {
182 if (m_Cameras == null)
183 return false;
184
185 foreach (Camera cam in m_Cameras)
186 if (cam == m_CurrentCamera)
187 return true;
188
189 return false;
190 }
191
193 {
194 if (m_Cameras == null)
195 return;
196
197 foreach(Camera cam in m_Cameras)
198 if (cam)
199 cam.depthTextureMode |= DepthTextureMode.Depth;
200 }
201}
LightShaftsShadowmapMode
UnityEngine.Color Color
Definition: TestScript.cs:32
void UpdateCameraDepthMode()
void SetShadowmapDirty()