private void LateUpdate() { if (OceanRenderer.Instance == null) { _rend.enabled = false; return; } float heightOffset = OceanRenderer.Instance.ViewerHeightAboveWater; // Disable skirt when camera not close to water. In the first few frames collision may not be avail, in that case no choice // but to assume enabled. In the future this could detect if camera is far enough under water, render a simple quad to avoid // finding the intersection line. _rend.enabled = heightOffset < _maxHeightAboveWater; if (_rend.enabled) { if (_copyParamsEachFrame) { _rend.material.CopyPropertiesFromMaterial(OceanRenderer.Instance.OceanMaterial); } // Assign lod0 shape - trivial but bound every frame because lod transform comes from here if (_mpb == null) { _mpb = new PropertyWrapperMPB(); } _rend.GetPropertyBlock(_mpb.materialPropertyBlock); // Underwater rendering uses displacements for intersecting the waves with the near plane, and ocean depth/shadows for ScatterColour() _mpb.SetInt(LodDataMgr.sp_LD_SliceIndex, 0); OceanRenderer.Instance._lodDataAnimWaves.BindResultData(_mpb); if (OceanRenderer.Instance._lodDataSeaDepths) { OceanRenderer.Instance._lodDataSeaDepths.BindResultData(_mpb); } else { LodDataMgrSeaFloorDepth.BindNull(_mpb); } if (OceanRenderer.Instance._lodDataShadow) { OceanRenderer.Instance._lodDataShadow.BindResultData(_mpb); } else { LodDataMgrShadow.BindNull(_mpb); } _mpb.SetFloat(sp_HeightOffset, heightOffset); _mpb.SetVector(sp_InstanceData, new Vector4(OceanRenderer.Instance.ViewerAltitudeLevelAlpha, 0f, 0f, OceanRenderer.Instance.CurrentLodCount)); _rend.SetPropertyBlock(_mpb.materialPropertyBlock); } }
private void LateUpdate() { if (OceanRenderer.Instance == null) { _rend.enabled = false; return; } float heightOffset = OceanRenderer.Instance.ViewerHeightAboveWater; if (_rend.enabled) { //if (_copyParamsEachFrame) //{ // _rend.material.CopyPropertiesFromMaterial(OceanRenderer.Instance.OceanMaterial); //} // Assign lod0 shape - trivial but bound every frame because lod transform comes from here if (_mpb == null) { _mpb = new MaterialPropertyBlock(); } _rend.GetPropertyBlock(_mpb); // Underwater rendering uses displacements for intersecting the waves with the near plane, and ocean depth/shadows for ScatterColour() OceanRenderer.Instance._lodDataAnimWaves.BindResultData(0, 0, _mpb); if (OceanRenderer.Instance._lodDataSeaDepths) { OceanRenderer.Instance._lodDataSeaDepths.BindResultData(0, 0, _mpb); } else { LodDataMgrSeaFloorDepth.BindNull(0, _mpb); } if (OceanRenderer.Instance._lodDataShadow) { OceanRenderer.Instance._lodDataShadow.BindResultData(0, 0, _mpb); } else { LodDataMgrShadow.BindNull(0, _mpb); } _mpb.SetFloat("_HeightOffset", heightOffset); _rend.SetPropertyBlock(_mpb); } }
private void LateUpdate() { float heightOffset = OceanRenderer.Instance.ViewerHeightAboveWater; // Disable skirt when camera not close to water. In the first few frames collision may not be avail, in that case no choice // but to assume enabled. In the future this could detect if camera is far enough under water, render a simple quad to avoid // finding the intersection line. _rend.enabled = heightOffset < _maxHeightAboveWater; if (_rend.enabled) { if (_copyParamsEachFrame) { _rend.material.CopyPropertiesFromMaterial(OceanRenderer.Instance.OceanMaterial); } // Assign lod0 shape - trivial but bound every frame because lod transform comes from here if (_mpb == null) { _mpb = new MaterialPropertyBlock(); } _rend.GetPropertyBlock(_mpb); // Underwater rendering uses displacements for intersecting the waves with the near plane, and ocean depth/shadows for ScatterColour() OceanRenderer.Instance._lodDataAnimWaves.BindResultData(0, 0, _mpb); if (OceanRenderer.Instance._createSeaFloorDepthData) { OceanRenderer.Instance._lodDataSeaDepths.BindResultData(0, 0, _mpb); } else { LodDataMgrSeaFloorDepth.BindNull(0, _mpb); } if (OceanRenderer.Instance._createShadowData) { OceanRenderer.Instance._lodDataShadow.BindResultData(0, 0, _mpb); } else { LodDataMgrShadow.BindNull(0, _mpb); } _mpb.SetFloat("_HeightOffset", heightOffset); _rend.SetPropertyBlock(_mpb); } }
// 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); }
private void LateUpdate() { #if UNITY_EDITOR // We don't run in "prefab scenes", i.e. when editing a prefab. Bail out if prefab scene is detected. if (PrefabStageUtility.GetCurrentPrefabStage() != null) { return; } #endif if (OceanRenderer.Instance == null) { _rend.enabled = false; return; } float waterHeight = OceanRenderer.Instance.SeaLevel; // Pass true in last arg for a crap reason - in edit mode LateUpdate can be called very frequently, and the height sampler mistakenly thinks // this is erroneous and complains. _sampleWaterHeight.Init(transform.position, 0f, true); _sampleWaterHeight.Sample(ref waterHeight); float heightOffset = transform.position.y - waterHeight; // Disable skirt when camera not close to water. In the first few frames collision may not be avail, in that case no choice // but to assume enabled. In the future this could detect if camera is far enough under water, render a simple quad to avoid // finding the intersection line. _rend.enabled = heightOffset < _maxHeightAboveWater; if (_rend.enabled) { if (_copyParamsEachFrame) { _rend.sharedMaterial.CopyPropertiesFromMaterial(OceanRenderer.Instance.OceanMaterial); } // Assign lod0 shape - trivial but bound every frame because lod transform comes from here if (_mpb == null) { _mpb = new PropertyWrapperMPB(); } _rend.GetPropertyBlock(_mpb.materialPropertyBlock); // Underwater rendering uses displacements for intersecting the waves with the near plane, and ocean depth/shadows for ScatterColour() _mpb.SetInt(LodDataMgr.sp_LD_SliceIndex, 0); OceanRenderer.Instance._lodDataAnimWaves.BindResultData(_mpb); if (OceanRenderer.Instance._lodDataSeaDepths != null) { OceanRenderer.Instance._lodDataSeaDepths.BindResultData(_mpb); } else { LodDataMgrSeaFloorDepth.BindNull(_mpb); } if (OceanRenderer.Instance._lodDataShadow != null) { OceanRenderer.Instance._lodDataShadow.BindResultData(_mpb); } else { LodDataMgrShadow.BindNull(_mpb); } _mpb.SetFloat(sp_HeightOffset, heightOffset); _mpb.SetVector(OceanChunkRenderer.sp_InstanceData, new Vector3(OceanRenderer.Instance.ViewerAltitudeLevelAlpha, 0f, 0f)); _rend.SetPropertyBlock(_mpb.materialPropertyBlock); } }
// Called when visible to a camera void OnWillRenderObject() { // 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 MaterialPropertyBlock(); } _rend.GetPropertyBlock(_mpb); // 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("_InstanceData", new Vector4(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 = Mathf.Pow(2f, Mathf.Round(Mathf.Log(transform.lossyScale.x) / Mathf.Log(2f))); 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("_GeomData", new Vector4(gridSizeLodData, gridSizeGeo, normalScrollSpeed0, normalScrollSpeed1)); // assign lod data to ocean shader var ldaws = OceanRenderer.Instance._lodDataAnimWaves; var ldsds = OceanRenderer.Instance._lodDataSeaDepths; var ldfoam = OceanRenderer.Instance._lodDataFoam; var ldflow = OceanRenderer.Instance._lodDataFlow; var ldshadows = OceanRenderer.Instance._lodDataShadow; ldaws.BindResultData(_lodIndex, 0, _mpb); if (ldflow) ldflow.BindResultData(_lodIndex, 0, _mpb); if (ldfoam) ldfoam.BindResultData(_lodIndex, 0, _mpb); if (ldsds) ldsds.BindResultData(_lodIndex, 0, _mpb); if (ldshadows) ldshadows.BindResultData(_lodIndex, 0, _mpb); else LodDataMgrShadow.BindNull(0, _mpb); if (_lodIndex + 1 < OceanRenderer.Instance.CurrentLodCount) { ldaws.BindResultData(_lodIndex + 1, 1, _mpb); if (ldflow) ldflow.BindResultData(_lodIndex + 1, 1, _mpb); if (ldfoam) ldfoam.BindResultData(_lodIndex + 1, 1, _mpb); if (ldsds) ldsds.BindResultData(_lodIndex + 1, 1, _mpb); if (ldshadows) ldshadows.BindResultData(_lodIndex + 1, 1, _mpb); else LodDataMgrShadow.BindNull(1, _mpb); } var reflTex = OceanPlanarReflection.GetRenderTexture(_currentCamera.targetDisplay); if (reflTex) { _mpb.SetTexture(_reflectionTexId, reflTex); } else { _mpb.SetTexture(_reflectionTexId, Texture2D.blackTexture); } // Hack - due to SV_IsFrontFace occasionally coming through as true for backfaces, // add a param here that forces ocean to be in undrwater 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("_ForceUnderwater", heightOffset < -2f ? 1f : 0f); _rend.SetPropertyBlock(_mpb); if (_drawRenderBounds) { _rend.bounds.DebugDraw(); } }