public WaterSurface(
            GraphicsDevice graphicsDevice,
            InitInfo initInfo)
        {
            Effect = new VisionEffect(initInfo.Fx, graphicsDevice.SamplerStates.LinearClamp)
            {
                SunlightDirection = VisionContent.SunlightDirection - new Vector3(0, VisionContent.SunlightDirection.Y/2, 0)
            };

            _waveBumpMapVelocity0 = initInfo.waveBumpMapVelocity0;
            _waveBumpMapVelocity1 = initInfo.waveBumpMapVelocity1;
            _waveDispMapVelocity0 = initInfo.waveDispMapVelocity0;
            _waveDispMapVelocity1 = initInfo.waveDispMapVelocity1;

            _hiPolyPlane = generatePlane(graphicsDevice, initInfo.SquareSize, initInfo.dx, initInfo.dz,
                                         initInfo.texScale);

            _lakePlane = generatePlane(graphicsDevice, 1, initInfo.SquareSize*512, initInfo.SquareSize*512, initInfo.texScale*512);

            buildFx(initInfo);

            var targetWidth = graphicsDevice.BackBuffer.Width;
            var targetHeight = graphicsDevice.BackBuffer.Height;
            _reflectionTarget = RenderTarget2D.New(
                graphicsDevice,
                targetWidth,
                targetHeight*11/10, //compensate for displaced waves
                graphicsDevice.BackBuffer.Format);

            _reflectionCamera = new Camera(
                new Vector2(targetWidth, targetHeight),
                null,
                null,
                null,
                Vector3.Zero,
                Vector3.Up);

            Update(10);
        }
        private void buildFx(InitInfo initInfo)
        {
            var p = Effect.Effect.Parameters;

            p["MirrorSampler"].SetResource(Effect.GraphicsDevice.SamplerStates.PointMirror);

            _mhWorldInv = p["WorldInv"];
            _mhCameraPosition = p["CameraPosition"];
            _mhWaveBumpMapOffset0 = p["WaveNMapOffset0"];
            _mhWaveBumpMapOffset1 = p["WaveNMapOffset1"];
            _mhWaveDispMapOffset0 = p["WaveDMapOffset0"];
            _mhWaveDispMapOffset1 = p["WaveDMapOffset1"];
            _reflectedView = p["ReflectedView"];
            _reflectedMap = p["ReflectedMap"];

            p["BumpMap0"].SetResource(initInfo.waveMap0);
            p["BumpMap1"].SetResource(initInfo.waveMap1);

            p["WaveDispMap0"].SetResource(initInfo.dmap0);
            p["WaveDispMap1"].SetResource(initInfo.dmap1);
            p["ScaleHeights"].SetValue(initInfo.scaleHeights);
            p["GridStepSizeL"].SetValue(new Vector2(initInfo.dx, initInfo.dz));
            p["WaveHeight"].SetValue(0.3f * 2);
        }