private Tuple <Material, Media3D.Transform3D> LoadBeetle()
        {
            var    data = ReadDat("stagbeetle208x208x123.dat", out var width, out var height, out var depth);
            var    m    = new VolumeTextureDiffuseMaterial();
            ushort max  = data.Max();

            uint[] histogram = new uint[max + 1];

            float[] fdata = new float[data.Length];

            for (int i = 0; i < data.Length; ++i)
            {
                fdata[i] = (float)data[i] / max;
                histogram[data[i]]++;
            }
            var transferMap = GetTransferFunction(histogram, data.Length, 1, 0.0001f);
            var gradients   = VolumeDataHelper.GenerateGradients(fdata, width, height, depth, 1);

            VolumeDataHelper.FilterNxNxN(gradients, width, height, depth, 3);
            m.Texture = new VolumeTextureGradientParams(gradients, width, height, depth);
            m.Color   = new Color4(0, 1, 0, 0.4f);
            var transform = new Media3D.ScaleTransform3D(1, 1, 1);

            transform.Freeze();
            m.Freeze();
            return(new Tuple <Material, Media3D.Transform3D>(m, transform));
        }
        private VolumeTextureGradientParams ProcessData(byte[] data, int width, int height, int depth, out Color4[] transferMap)
        {
            uint[] histogram = new uint[256];

            float[] fdata = new float[data.Length];
            for (int i = 0; i < data.Length; ++i)
            {
                fdata[i] = (float)data[i] / byte.MaxValue;
                histogram[data[i]]++;
            }
            transferMap = GetTransferFunction(histogram, data.Length);
            var gradients = VolumeDataHelper.GenerateGradients(fdata, width, height, depth, 1);

            VolumeDataHelper.FilterNxNxN(gradients, width, height, depth, 3);
            return(new VolumeTextureGradientParams(gradients, width, height, depth));
        }