private void CleanUp() { foreach (var lodData in _lodDatas) { lodData.OnDisable(); } _lodDatas.Clear(); #if UNITY_EDITOR if (!EditorApplication.isPlaying && Root != null) { DestroyImmediate(Root.gameObject); } else #endif if (Root != null) { Destroy(Root.gameObject); } Root = null; _lodTransform = null; _lodDataAnimWaves = null; _lodDataClipSurface = null; _lodDataDynWaves = null; _lodDataFlow = null; _lodDataFoam = null; _lodDataSeaDepths = null; _lodDataShadow = null; }
private void LateUpdate() { if (OceanRenderer.Instance == null) { return; } // find which lod this object is overlapping var rect = new Rect(transform.position.x, transform.position.z, 0f, 0f); var lodIdx = LodDataMgrAnimWaves.SuggestDataLOD(rect); if (lodIdx > -1) { if (_mpb == null) { _mpb = new PropertyWrapperMPB(); } _rend.GetPropertyBlock(_mpb.materialPropertyBlock); var lodCount = OceanRenderer.Instance.CurrentLodCount; var lodDataAnimWaves = OceanRenderer.Instance._lodDataAnimWaves; _mpb.SetInt(LodDataMgr.sp_LD_SliceIndex, lodIdx); lodDataAnimWaves.BindResultData(_mpb); var lodDataClipSurface = OceanRenderer.Instance._lodDataClipSurface; if (lodDataClipSurface != null) { lodDataClipSurface.BindResultData(_mpb); } else { LodDataMgrClipSurface.BindNull(_mpb); } // blend LOD 0 shape in/out to avoid pop, if the ocean might scale up later (it is smaller than its maximum scale) bool needToBlendOutShape = lodIdx == 0 && OceanRenderer.Instance.ScaleCouldIncrease; float meshScaleLerp = needToBlendOutShape ? OceanRenderer.Instance.ViewerAltitudeLevelAlpha : 0f; // blend furthest normals scale in/out to avoid pop, if scale could reduce bool needToBlendOutNormals = lodIdx == lodCount - 1 && OceanRenderer.Instance.ScaleCouldDecrease; float farNormalsWeight = needToBlendOutNormals ? OceanRenderer.Instance.ViewerAltitudeLevelAlpha : 1f; _mpb.SetVector(OceanChunkRenderer.sp_InstanceData, new Vector3(meshScaleLerp, farNormalsWeight, lodIdx)); _rend.SetPropertyBlock(_mpb.materialPropertyBlock); } LateUpdateBounds(); }
// Called when visible to a camera void OnWillRenderObject() { if (OceanRenderer.Instance == null || Rend == null) { return; } // check if built-in pipeline being used if (Camera.current != null) { _currentCamera = Camera.current; } // Depth texture is used by ocean shader for transparency/depth fog, and for fading out foam at shoreline. _currentCamera.depthTextureMode |= DepthTextureMode.Depth; if (Rend.sharedMaterial != OceanRenderer.Instance.OceanMaterial) { Rend.sharedMaterial = OceanRenderer.Instance.OceanMaterial; } // per instance data if (_mpb == null) { _mpb = new PropertyWrapperMPB(); } Rend.GetPropertyBlock(_mpb.materialPropertyBlock); // blend LOD 0 shape in/out to avoid pop, if the ocean might scale up later (it is smaller than its maximum scale) var needToBlendOutShape = _lodIndex == 0 && OceanRenderer.Instance.ScaleCouldIncrease; var meshScaleLerp = needToBlendOutShape ? OceanRenderer.Instance.ViewerAltitudeLevelAlpha : 0f; // blend furthest normals scale in/out to avoid pop, if scale could reduce var needToBlendOutNormals = _lodIndex == _totalLodCount - 1 && OceanRenderer.Instance.ScaleCouldDecrease; var farNormalsWeight = needToBlendOutNormals ? OceanRenderer.Instance.ViewerAltitudeLevelAlpha : 1f; _mpb.SetVector(sp_InstanceData, new Vector3(meshScaleLerp, farNormalsWeight, _lodIndex)); // geometry data // compute grid size of geometry. take the long way to get there - make sure we land exactly on a power of two // and not inherit any of the lossy-ness from lossyScale. var scale_pow_2 = OceanRenderer.Instance.CalcLodScale(_lodIndex); var gridSizeGeo = scale_pow_2 / (0.25f * _lodDataResolution / _geoDownSampleFactor); var gridSizeLodData = gridSizeGeo / _geoDownSampleFactor; var mul = 1.875f; // fudge 1 var pow = 1.4f; // fudge 2 var normalScrollSpeed0 = Mathf.Pow(Mathf.Log(1f + 2f * gridSizeLodData) * mul, pow); var normalScrollSpeed1 = Mathf.Pow(Mathf.Log(1f + 4f * gridSizeLodData) * mul, pow); _mpb.SetVector(sp_GeomData, new Vector4(gridSizeLodData, gridSizeGeo, normalScrollSpeed0, normalScrollSpeed1)); // Assign LOD data to ocean shader var ldaws = OceanRenderer.Instance._lodDataAnimWaves; var ldsds = OceanRenderer.Instance._lodDataSeaDepths; var ldclip = OceanRenderer.Instance._lodDataClipSurface; var ldfoam = OceanRenderer.Instance._lodDataFoam; var ldflow = OceanRenderer.Instance._lodDataFlow; var ldshadows = OceanRenderer.Instance._lodDataShadow; _mpb.SetInt(LodDataMgr.sp_LD_SliceIndex, _lodIndex); if (ldaws != null) { ldaws.BindResultData(_mpb); } if (ldflow != null) { ldflow.BindResultData(_mpb); } else { LodDataMgrFlow.BindNull(_mpb); } if (ldfoam != null) { ldfoam.BindResultData(_mpb); } else { LodDataMgrFoam.BindNull(_mpb); } if (ldsds != null) { ldsds.BindResultData(_mpb); } else { LodDataMgrSeaFloorDepth.BindNull(_mpb); } if (ldclip != null) { ldclip.BindResultData(_mpb); } else { LodDataMgrClipSurface.BindNull(_mpb); } if (ldshadows != null) { ldshadows.BindResultData(_mpb); } else { LodDataMgrShadow.BindNull(_mpb); } var reflTex = PreparedReflections.GetRenderTexture(_currentCamera.GetHashCode()); if (reflTex) { _mpb.SetTexture(sp_ReflectionTex, reflTex); } else { _mpb.SetTexture(sp_ReflectionTex, Texture2D.blackTexture); } // Hack - due to SV_IsFrontFace occasionally coming through as true for back faces, // add a param here that forces ocean to be in underwater state. I think the root // cause here might be imprecision or numerical issues at ocean tile boundaries, although // i'm not sure why cracks are not visible in this case. var heightOffset = OceanRenderer.Instance.ViewerHeightAboveWater; _mpb.SetFloat(sp_ForceUnderwater, heightOffset < -2f ? 1f : 0f); Rend.SetPropertyBlock(_mpb.materialPropertyBlock); }
void CreateDestroySubSystems() { { if (_lodDataAnimWaves == null) { _lodDataAnimWaves = new LodDataMgrAnimWaves(this); _lodDatas.Add(_lodDataAnimWaves); } } if (CreateClipSurfaceData) { if (_lodDataClipSurface == null) { _lodDataClipSurface = new LodDataMgrClipSurface(this); _lodDatas.Add(_lodDataClipSurface); } } else { if (_lodDataClipSurface != null) { _lodDataClipSurface.OnDisable(); _lodDatas.Remove(_lodDataClipSurface); _lodDataClipSurface = null; } } if (CreateDynamicWaveSim) { if (_lodDataDynWaves == null) { _lodDataDynWaves = new LodDataMgrDynWaves(this); _lodDatas.Add(_lodDataDynWaves); } } else { if (_lodDataDynWaves != null) { _lodDataDynWaves.OnDisable(); _lodDatas.Remove(_lodDataDynWaves); _lodDataDynWaves = null; } } if (CreateFlowSim) { if (_lodDataFlow == null) { _lodDataFlow = new LodDataMgrFlow(this); _lodDatas.Add(_lodDataFlow); } if (FlowProvider != null && !(FlowProvider is QueryFlow)) { FlowProvider.CleanUp(); FlowProvider = null; } } else { if (_lodDataFlow != null) { _lodDataFlow.OnDisable(); _lodDatas.Remove(_lodDataFlow); _lodDataFlow = null; } if (FlowProvider != null && FlowProvider is QueryFlow) { FlowProvider.CleanUp(); FlowProvider = null; } } if (FlowProvider == null) { FlowProvider = _lodDataAnimWaves.Settings.CreateFlowProvider(this); } if (CreateFoamSim) { if (_lodDataFoam == null) { _lodDataFoam = new LodDataMgrFoam(this); _lodDatas.Add(_lodDataFoam); } } else { if (_lodDataFoam != null) { _lodDataFoam.OnDisable(); _lodDatas.Remove(_lodDataFoam); _lodDataFoam = null; } } if (CreateSeaFloorDepthData) { if (_lodDataSeaDepths == null) { _lodDataSeaDepths = new LodDataMgrSeaFloorDepth(this); _lodDatas.Add(_lodDataSeaDepths); } } else { if (_lodDataSeaDepths != null) { _lodDataSeaDepths.OnDisable(); _lodDatas.Remove(_lodDataSeaDepths); _lodDataSeaDepths = null; } } if (CreateShadowData) { if (_lodDataShadow == null) { _lodDataShadow = new LodDataMgrShadow(this); _lodDatas.Add(_lodDataShadow); } } else { if (_lodDataShadow != null) { _lodDataShadow.OnDisable(); _lodDatas.Remove(_lodDataShadow); _lodDataShadow = null; } } // Potential extension - add 'type' field to collprovider and change provider if settings have changed - this would support runtime changes. if (CollisionProvider == null) { CollisionProvider = _lodDataAnimWaves.Settings.CreateCollisionProvider(); } }
void CreateDestroyLodDatas() { { if (_lodDataAnimWaves == null) { _lodDataAnimWaves = new LodDataMgrAnimWaves(this); _lodDatas.Add(_lodDataAnimWaves); } } if (CreateClipSurfaceData) { if (_lodDataClipSurface == null) { _lodDataClipSurface = new LodDataMgrClipSurface(this); _lodDatas.Add(_lodDataClipSurface); } } else { if (_lodDataClipSurface != null) { _lodDataClipSurface.OnDisable(); _lodDatas.Remove(_lodDataClipSurface); _lodDataClipSurface = null; } } if (CreateDynamicWaveSim) { if (_lodDataDynWaves == null) { _lodDataDynWaves = new LodDataMgrDynWaves(this); _lodDatas.Add(_lodDataDynWaves); } } else { if (_lodDataDynWaves != null) { _lodDataDynWaves.OnDisable(); _lodDatas.Remove(_lodDataDynWaves); _lodDataDynWaves = null; } } if (CreateFlowSim) { if (_lodDataFlow == null) { _lodDataFlow = new LodDataMgrFlow(this); _lodDatas.Add(_lodDataFlow); } } else { if (_lodDataFlow != null) { _lodDataFlow.OnDisable(); _lodDatas.Remove(_lodDataFlow); _lodDataFlow = null; } } if (CreateFoamSim) { if (_lodDataFoam == null) { _lodDataFoam = new LodDataMgrFoam(this); _lodDatas.Add(_lodDataFoam); } } else { if (_lodDataFoam != null) { _lodDataFoam.OnDisable(); _lodDatas.Remove(_lodDataFoam); _lodDataFoam = null; } } if (CreateSeaFloorDepthData) { if (_lodDataSeaDepths == null) { _lodDataSeaDepths = new LodDataMgrSeaFloorDepth(this); _lodDatas.Add(_lodDataSeaDepths); } } else { if (_lodDataSeaDepths != null) { _lodDataSeaDepths.OnDisable(); _lodDatas.Remove(_lodDataSeaDepths); _lodDataSeaDepths = null; } } if (CreateShadowData) { if (_lodDataShadow == null) { _lodDataShadow = new LodDataMgrShadow(this); _lodDatas.Add(_lodDataShadow); } } else { if (_lodDataShadow != null) { _lodDataShadow.OnDisable(); _lodDatas.Remove(_lodDataShadow); _lodDataShadow = null; } } }