void InitViewpoint() { if (_viewpoint == null) { var camMain = Camera.main; if (camMain != null) { _viewpoint = camMain.transform; _planarReflection = camMain.GetComponent <OceanPlanarReflection>(); } else { Debug.LogError("Please provide the viewpoint transform, or tag the primary camera as MainCamera.", this); } } }
// Called when visible to a camera void OnWillRenderObject() { // Depth texture is used by ocean shader for transparency/depth fog, and for fading out foam at shoreline. Camera.current.depthTextureMode |= DepthTextureMode.Depth; // 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 (OceanRenderer.Instance.CreateFlowSim) { ldflow.BindResultData(_lodIndex, 0, _mpb); } if (OceanRenderer.Instance.CreateFoamSim) { ldfoam.BindResultData(_lodIndex, 0, _mpb); } if (OceanRenderer.Instance.CreateSeaFloorDepthData) { ldsds.BindResultData(_lodIndex, 0, _mpb); } if (OceanRenderer.Instance.CreateShadowData) { ldshadows.BindResultData(_lodIndex, 0, _mpb); } if (_lodIndex + 1 < OceanRenderer.Instance.CurrentLodCount) { ldaws.BindResultData(_lodIndex + 1, 1, _mpb); if (OceanRenderer.Instance.CreateFlowSim) { ldflow.BindResultData(_lodIndex + 1, 1, _mpb); } if (OceanRenderer.Instance.CreateFoamSim) { ldfoam.BindResultData(_lodIndex + 1, 1, _mpb); } if (OceanRenderer.Instance.CreateSeaFloorDepthData) { ldsds.BindResultData(_lodIndex + 1, 1, _mpb); } if (OceanRenderer.Instance.CreateShadowData) { ldshadows.BindResultData(_lodIndex + 1, 1, _mpb); } } var reflTex = OceanPlanarReflection.GetRenderTexture(Camera.current.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(); } }