示例#1
0
        private void SetLocalMapCoordinates()
        {
            int   resolution    = Mathf.NextPowerOfTwo((thisCamera.pixelWidth + thisCamera.pixelHeight) >> 1);
            float maxHeight     = 0.0f;
            float maxWaterLevel = 0.0f;

            var waters            = WaterGlobals.Instance.Waters;
            int numWaterInstances = waters.Count;

            for (int waterIndex = 0; waterIndex < numWaterInstances; ++waterIndex)
            {
                var water = waters[waterIndex];
                maxHeight += water.MaxVerticalDisplacement;

                float posY = water.transform.position.y;
                if (maxWaterLevel < posY)
                {
                    maxWaterLevel = posY;
                }
            }

            // place camera
            Vector3 thisCameraPosition = thisCamera.transform.position;
            Vector3 screenSpaceDown    = WaterUtilities.ViewportWaterPerpendicular(thisCamera);
            Vector3 worldSpaceDown     = thisCamera.transform.localToWorldMatrix * WaterUtilities.RaycastPlane(thisCamera, maxWaterLevel, screenSpaceDown);
            Vector3 worldSpaceCenter   = thisCamera.transform.localToWorldMatrix * WaterUtilities.RaycastPlane(thisCamera, maxWaterLevel, new Vector3(0.5f, 0.5f, 0.5f));

            Vector3 effectCameraPosition;

            if (worldSpaceDown.sqrMagnitude > worldSpaceCenter.sqrMagnitude)
            {
                effectCameraPosition = new Vector3(thisCameraPosition.x + worldSpaceDown.x * 3.0f, 0.0f, thisCameraPosition.z + worldSpaceDown.z * 3.0f);
            }
            else
            {
                effectCameraPosition = new Vector3(thisCameraPosition.x + worldSpaceCenter.x * 3.0f, 0.0f, thisCameraPosition.z + worldSpaceCenter.z * 3.0f);
            }

            Vector3 diff = effectCameraPosition - thisCameraPosition;

            if (diff.magnitude > thisCamera.farClipPlane * 0.5f)
            {
                effectCameraPosition   = thisCameraPosition + diff.normalized * thisCamera.farClipPlane * 0.5f;
                effectCameraPosition.y = 0.0f;
            }

            Vector3 thisCameraForward = thisCamera.transform.forward;
            float   forwardFactor     = Mathf.Min(1.0f, thisCameraForward.y + 1.0f);

            float size1 = thisCameraPosition.y * (1.0f + 7.0f * Mathf.Sqrt(forwardFactor));
            float size2 = maxHeight * 2.5f;
            //float size3 = Vector3.Distance(effectCameraPosition, thisCameraPosition);
            //float size = size1 > size2 ? (size1 > size3 ? size1 : size3) : (size2 > size3 ? size2 : size3);
            float size = size1 > size2 ? size1 : size2;

            effectCameraPosition = new Vector3(thisCameraPosition.x + thisCameraForward.x * size * 0.4f, 0.0f, thisCameraPosition.z + thisCameraForward.z * size * 0.4f);

            localMapsRectPrevious = localMapsRect;

            float halfPixelSize = size / resolution;

            localMapsRect = new Rect((effectCameraPosition.x - size) + halfPixelSize, (effectCameraPosition.z - size) + halfPixelSize, 2.0f * size, 2.0f * size);

            Shader.SetGlobalVector("_LocalMapsCoordsPrevious", new Vector4(-localMapsRectPrevious.xMin, -localMapsRectPrevious.yMin, 1.0f / localMapsRectPrevious.width, localMapsRectPrevious.width));
            Shader.SetGlobalVector("_LocalMapsCoords", new Vector4(-localMapsRect.xMin, -localMapsRect.yMin, 1.0f / localMapsRect.width, localMapsRect.width));
        }
示例#2
0
        protected override Matrix4x4 GetMatrix(Camera camera)
        {
            Vector3 down  = WaterUtilities.ViewportWaterPerpendicular(camera);
            Vector3 right = WaterUtilities.ViewportWaterRight(camera);

            float   waterPositionY = water.transform.position.y;
            Vector3 ld             = WaterUtilities.RaycastPlane(camera, waterPositionY, (down - right));
            Vector3 rd             = WaterUtilities.RaycastPlane(camera, waterPositionY, (down + right));

            float   farClipPlane   = camera.farClipPlane;
            float   fieldOfViewTan = Mathf.Tan(camera.fieldOfView * 0.5f * Mathf.Deg2Rad);
            Vector3 position       = camera.transform.position;
            Vector3 scale          = camera.orthographic ? new Vector3(farClipPlane, farClipPlane, farClipPlane) : new Vector3(farClipPlane * fieldOfViewTan * camera.aspect + water.MaxHorizontalDisplacement * 2, farClipPlane, farClipPlane);

            float width = rd.x - ld.x;

            if (width < 0.0f)
            {
                width = -width;
            }

            float offset = (ld.z < rd.z ? ld.z : rd.z) - (width + water.MaxHorizontalDisplacement * 2.0f) * scale.z / scale.x;

            if (camera.orthographic)
            {
                offset -= camera.orthographicSize * 3.2f;
            }

            Vector3 backward;

            float dp = camera.transform.forward.y;                         // Vector3.Dot(Vector3.down, camera.transform.forward)

            if (dp < -0.98f || dp > 0.98f)
            {
                backward = -camera.transform.up;
                float len = Mathf.Sqrt(backward.x * backward.x + backward.z * backward.z);
                backward.x /= len;
                backward.z /= len;

                if (!camera.orthographic)
                {
                    offset = -position.y * 4.0f * fieldOfViewTan;
                }
            }
            else
            {
                backward = camera.transform.forward;
                float len = Mathf.Sqrt(backward.x * backward.x + backward.z * backward.z);
                backward.x /= len;
                backward.z /= len;
            }

            if (!camera.orthographic)
            {
                scale.z -= offset;
            }

            return(Matrix4x4.TRS(
                       new Vector3(position.x + backward.x * offset, waterPositionY, position.z + backward.z * offset),
                       Quaternion.AngleAxis(Mathf.Atan2(backward.x, backward.z) * Mathf.Rad2Deg, Vector3.up),
                       scale
                       ));
        }