using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.XR; namespace LuxWater { [RequireComponent(typeof(Camera))] public class LuxWater_UnderWaterRendering : MonoBehaviour { public static LuxWater_UnderWaterRendering instance; [Space(6f)] [LuxWater_HelpBtn("h.d0q6uguuxpy")] public Transform Sun; [Space(4f)] public bool FindSunOnEnable; public string SunGoName = ""; public string SunTagName = ""; private Light SunLight; [Space(2f)] [Header("Deep Water Lighting")] [Space(4f)] public bool EnableDeepwaterLighting; public float DefaultWaterSurfacePosition; public float DirectionalLightingFadeRange = 64f; public float FogLightingFadeRange = 64f; [Space(2f)] [Header("Advanced Deferred Fog")] [Space(4f)] public bool EnableAdvancedDeferredFog; public float FogDepthShift = 1f; public float FogEdgeBlending = 0.125f; [NonSerialized] [Space(8f)] public int activeWaterVolume = -1; [NonSerialized] public List activeWaterVolumeCameras = new List(); [NonSerialized] public float activeGridSize; [NonSerialized] public float WaterSurfacePos; [NonSerialized] [Space(8f)] public List RegisteredWaterVolumesIDs = new List(); [NonSerialized] public List RegisteredWaterVolumes = new List(); private List WaterMeshes = new List(); private List WaterTransforms = new List(); private List WaterMaterials = new List(); private List WaterIsOnScreen = new List(); private List WaterUsesSlidingVolume = new List(); private RenderTexture UnderWaterMask; [Space(2f)] [Header("Managed transparent Materials")] [Space(4f)] public List m_aboveWatersurface = new List(); public List m_belowWatersurface = new List(); [Space(2f)] [Header("Optimize")] [Space(4f)] public ShaderVariantCollection PrewarmedShaders; public int ListCapacity = 10; [Space(2f)] [Header("Debug")] [Space(4f)] public bool enableDebug; [Space(8f)] private Material mat; private Material blurMaterial; private Material blitMaterial; private Camera cam; private bool UnderwaterIsSetUp; private static CommandBuffer cb_Mask; private CameraEvent cameraEvent = CameraEvent.AfterSkybox; private Transform camTransform; private Matrix4x4 frustumCornersArray = Matrix4x4.identity; private Matrix4x4 frustumCornersArray2nd = Matrix4x4.identity; private SphericalHarmonicsL2 ambientProbe; private Vector3[] directions = new Vector3[1] { new Vector3(0f, 1f, 0f) }; private Color[] AmbientLightingSamples = new Color[1]; private bool DoUnderWaterRendering; private Matrix4x4 camProj; private Vector3[] frustumCorners = new Vector3[4]; private float Projection; private bool islinear; private Matrix4x4 WatervolumeMatrix; private static readonly int UnderWaterMaskPID = Shader.PropertyToID("_UnderWaterMask"); private static readonly int Lux_FrustumCornersWSPID = Shader.PropertyToID("_Lux_FrustumCornersWS"); private static readonly int Lux_FrustumCornersWS2ndPID = Shader.PropertyToID("_Lux_FrustumCornersWS2ndEye"); private static readonly int Lux_CameraWSPID = Shader.PropertyToID("_Lux_CameraWS"); private static readonly int GerstnerEnabledPID = Shader.PropertyToID("_GerstnerEnabled"); private static readonly int LuxWaterMask_GerstnerVertexIntensityPID = Shader.PropertyToID("_LuxWaterMask_GerstnerVertexIntensity"); private static readonly int GerstnerVertexIntensityPID = Shader.PropertyToID("_GerstnerVertexIntensity"); private static readonly int LuxWaterMask_GAmplitudePID = Shader.PropertyToID("_LuxWaterMask_GAmplitude"); private static readonly int GAmplitudePID = Shader.PropertyToID("_GAmplitude"); private static readonly int LuxWaterMask_GFinalFrequencyPID = Shader.PropertyToID("_LuxWaterMask_GFinalFrequency"); private static readonly int GFinalFrequencyPID = Shader.PropertyToID("_GFinalFrequency"); private static readonly int LuxWaterMask_GSteepnessPID = Shader.PropertyToID("_LuxWaterMask_GSteepness"); private static readonly int GSteepnessPID = Shader.PropertyToID("_GSteepness"); private static readonly int LuxWaterMask_GFinalSpeedPID = Shader.PropertyToID("_LuxWaterMask_GFinalSpeed"); private static readonly int GFinalSpeedPID = Shader.PropertyToID("_GFinalSpeed"); private static readonly int LuxWaterMask_GDirectionABPID = Shader.PropertyToID("_LuxWaterMask_GDirectionAB"); private static readonly int GDirectionABPID = Shader.PropertyToID("_GDirectionAB"); private static readonly int LuxWaterMask_GDirectionCDPID = Shader.PropertyToID("_LuxWaterMask_GDirectionCD"); private static readonly int GDirectionCDPID = Shader.PropertyToID("_GDirectionCD"); private static readonly int LuxWaterMask_GerstnerSecondaryWaves = Shader.PropertyToID("_LuxWaterMask_GerstnerSecondaryWaves"); private static readonly int GerstnerSecondaryWaves = Shader.PropertyToID("_GerstnerSecondaryWaves"); private static readonly int Lux_UnderWaterAmbientSkyLightPID = Shader.PropertyToID("_Lux_UnderWaterAmbientSkyLight"); private static readonly int Lux_UnderWaterSunColorPID = Shader.PropertyToID("_Lux_UnderWaterSunColor"); private static readonly int Lux_UnderWaterSunDirPID = Shader.PropertyToID("_Lux_UnderWaterSunDir"); private static readonly int Lux_UnderWaterSunDirViewSpacePID = Shader.PropertyToID("_Lux_UnderWaterSunDirViewSpace"); private static readonly int Lux_EdgeLengthPID = Shader.PropertyToID("_LuxWater_EdgeLength"); private static readonly int Lux_ExtrusionPID = Shader.PropertyToID("_LuxWater_Extrusion"); private static readonly int LuxMask_ExtrusionPID = Shader.PropertyToID("_LuxWaterMask_Extrusion"); private static readonly int Lux_MaxDirLightDepthPID = Shader.PropertyToID("_MaxDirLightDepth"); private static readonly int Lux_MaxFogLightDepthPID = Shader.PropertyToID("_MaxFogLightDepth"); private static readonly int Lux_CausticsEnabledPID = Shader.PropertyToID("_CausticsEnabled"); private static readonly int Lux_CausticModePID = Shader.PropertyToID("_CausticMode"); private static readonly int Lux_UnderWaterFogColorPID = Shader.PropertyToID("_Lux_UnderWaterFogColor"); private static readonly int Lux_UnderWaterFogDensityPID = Shader.PropertyToID("_Lux_UnderWaterFogDensity"); private static readonly int Lux_UnderWaterFogAbsorptionCancellationPID = Shader.PropertyToID("_Lux_UnderWaterFogAbsorptionCancellation"); private static readonly int Lux_UnderWaterAbsorptionHeightPID = Shader.PropertyToID("_Lux_UnderWaterAbsorptionHeight"); private static readonly int Lux_UnderWaterAbsorptionMaxHeightPID = Shader.PropertyToID("_Lux_UnderWaterAbsorptionMaxHeight"); private static readonly int Lux_UnderWaterAbsorptionDepthPID = Shader.PropertyToID("_Lux_UnderWaterAbsorptionDepth"); private static readonly int Lux_UnderWaterAbsorptionColorStrengthPID = Shader.PropertyToID("_Lux_UnderWaterAbsorptionColorStrength"); private static readonly int Lux_UnderWaterAbsorptionStrengthPID = Shader.PropertyToID("_Lux_UnderWaterAbsorptionStrength"); private static readonly int Lux_UnderWaterUnderwaterScatteringPowerPID = Shader.PropertyToID("_Lux_UnderWaterUnderwaterScatteringPower"); private static readonly int Lux_UnderWaterUnderwaterScatteringIntensityPID = Shader.PropertyToID("_Lux_UnderWaterUnderwaterScatteringIntensity"); private static readonly int Lux_UnderWaterUnderwaterScatteringColorPID = Shader.PropertyToID("_Lux_UnderWaterUnderwaterScatteringColor"); private static readonly int Lux_UnderWaterUnderwaterScatteringOcclusionPID = Shader.PropertyToID("_Lux_UnderwaterScatteringOcclusion"); private static readonly int Lux_UnderWaterCausticsPID = Shader.PropertyToID("_Lux_UnderWaterCaustics"); private static readonly int Lux_UnderWaterDeferredFogParams = Shader.PropertyToID("_LuxUnderWaterDeferredFogParams"); private static readonly int CausticTexPID = Shader.PropertyToID("_CausticTex"); private static readonly int Lux_UnderWaterCausticsTilingPID = Shader.PropertyToID("_Lux_UnderWaterCausticsTiling"); private static readonly int Lux_UnderWaterCausticsScalePID = Shader.PropertyToID("_Lux_UnderWaterCausticsScale"); private static readonly int Lux_UnderWaterCausticsSpeedPID = Shader.PropertyToID("_Lux_UnderWaterCausticsSpeed"); private static readonly int Lux_UnderWaterCausticsSelfDistortionPID = Shader.PropertyToID("_Lux_UnderWaterCausticsSelfDistortion"); private static readonly int Lux_UnderWaterFinalBumpSpeed01PID = Shader.PropertyToID("_Lux_UnderWaterFinalBumpSpeed01"); private static readonly int Lux_UnderWaterFogDepthAttenPID = Shader.PropertyToID("_Lux_UnderWaterFogDepthAtten"); private void OnEnable() { if (instance != null) { UnityEngine.Object.Destroy(this); } else { instance = this; } mat = new Material(Shader.Find("Hidden/Lux Water/WaterMask")); blurMaterial = new Material(Shader.Find("Hidden/Lux Water/BlurEffectConeTap")); blitMaterial = new Material(Shader.Find("Hidden/Lux Water/UnderWaterPost")); if (cam == null) { cam = GetComponent(); } cam.depthTextureMode |= DepthTextureMode.Depth; camTransform = cam.transform; cb_Mask = new CommandBuffer(); cb_Mask.name = "Lux Water: Underwater Mask"; cam.AddCommandBuffer(cameraEvent, cb_Mask); if (FindSunOnEnable) { if (SunGoName != "") { Sun = GameObject.Find(SunGoName).transform; } else if (SunTagName != "") { Sun = GameObject.FindWithTag(SunTagName).transform; } } if (SystemInfo.usesReversedZBuffer) { Projection = -1f; } else { Projection = 1f; } islinear = QualitySettings.desiredColorSpace == ColorSpace.Linear; if (PrewarmedShaders != null && !PrewarmedShaders.isWarmedUp) { PrewarmedShaders.WarmUp(); } if (Sun != null) { SunLight = Sun.GetComponent(); } RegisteredWaterVolumesIDs.Capacity = ListCapacity; RegisteredWaterVolumes.Capacity = ListCapacity; WaterMeshes.Capacity = ListCapacity; WaterTransforms.Capacity = ListCapacity; WaterMaterials.Capacity = ListCapacity; WaterIsOnScreen.Capacity = ListCapacity; WaterUsesSlidingVolume.Capacity = ListCapacity; activeWaterVolumeCameras.Capacity = 2; SetDeepwaterLighting(); SetDeferredFogParams(); } private void CleanUp() { instance = null; if (UnderWaterMask != null) { UnderWaterMask.Release(); UnityEngine.Object.Destroy(UnderWaterMask); } if ((bool)mat) { UnityEngine.Object.Destroy(mat); } if ((bool)blurMaterial) { UnityEngine.Object.Destroy(blurMaterial); } if ((bool)blitMaterial) { UnityEngine.Object.Destroy(blitMaterial); } Shader.DisableKeyword("LUXWATER_DEEPWATERLIGHTING"); Shader.DisableKeyword("LUXWATER_DEFERREDFOG"); cam.RemoveCommandBuffer(cameraEvent, cb_Mask); } private void OnDisable() { CleanUp(); } private void OnDestroy() { CleanUp(); } private void OnValidate() { SetDeepwaterLighting(); SetDeferredFogParams(); } public void SetDeferredFogParams() { if (EnableAdvancedDeferredFog) { Shader.EnableKeyword("LUXWATER_DEFERREDFOG"); Vector4 value = new Vector4(DoUnderWaterRendering ? 1 : 0, FogDepthShift, FogEdgeBlending, 0f); Shader.SetGlobalVector(Lux_UnderWaterDeferredFogParams, value); } else { Shader.DisableKeyword("LUXWATER_DEFERREDFOG"); } } public void SetDeepwaterLighting() { if (EnableDeepwaterLighting) { Shader.EnableKeyword("LUXWATER_DEEPWATERLIGHTING"); if (activeWaterVolume != -1) { Shader.SetGlobalFloat("_Lux_UnderWaterWaterSurfacePos", WaterSurfacePos); } else { Shader.SetGlobalFloat("_Lux_UnderWaterWaterSurfacePos", DefaultWaterSurfacePosition); } Shader.SetGlobalFloat("_Lux_UnderWaterDirLightingDepth", DirectionalLightingFadeRange); Shader.SetGlobalFloat("_Lux_UnderWaterFogLightingDepth", FogLightingFadeRange); } else { Shader.DisableKeyword("LUXWATER_DEEPWATERLIGHTING"); } } public void RegisterWaterVolume(LuxWater_WaterVolume item, int ID, bool visible, bool SlidingVolume) { RegisteredWaterVolumesIDs.Add(ID); RegisteredWaterVolumes.Add(item); WaterMeshes.Add(item.WaterVolumeMesh); WaterMaterials.Add(item.transform.GetComponent().sharedMaterial); WaterTransforms.Add(item.transform); WaterIsOnScreen.Add(visible); WaterUsesSlidingVolume.Add(SlidingVolume); int num = WaterMaterials.Count - 1; Shader.SetGlobalTexture(Lux_UnderWaterCausticsPID, WaterMaterials[num].GetTexture(CausticTexPID)); SetGerstnerWaves(num); } public void DeRegisterWaterVolume(LuxWater_WaterVolume item, int ID) { int num = RegisteredWaterVolumesIDs.IndexOf(ID); if (activeWaterVolume == num) { activeWaterVolume = -1; } RegisteredWaterVolumesIDs.RemoveAt(num); RegisteredWaterVolumes.RemoveAt(num); WaterMeshes.RemoveAt(num); WaterMaterials.RemoveAt(num); WaterTransforms.RemoveAt(num); WaterIsOnScreen.RemoveAt(num); WaterUsesSlidingVolume.RemoveAt(num); } public void SetWaterVisible(int ID) { int index = RegisteredWaterVolumesIDs.IndexOf(ID); WaterIsOnScreen[index] = true; } public void SetWaterInvisible(int ID) { int index = RegisteredWaterVolumesIDs.IndexOf(ID); WaterIsOnScreen[index] = false; } public void EnteredWaterVolume(LuxWater_WaterVolume item, int ID, Camera triggerCam, float GridSize) { DoUnderWaterRendering = true; int num = RegisteredWaterVolumesIDs.IndexOf(ID); if (num != activeWaterVolume) { activeWaterVolume = num; activeGridSize = GridSize; WaterSurfacePos = WaterTransforms[activeWaterVolume].position.y; for (int i = 0; i < m_aboveWatersurface.Count; i++) { m_aboveWatersurface[i].renderQueue = 2997; } for (int j = 0; j < m_belowWatersurface.Count; j++) { m_belowWatersurface[j].renderQueue = 3001; } } if (!activeWaterVolumeCameras.Contains(triggerCam)) { activeWaterVolumeCameras.Add(triggerCam); } } public void LeftWaterVolume(LuxWater_WaterVolume item, int ID, Camera triggerCam) { DoUnderWaterRendering = false; int num = RegisteredWaterVolumesIDs.IndexOf(ID); if (activeWaterVolume == num) { activeWaterVolume = -1; for (int i = 0; i < m_aboveWatersurface.Count; i++) { m_aboveWatersurface[i].renderQueue = 3000; } for (int j = 0; j < m_belowWatersurface.Count; j++) { m_belowWatersurface[j].renderQueue = 2997; } } if (activeWaterVolumeCameras.Contains(triggerCam)) { activeWaterVolumeCameras.Remove(triggerCam); } } private void OnPreRender() { SetDeferredFogParams(); RenderWaterMask(cam, SecondaryCameraRendering: false, cb_Mask); } [ImageEffectOpaque] private void OnRenderImage(RenderTexture src, RenderTexture dest) { RenderUnderWater(src, dest, cam, SecondaryCameraRendering: false); } public void SetGerstnerWaves(int index) { if (WaterMaterials[index].GetFloat(GerstnerEnabledPID) == 1f) { mat.EnableKeyword("GERSTNERENABLED"); mat.SetVector(LuxWaterMask_GerstnerVertexIntensityPID, WaterMaterials[index].GetVector(GerstnerVertexIntensityPID)); mat.SetVector(LuxWaterMask_GAmplitudePID, WaterMaterials[index].GetVector(GAmplitudePID)); mat.SetVector(LuxWaterMask_GFinalFrequencyPID, WaterMaterials[index].GetVector(GFinalFrequencyPID)); mat.SetVector(LuxWaterMask_GSteepnessPID, WaterMaterials[index].GetVector(GSteepnessPID)); mat.SetVector(LuxWaterMask_GFinalSpeedPID, WaterMaterials[index].GetVector(GFinalSpeedPID)); mat.SetVector(LuxWaterMask_GDirectionABPID, WaterMaterials[index].GetVector(GDirectionABPID)); mat.SetVector(LuxWaterMask_GDirectionCDPID, WaterMaterials[index].GetVector(GDirectionCDPID)); mat.SetVector(LuxWaterMask_GerstnerSecondaryWaves, WaterMaterials[index].GetVector(GerstnerSecondaryWaves)); } else { mat.DisableKeyword("GERSTNERENABLED"); } } public void RenderWaterMask(Camera currentCamera, bool SecondaryCameraRendering, CommandBuffer cmb) { Shader.SetGlobalFloat("_Lux_Time", Time.timeSinceLevelLoad); currentCamera.depthTextureMode |= DepthTextureMode.Depth; camTransform = currentCamera.transform; bool flag = false; TextureDimension dimension = TextureDimension.Tex2D; if (currentCamera.stereoEnabled && XRSettings.stereoRenderingMode == XRSettings.StereoRenderingMode.SinglePassInstanced) { flag = true; dimension = TextureDimension.Tex2DArray; } if (!UnderWaterMask) { UnderWaterMask = new RenderTexture(currentCamera.pixelWidth, currentCamera.pixelHeight, 24, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear); UnderWaterMask.dimension = dimension; if (flag) { UnderWaterMask.volumeDepth = 2; } } else if (UnderWaterMask.width != currentCamera.pixelWidth && !SecondaryCameraRendering) { UnityEngine.Object.DestroyImmediate(UnderWaterMask); UnderWaterMask = new RenderTexture(currentCamera.pixelWidth, currentCamera.pixelHeight, 24, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear); UnderWaterMask.dimension = dimension; if (flag) { UnderWaterMask.volumeDepth = 2; } } Shader.SetGlobalTexture(UnderWaterMaskPID, UnderWaterMask); currentCamera.CalculateFrustumCorners(new Rect(0f, 0f, 1f, 1f), currentCamera.farClipPlane, currentCamera.stereoActiveEye, frustumCorners); Vector3 vector = camTransform.TransformVector(frustumCorners[0]); Vector3 vector2 = camTransform.TransformVector(frustumCorners[1]); Vector3 vector3 = camTransform.TransformVector(frustumCorners[2]); Vector3 vector4 = camTransform.TransformVector(frustumCorners[3]); frustumCornersArray.SetRow(0, vector); frustumCornersArray.SetRow(1, vector4); frustumCornersArray.SetRow(2, vector2); frustumCornersArray.SetRow(3, vector3); if (flag) { currentCamera.CalculateFrustumCorners(new Rect(0f, 0f, 1f, 1f), currentCamera.farClipPlane, Camera.MonoOrStereoscopicEye.Right, frustumCorners); vector = camTransform.TransformVector(frustumCorners[0]); vector2 = camTransform.TransformVector(frustumCorners[1]); vector3 = camTransform.TransformVector(frustumCorners[2]); vector4 = camTransform.TransformVector(frustumCorners[3]); frustumCornersArray2nd.SetRow(0, vector); frustumCornersArray2nd.SetRow(1, vector4); frustumCornersArray2nd.SetRow(2, vector2); frustumCornersArray2nd.SetRow(3, vector3); } ambientProbe = RenderSettings.ambientProbe; ambientProbe.Evaluate(directions, AmbientLightingSamples); if (islinear) { Shader.SetGlobalColor(Lux_UnderWaterAmbientSkyLightPID, (AmbientLightingSamples[0] * RenderSettings.ambientIntensity).linear); } else { Shader.SetGlobalColor(Lux_UnderWaterAmbientSkyLightPID, AmbientLightingSamples[0] * RenderSettings.ambientIntensity); } if (!activeWaterVolumeCameras.Contains(currentCamera)) { _ = EnableAdvancedDeferredFog; } if (activeWaterVolume > -1) { Shader.EnableKeyword("LUXWATERENABLED"); if (!EnableDeepwaterLighting) { Shader.SetGlobalFloat("_Lux_UnderWaterDirLightingDepth", WaterMaterials[activeWaterVolume].GetFloat(Lux_MaxDirLightDepthPID)); Shader.SetGlobalFloat("_Lux_UnderWaterFogLightingDepth", WaterMaterials[activeWaterVolume].GetFloat(Lux_MaxFogLightDepthPID)); } Shader.SetGlobalFloat("_Lux_UnderWaterWaterSurfacePos", WaterSurfacePos); } else { Shader.DisableKeyword("LUXWATERENABLED"); } RenderTargetIdentifier renderTarget = ((!flag) ? new RenderTargetIdentifier(UnderWaterMask) : new RenderTargetIdentifier(UnderWaterMask, 0, CubemapFace.Unknown, -1)); cmb.Clear(); cmb.SetRenderTarget(renderTarget); cmb.ClearRenderTarget(clearDepth: true, clearColor: true, new Color(0f, 0f, 0f, 0f), 1f); cmb.SetGlobalMatrix(Lux_FrustumCornersWSPID, frustumCornersArray); cmb.SetGlobalMatrix("_Lux_FrustumCornersWS2ndEye", frustumCornersArray2nd); cmb.SetGlobalVector(Lux_CameraWSPID, camTransform.position); Shader.SetGlobalVector("_WorldSpaceCameraPos", camTransform.position); Shader.SetGlobalVector("_ProjectionParams", new Vector4(Projection, currentCamera.nearClipPlane, currentCamera.farClipPlane, 1f / currentCamera.farClipPlane)); Shader.SetGlobalVector("_ScreenParams", new Vector4(currentCamera.pixelWidth, currentCamera.pixelHeight, 1f + 1f / (float)currentCamera.pixelWidth, 1f + 1f / (float)currentCamera.pixelHeight)); for (int i = 0; i < RegisteredWaterVolumes.Count; i++) { if ((!WaterIsOnScreen[i] && i != activeWaterVolume) || (!EnableAdvancedDeferredFog && i != activeWaterVolume)) { continue; } WatervolumeMatrix = WaterTransforms[i].localToWorldMatrix; if (WaterUsesSlidingVolume[i]) { Vector3 position = camTransform.position; Vector4 column = WatervolumeMatrix.GetColumn(3); Vector3 lossyScale = WaterTransforms[i].lossyScale; Vector2 vector5 = new Vector2(activeGridSize * lossyScale.x, activeGridSize * lossyScale.z); float num = (float)Math.Round(position.x / vector5.x); float num2 = vector5.x * num; num = (float)Math.Round(position.z / vector5.y); float num3 = vector5.y * num; column.x = num2 + column.x % vector5.x; column.z = num3 + column.z % vector5.y; WatervolumeMatrix.SetColumn(3, column); } Material material = WaterMaterials[i]; if (material.GetFloat(GerstnerEnabledPID) == 1f) { mat.EnableKeyword("GERSTNERENABLED"); mat.SetVector(LuxWaterMask_GerstnerVertexIntensityPID, material.GetVector(GerstnerVertexIntensityPID)); mat.SetVector(LuxWaterMask_GAmplitudePID, material.GetVector(GAmplitudePID)); mat.SetVector(LuxWaterMask_GFinalFrequencyPID, material.GetVector(GFinalFrequencyPID)); mat.SetVector(LuxWaterMask_GSteepnessPID, material.GetVector(GSteepnessPID)); mat.SetVector(LuxWaterMask_GFinalSpeedPID, material.GetVector(GFinalSpeedPID)); mat.SetVector(LuxWaterMask_GDirectionABPID, material.GetVector(GDirectionABPID)); mat.SetVector(LuxWaterMask_GDirectionCDPID, material.GetVector(GDirectionCDPID)); mat.SetVector(LuxWaterMask_GerstnerSecondaryWaves, material.GetVector(GerstnerSecondaryWaves)); } else { mat.DisableKeyword("GERSTNERENABLED"); } mat.SetFloat(LuxMask_ExtrusionPID, material.GetFloat(Lux_ExtrusionPID)); bool flag2 = material.HasProperty(Lux_EdgeLengthPID) && SystemInfo.graphicsShaderLevel >= 46; if (flag2) { mat.SetFloat(Lux_EdgeLengthPID, material.GetFloat(Lux_EdgeLengthPID)); } if (i == activeWaterVolume && activeWaterVolumeCameras.Contains(currentCamera)) { if (WaterUsesSlidingVolume[i] && flag2) { cmb.DrawMesh(WaterMeshes[i], WatervolumeMatrix, mat, 0, 5); } else { cmb.DrawMesh(WaterMeshes[i], WatervolumeMatrix, mat, 0, 0); } } if ((i != activeWaterVolume || !activeWaterVolumeCameras.Contains(currentCamera)) && !EnableAdvancedDeferredFog) { continue; } if (flag2) { if (i == activeWaterVolume) { cmb.DrawMesh(WaterMeshes[i], WatervolumeMatrix, mat, 1, 3); } else { cmb.DrawMesh(WaterMeshes[i], WatervolumeMatrix, mat, 1, 4); } } else if (i == activeWaterVolume) { cmb.DrawMesh(WaterMeshes[i], WatervolumeMatrix, mat, 1, 1); } else { cmb.DrawMesh(WaterMeshes[i], WatervolumeMatrix, mat, 1, 2); } } } public void RenderUnderWater(RenderTexture src, RenderTexture dest, Camera currentCamera, bool SecondaryCameraRendering) { if (activeWaterVolumeCameras.Contains(currentCamera)) { if (DoUnderWaterRendering && activeWaterVolume > -1) { if (!UnderwaterIsSetUp) { if ((bool)Sun) { Vector3 vector = -Sun.forward; Color color = SunLight.color * SunLight.intensity; if (islinear) { color = color.linear; } Shader.SetGlobalColor(Lux_UnderWaterSunColorPID, color * Mathf.Clamp01(Vector3.Dot(vector, Vector3.up))); Shader.SetGlobalVector(Lux_UnderWaterSunDirPID, -vector); Shader.SetGlobalVector(Lux_UnderWaterSunDirViewSpacePID, currentCamera.WorldToViewportPoint(currentCamera.transform.position - vector * 1000f)); } if (WaterMaterials[activeWaterVolume].GetFloat(Lux_CausticsEnabledPID) == 1f) { blitMaterial.EnableKeyword("GEOM_TYPE_FROND"); if (WaterMaterials[activeWaterVolume].GetFloat(Lux_CausticModePID) == 1f) { blitMaterial.EnableKeyword("GEOM_TYPE_LEAF"); } else { blitMaterial.DisableKeyword("GEOM_TYPE_LEAF"); } } else { blitMaterial.DisableKeyword("GEOM_TYPE_FROND"); } if (islinear) { Shader.SetGlobalColor(Lux_UnderWaterFogColorPID, WaterMaterials[activeWaterVolume].GetColor("_Color").linear); } else { Shader.SetGlobalColor(Lux_UnderWaterFogColorPID, WaterMaterials[activeWaterVolume].GetColor("_Color")); } Shader.SetGlobalFloat(Lux_UnderWaterFogDensityPID, WaterMaterials[activeWaterVolume].GetFloat("_Density")); Shader.SetGlobalFloat(Lux_UnderWaterFogAbsorptionCancellationPID, WaterMaterials[activeWaterVolume].GetFloat("_FogAbsorptionCancellation")); Shader.SetGlobalFloat(Lux_UnderWaterAbsorptionHeightPID, WaterMaterials[activeWaterVolume].GetFloat("_AbsorptionHeight")); Shader.SetGlobalFloat(Lux_UnderWaterAbsorptionMaxHeightPID, WaterMaterials[activeWaterVolume].GetFloat("_AbsorptionMaxHeight")); Shader.SetGlobalFloat(Lux_UnderWaterAbsorptionDepthPID, WaterMaterials[activeWaterVolume].GetFloat("_AbsorptionDepth")); Shader.SetGlobalFloat(Lux_UnderWaterAbsorptionColorStrengthPID, WaterMaterials[activeWaterVolume].GetFloat("_AbsorptionColorStrength")); Shader.SetGlobalFloat(Lux_UnderWaterAbsorptionStrengthPID, WaterMaterials[activeWaterVolume].GetFloat("_AbsorptionStrength")); Shader.SetGlobalFloat(Lux_UnderWaterUnderwaterScatteringPowerPID, WaterMaterials[activeWaterVolume].GetFloat("_ScatteringPower")); Shader.SetGlobalFloat(Lux_UnderWaterUnderwaterScatteringIntensityPID, WaterMaterials[activeWaterVolume].GetFloat("_UnderwaterScatteringIntensity")); if (islinear) { Shader.SetGlobalColor(Lux_UnderWaterUnderwaterScatteringColorPID, WaterMaterials[activeWaterVolume].GetColor("_TranslucencyColor").linear); } else { Shader.SetGlobalColor(Lux_UnderWaterUnderwaterScatteringColorPID, WaterMaterials[activeWaterVolume].GetColor("_TranslucencyColor")); } Shader.SetGlobalFloat(Lux_UnderWaterUnderwaterScatteringOcclusionPID, WaterMaterials[activeWaterVolume].GetFloat("_ScatterOcclusion")); Shader.SetGlobalTexture(Lux_UnderWaterCausticsPID, WaterMaterials[activeWaterVolume].GetTexture(CausticTexPID)); Shader.SetGlobalFloat(Lux_UnderWaterCausticsTilingPID, WaterMaterials[activeWaterVolume].GetFloat("_CausticsTiling")); Shader.SetGlobalFloat(Lux_UnderWaterCausticsScalePID, WaterMaterials[activeWaterVolume].GetFloat("_CausticsScale")); Shader.SetGlobalFloat(Lux_UnderWaterCausticsSpeedPID, WaterMaterials[activeWaterVolume].GetFloat("_CausticsSpeed")); Shader.SetGlobalFloat(Lux_UnderWaterCausticsTilingPID, WaterMaterials[activeWaterVolume].GetFloat("_CausticsTiling")); Shader.SetGlobalFloat(Lux_UnderWaterCausticsSelfDistortionPID, WaterMaterials[activeWaterVolume].GetFloat("_CausticsSelfDistortion")); Shader.SetGlobalVector(Lux_UnderWaterFinalBumpSpeed01PID, WaterMaterials[activeWaterVolume].GetVector("_FinalBumpSpeed01")); Shader.SetGlobalVector(Lux_UnderWaterFogDepthAttenPID, WaterMaterials[activeWaterVolume].GetVector("_DepthAtten")); } Graphics.Blit(src, dest, blitMaterial, 0); } else { Graphics.Blit(src, dest); } } else { Graphics.Blit(src, dest); } } } }