6 public class Water : MonoBehaviour
38 if( !enabled || !GetComponent<Renderer>() || !GetComponent<Renderer>().sharedMaterial || !GetComponent<Renderer>().enabled )
41 Camera cam = Camera.current;
56 Camera reflectionCamera, refractionCamera;
60 Vector3 pos = transform.position;
61 Vector3 normal = transform.up;
64 int oldPixelLightCount = QualitySettings.pixelLightCount;
65 if( m_DisablePixelLights )
66 QualitySettings.pixelLightCount = 0;
76 Vector4 reflectionPlane =
new Vector4 (normal.x, normal.y, normal.z, d);
78 Matrix4x4 reflection = Matrix4x4.zero;
80 Vector3 oldpos = cam.transform.position;
81 Vector3 newpos = reflection.MultiplyPoint( oldpos );
82 reflectionCamera.worldToCameraMatrix = cam.worldToCameraMatrix * reflection;
87 Matrix4x4 projection = cam.projectionMatrix;
89 reflectionCamera.projectionMatrix = projection;
91 reflectionCamera.cullingMask = ~(1<<4) & m_ReflectLayers.value;
92 reflectionCamera.targetTexture = m_ReflectionTexture;
93 GL.invertCulling =
true;
94 reflectionCamera.transform.position = newpos;
95 Vector3 euler = cam.transform.eulerAngles;
96 reflectionCamera.transform.eulerAngles =
new Vector3(0, euler.y, euler.z);
97 reflectionCamera.Render();
98 reflectionCamera.transform.position = oldpos;
99 GL.invertCulling =
false;
100 GetComponent<Renderer>().sharedMaterial.SetTexture(
"_ReflectionTex", m_ReflectionTexture );
106 refractionCamera.worldToCameraMatrix = cam.worldToCameraMatrix;
110 Vector4 clipPlane =
CameraSpacePlane( refractionCamera, pos, normal, -1.0f );
111 Matrix4x4 projection = cam.projectionMatrix;
113 refractionCamera.projectionMatrix = projection;
115 refractionCamera.cullingMask = ~(1<<4) & m_RefractLayers.value;
116 refractionCamera.targetTexture = m_RefractionTexture;
117 refractionCamera.transform.position = cam.transform.position;
118 refractionCamera.transform.rotation = cam.transform.rotation;
119 refractionCamera.Render();
120 GetComponent<Renderer>().sharedMaterial.SetTexture(
"_RefractionTex", m_RefractionTexture );
124 if( m_DisablePixelLights )
125 QualitySettings.pixelLightCount = oldPixelLightCount;
131 Shader.EnableKeyword(
"WATER_SIMPLE" );
132 Shader.DisableKeyword(
"WATER_REFLECTIVE" );
133 Shader.DisableKeyword(
"WATER_REFRACTIVE" );
136 Shader.DisableKeyword(
"WATER_SIMPLE" );
137 Shader.EnableKeyword(
"WATER_REFLECTIVE" );
138 Shader.DisableKeyword(
"WATER_REFRACTIVE" );
141 Shader.DisableKeyword(
"WATER_SIMPLE" );
142 Shader.DisableKeyword(
"WATER_REFLECTIVE" );
143 Shader.EnableKeyword(
"WATER_REFRACTIVE" );
147 s_InsideWater =
false;
154 if( m_ReflectionTexture ) {
155 DestroyImmediate( m_ReflectionTexture );
156 m_ReflectionTexture = null;
158 if( m_RefractionTexture ) {
159 DestroyImmediate( m_RefractionTexture );
160 m_RefractionTexture = null;
162 foreach( DictionaryEntry kvp
in m_ReflectionCameras )
163 DestroyImmediate( ((Camera)kvp.Value).gameObject );
164 m_ReflectionCameras.Clear();
165 foreach( DictionaryEntry kvp
in m_RefractionCameras )
166 DestroyImmediate( ((Camera)kvp.Value).gameObject );
167 m_RefractionCameras.Clear();
175 if( !GetComponent<Renderer>() )
177 Material mat = GetComponent<Renderer>().sharedMaterial;
181 Vector4 waveSpeed = mat.GetVector(
"WaveSpeed" );
182 float waveScale = mat.GetFloat(
"_WaveScale" );
183 float t = Time.time / 40.0f;
185 Vector3 offset =
new Vector3( t * waveSpeed.x, t * waveSpeed.y, 0 );
186 Vector3 scale =
new Vector3( 1.0f/waveScale, 1.0f/waveScale, 1 );
187 Matrix4x4 scrollMatrix = Matrix4x4.TRS( offset, Quaternion.identity, scale );
188 mat.SetMatrix(
"_WaveMatrix", scrollMatrix );
190 offset =
new Vector3( t * waveSpeed.z, t * waveSpeed.w, 0 );
191 scrollMatrix = Matrix4x4.TRS( offset, Quaternion.identity, scale * 0.45f );
192 mat.SetMatrix(
"_WaveMatrix2", scrollMatrix );
200 dest.clearFlags = src.clearFlags;
201 dest.backgroundColor = src.backgroundColor;
202 if( src.clearFlags == CameraClearFlags.Skybox )
204 Skybox sky = src.GetComponent(typeof(Skybox)) as Skybox;
205 Skybox mysky = dest.GetComponent(typeof(Skybox)) as Skybox;
206 if( !sky || !sky.material )
208 mysky.enabled =
false;
212 mysky.enabled =
true;
213 mysky.material = sky.material;
219 dest.farClipPlane = src.farClipPlane;
220 dest.nearClipPlane = src.nearClipPlane;
221 dest.orthographic = src.orthographic;
222 dest.fieldOfView = src.fieldOfView;
223 dest.aspect = src.aspect;
224 dest.orthographicSize = src.orthographicSize;
228 private void CreateWaterObjects( Camera currentCamera, out Camera reflectionCamera, out Camera refractionCamera )
232 reflectionCamera = null;
233 refractionCamera = null;
238 if( !m_ReflectionTexture || m_OldReflectionTextureSize != m_TextureSize )
240 if( m_ReflectionTexture )
241 DestroyImmediate( m_ReflectionTexture );
242 m_ReflectionTexture =
new RenderTexture( m_TextureSize, m_TextureSize, 16 );
243 m_ReflectionTexture.name =
"__WaterReflection" + GetInstanceID();
244 m_ReflectionTexture.isPowerOfTwo =
true;
245 m_ReflectionTexture.hideFlags = HideFlags.DontSave;
250 reflectionCamera = m_ReflectionCameras[currentCamera] as Camera;
251 if( !reflectionCamera )
253 GameObject go =
new GameObject(
"Water Refl Camera id" + GetInstanceID() +
" for " + currentCamera.GetInstanceID(), typeof(Camera), typeof(Skybox) );
254 reflectionCamera = go.GetComponent<Camera>();
255 reflectionCamera.enabled =
false;
256 reflectionCamera.transform.position = transform.position;
257 reflectionCamera.transform.rotation = transform.rotation;
258 reflectionCamera.gameObject.AddComponent<FlareLayer>();
259 go.hideFlags = HideFlags.HideAndDontSave;
260 m_ReflectionCameras[currentCamera] = reflectionCamera;
267 if( !m_RefractionTexture || m_OldRefractionTextureSize != m_TextureSize )
269 if( m_RefractionTexture )
270 DestroyImmediate( m_RefractionTexture );
271 m_RefractionTexture =
new RenderTexture( m_TextureSize, m_TextureSize, 16 );
272 m_RefractionTexture.name =
"__WaterRefraction" + GetInstanceID();
273 m_RefractionTexture.isPowerOfTwo =
true;
274 m_RefractionTexture.hideFlags = HideFlags.DontSave;
279 refractionCamera = m_RefractionCameras[currentCamera] as Camera;
280 if( !refractionCamera )
282 GameObject go =
new GameObject(
"Water Refr Camera id" + GetInstanceID() +
" for " + currentCamera.GetInstanceID(), typeof(Camera), typeof(Skybox) );
283 refractionCamera = go.GetComponent<Camera>();
284 refractionCamera.enabled =
false;
285 refractionCamera.transform.position = transform.position;
286 refractionCamera.transform.rotation = transform.rotation;
287 refractionCamera.gameObject.AddComponent<FlareLayer>();
288 go.hideFlags = HideFlags.HideAndDontSave;
289 m_RefractionCameras[currentCamera] = refractionCamera;
296 if( m_HardwareWaterSupport < m_WaterMode )
304 if( !SystemInfo.supportsRenderTextures || !GetComponent<Renderer>() )
307 Material mat = GetComponent<Renderer>().sharedMaterial;
311 string mode = mat.GetTag(
"WATERMODE",
false);
312 if( mode ==
"Refractive" )
314 if( mode ==
"Reflective" )
321 private static float sgn(
float a)
323 if (a > 0.0f)
return 1.0f;
324 if (a < 0.0f)
return -1.0f;
332 Matrix4x4 m = cam.worldToCameraMatrix;
333 Vector3 cpos = m.MultiplyPoint( offsetPos );
334 Vector3 cnormal = m.MultiplyVector( normal ).normalized * sideSign;
335 return new Vector4( cnormal.x, cnormal.y, cnormal.z, -Vector3.Dot(cpos,cnormal) );
343 Vector4 q = projection.inverse *
new Vector4(
349 Vector4 c = clipPlane * (2.0F / (Vector4.Dot (clipPlane, q)));
351 projection[2] = c.x - projection[3];
352 projection[6] = c.y - projection[7];
353 projection[10] = c.z - projection[11];
354 projection[14] = c.w - projection[15];
360 reflectionMat.m00 = (1F - 2F*plane[0]*plane[0]);
361 reflectionMat.m01 = ( - 2F*plane[0]*plane[1]);
362 reflectionMat.m02 = ( - 2F*plane[0]*plane[2]);
363 reflectionMat.m03 = ( - 2F*plane[3]*plane[0]);
365 reflectionMat.m10 = ( - 2F*plane[1]*plane[0]);
366 reflectionMat.m11 = (1F - 2F*plane[1]*plane[1]);
367 reflectionMat.m12 = ( - 2F*plane[1]*plane[2]);
368 reflectionMat.m13 = ( - 2F*plane[3]*plane[1]);
370 reflectionMat.m20 = ( - 2F*plane[2]*plane[0]);
371 reflectionMat.m21 = ( - 2F*plane[2]*plane[1]);
372 reflectionMat.m22 = (1F - 2F*plane[2]*plane[2]);
373 reflectionMat.m23 = ( - 2F*plane[3]*plane[2]);
375 reflectionMat.m30 = 0F;
376 reflectionMat.m31 = 0F;
377 reflectionMat.m32 = 0F;
378 reflectionMat.m33 = 1F;
static void CalculateObliqueMatrix(ref Matrix4x4 projection, Vector4 clipPlane)
void CreateWaterObjects(Camera currentCamera, out Camera reflectionCamera, out Camera refractionCamera)
LayerMask m_RefractLayers
Vector4 CameraSpacePlane(Camera cam, Vector3 pos, Vector3 normal, float sideSign)
static bool s_InsideWater
WaterMode m_HardwareWaterSupport
LayerMask m_ReflectLayers
void UpdateCameraModes(Camera src, Camera dest)
static void CalculateReflectionMatrix(ref Matrix4x4 reflectionMat, Vector4 plane)
Hashtable m_ReflectionCameras
bool m_DisablePixelLights
WaterMode FindHardwareWaterSupport()
RenderTexture m_ReflectionTexture
int m_OldRefractionTextureSize
static float sgn(float a)
Hashtable m_RefractionCameras
RenderTexture m_RefractionTexture
int m_OldReflectionTextureSize
void OnWillRenderObject()