예제 #1
0
        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();
            }
        }