public WaterSurface(GraphicsDevice device, Camera camera, Vector3 normal, float position, int sizeX, int sizeY)
        {
            Vector3 x;

            Device             = device;
            Camera             = camera;
            Normal             = normal;
            Position           = position;
            Plane              = new Plane(normal, position);
            NoiseMaker         = new NoiseMaker(Device, GridSizeX, GridSizeY);
            PlaneWithinFrustum = false;

            // Set the initial water color
            WaterColor = Color.Aquamarine;

            // Calculate the U and V vectors
            if (Math.Abs(Vector3.Dot(Vector3.UnitX, normal)) < Math.Abs(Vector3.Dot(Vector3.UnitY, normal)))
            {
                x = Vector3.UnitX;
            }
            else
            {
                x = Vector3.UnitY;
            }

            U = x - normal * Vector3.Dot(normal, x);
            U = Vector3.Normalize(U);

            // Get V (cross)
            V = Vector3.Cross(U, normal);

            GridSizeX = sizeX + 1;
            GridSizeY = sizeY + 1;

            SetDisplacementAmplitude(0);

            if (!InitializeBuffers())
            {
                return;
            }

            // Load the textures
            if ((Fresnel = Texture2D.FromFile(Device, "textures/fresnel_water_linear.bmp")) == null)
            {
                return;
            }
            if ((XYNoise = Texture2D.FromFile(Device, "textures/xynoise.png")) == null)
            {
                return;
            }

            // Initialize the reflection and refraction textures, and the depth stencil
            Reflection = new Texture2D(Device, REFLREFRDETAIL, REFLREFRDETAIL, 1, ResourceUsage.RenderTarget,
                                       SurfaceFormat.Color, ResourcePool.Default);
            Refraction = new Texture2D(Device, REFLREFRDETAIL, REFLREFRDETAIL, 1, ResourceUsage.RenderTarget,
                                       SurfaceFormat.Color, ResourcePool.Default);
            DepthStencil = Device.CreateDepthStencilSurface(REFLREFRDETAIL, REFLREFRDETAIL, DepthFormat.Depth24Stencil8,
                                                            MultiSampleType.None, 0, true);

            // Load the effect
            CompiledEffect water = Effect.CompileEffectFromFile("shaders/watereffect.fx", null, null,
                                                                CompilerOptions.Debug | CompilerOptions.SkipOptimization, TargetPlatform.Windows);

            if (!water.Success)
            {
                return;
            }
            else
            {
                WaterEffect = new Effect(Device, water.GetShaderCode(), CompilerOptions.None, null);
            }

            Initialized = true;
        }
        public WaterSurface(GraphicsDevice device, Camera camera, Vector3 normal, float position, int sizeX, int sizeY)
        {
            Vector3 x;

            Device = device;
            Camera = camera;
            Normal = normal;
            Position = position;
            Plane = new Plane(normal, position);
            NoiseMaker = new NoiseMaker(Device, GridSizeX, GridSizeY);
            PlaneWithinFrustum = false;

            // Set the initial water color
            WaterColor = Color.Aquamarine;

            // Calculate the U and V vectors
            if (Math.Abs(Vector3.Dot(Vector3.UnitX, normal)) < Math.Abs(Vector3.Dot(Vector3.UnitY, normal)))
            {
                x = Vector3.UnitX;
            }
            else
            {
                x = Vector3.UnitY;
            }

            U = x - normal * Vector3.Dot(normal, x);
            U = Vector3.Normalize(U);

            // Get V (cross)
            V = Vector3.Cross(U, normal);

            GridSizeX = sizeX + 1;
            GridSizeY = sizeY + 1;

            SetDisplacementAmplitude(0);

            if (!InitializeBuffers())
            {
                return;
            }

            // Load the textures
            if ((Fresnel = Texture2D.FromFile(Device, "textures/fresnel_water_linear.bmp")) == null)
            {
                return;
            }
            if ((XYNoise = Texture2D.FromFile(Device, "textures/xynoise.png")) == null)
            {
                return;
            }

            // Initialize the reflection and refraction textures, and the depth stencil
            Reflection = new Texture2D(Device, REFLREFRDETAIL, REFLREFRDETAIL, 1, ResourceUsage.RenderTarget,
                SurfaceFormat.Color, ResourcePool.Default);
            Refraction = new Texture2D(Device, REFLREFRDETAIL, REFLREFRDETAIL, 1, ResourceUsage.RenderTarget,
                SurfaceFormat.Color, ResourcePool.Default);
            DepthStencil = Device.CreateDepthStencilSurface(REFLREFRDETAIL, REFLREFRDETAIL, DepthFormat.Depth24Stencil8,
                MultiSampleType.None, 0, true);

            // Load the effect
            CompiledEffect water = Effect.CompileEffectFromFile("shaders/watereffect.fx", null, null,
                CompilerOptions.Debug | CompilerOptions.SkipOptimization, TargetPlatform.Windows);
            if (!water.Success)
            {
                return;
            }
            else
            {
                WaterEffect = new Effect(Device, water.GetShaderCode(), CompilerOptions.None, null);
            }

            Initialized = true;
        }