Exemple #1
0
        /// <summary>
        /// Converts a bump map to a normal map.
        /// </summary>
        /// <param name="bitmap">Source bump map image.</param>
        /// <param name="strength">Normal strength.</param>
        /// <returns>DFBitmap normal image.</returns>
        public static DFBitmap ConvertBumpToNormals(DFBitmap bitmap, float strength = 1)
        {
            // Must be a colour format
            if (bitmap.Format == DFBitmap.Formats.Indexed)
            {
                return(null);
            }

            DFBitmap newBitmap = new DFBitmap(bitmap.Width, bitmap.Height);

            newBitmap.Format = bitmap.Format;
            newBitmap.Initialise(bitmap.Width, bitmap.Height);

            for (int y = 0; y < bitmap.Height; y++)
            {
                for (int x = 0; x < bitmap.Width; x++)
                {
                    // Look up the heights to either side of this pixel
                    float left   = GetIntensity(bitmap, x - 1, y);
                    float right  = GetIntensity(bitmap, x + 1, y);
                    float top    = GetIntensity(bitmap, x, y - 1);
                    float bottom = GetIntensity(bitmap, x, y + 1);

                    // Compute gradient vectors, then cross them to get the normal
                    Vector3 dx     = new Vector3(1, 0, (right - left) * strength);
                    Vector3 dy     = new Vector3(0, 1, (bottom - top) * strength);
                    Vector3 normal = Vector3.Cross(dx, dy);
                    normal.Normalize();

                    // Store result
                    int pos = y * bitmap.Stride + x * bitmap.FormatWidth;
                    newBitmap.Data[pos + 0] = (byte)((normal.x + 1.0f) * 127.5f);
                    newBitmap.Data[pos + 1] = (byte)((normal.y + 1.0f) * 127.5f);
                    newBitmap.Data[pos + 2] = (byte)((normal.z + 1.0f) * 127.5f);
                    newBitmap.Data[pos + 3] = 0xff;
                }
            }

            return(newBitmap);
        }
Exemple #2
0
        /// <summary>
        /// Creates average intensity bitmap.
        /// </summary>
        /// <param name="bitmap">Source DFBitmap.</param>
        /// <returns>Average intensity DFBitmap.</returns>
        public static DFBitmap MakeAverageIntensityBitmap(DFBitmap bitmap)
        {
            // Must be a colour format
            if (bitmap.Format == DFBitmap.Formats.Indexed)
            {
                return(null);
            }

            DFBitmap newBitmap = new DFBitmap();

            newBitmap.Format = bitmap.Format;
            newBitmap.Initialise(bitmap.Width, bitmap.Height);

            // Make each pixel grayscale based on average intensity
            int srcPos = 0, dstPos = 0;

            for (int i = 0; i < bitmap.Width * bitmap.Height; i++)
            {
                // Get source color
                byte r = bitmap.Data[srcPos++];
                byte g = bitmap.Data[srcPos++];
                byte b = bitmap.Data[srcPos++];
                byte a = bitmap.Data[srcPos++];

                // Get average intensity
                int intensity             = (r + g + b) / 3;
                DFBitmap.DFColor dstColor = DFBitmap.DFColor.FromRGBA((byte)intensity, (byte)intensity, (byte)intensity, a);

                // Write destination pixel
                newBitmap.Data[dstPos++] = dstColor.r;
                newBitmap.Data[dstPos++] = dstColor.g;
                newBitmap.Data[dstPos++] = dstColor.b;
                newBitmap.Data[dstPos++] = dstColor.a;
            }

            return(newBitmap);
        }
Exemple #3
0
        /// <summary>
        /// Creates a grayscale version of bitmap based on colour theory.
        /// </summary>
        /// <param name="bitmap">Source DFBitmap.</param>
        /// <returns>Grayscale DFBitmap image.</returns>
        public static DFBitmap MakeGrayscale(DFBitmap bitmap)
        {
            // Must be a colour format
            if (bitmap.Format == DFBitmap.Formats.Indexed)
            {
                return(null);
            }

            DFBitmap newBitmap = new DFBitmap();

            newBitmap.Format = bitmap.Format;
            newBitmap.Initialise(bitmap.Width, bitmap.Height);

            // Make each pixel grayscale
            int srcPos = 0, dstPos = 0;

            for (int i = 0; i < bitmap.Width * bitmap.Height; i++)
            {
                // Get source color
                byte r = bitmap.Data[srcPos++];
                byte g = bitmap.Data[srcPos++];
                byte b = bitmap.Data[srcPos++];
                byte a = bitmap.Data[srcPos++];

                // Create grayscale color
                int grayscale             = (int)(r * 0.3f + g * 0.59f + b * 0.11f);
                DFBitmap.DFColor dstColor = DFBitmap.DFColor.FromRGBA((byte)grayscale, (byte)grayscale, (byte)grayscale, a);

                // Write destination pixel
                newBitmap.Data[dstPos++] = dstColor.r;
                newBitmap.Data[dstPos++] = dstColor.g;
                newBitmap.Data[dstPos++] = dstColor.b;
                newBitmap.Data[dstPos++] = dstColor.a;
            }

            return(newBitmap);
        }
Exemple #4
0
        /// <summary>
        /// Gets a bump map from the source DFBitmap.
        /// </summary>
        /// <param name="bitmap">Source colour image.</param>
        /// <returns>DFBitmap bump image.</returns>
        public static DFBitmap GetBumpMap(DFBitmap bitmap)
        {
            // Must be a colour format
            if (bitmap.Format == DFBitmap.Formats.Indexed)
            {
                return(null);
            }

            // Create horizontal sobel matrix
            Filter horizontalMatrix = new Filter(3, 3);

            horizontalMatrix.MyFilter[0, 0] = -1;
            horizontalMatrix.MyFilter[1, 0] = 0;
            horizontalMatrix.MyFilter[2, 0] = 1;
            horizontalMatrix.MyFilter[0, 1] = -2;
            horizontalMatrix.MyFilter[1, 1] = 0;
            horizontalMatrix.MyFilter[2, 1] = 2;
            horizontalMatrix.MyFilter[0, 2] = -1;
            horizontalMatrix.MyFilter[1, 2] = 0;
            horizontalMatrix.MyFilter[2, 2] = 1;

            // Create vertical sobel matrix
            Filter verticalMatrix = new Filter(3, 3);

            verticalMatrix.MyFilter[0, 0] = 1;
            verticalMatrix.MyFilter[1, 0] = 2;
            verticalMatrix.MyFilter[2, 0] = 1;
            verticalMatrix.MyFilter[0, 1] = 0;
            verticalMatrix.MyFilter[1, 1] = 0;
            verticalMatrix.MyFilter[2, 1] = 0;
            verticalMatrix.MyFilter[0, 2] = -1;
            verticalMatrix.MyFilter[1, 2] = -2;
            verticalMatrix.MyFilter[2, 2] = -1;

            // Get filtered images
            DFBitmap horz = MakeAverageIntensityBitmap(horizontalMatrix.ApplyFilter(bitmap));
            DFBitmap vert = MakeAverageIntensityBitmap(verticalMatrix.ApplyFilter(bitmap));

            // Create target bitmap
            DFBitmap result = new DFBitmap();

            result.Format = bitmap.Format;
            result.Initialise(horz.Width, horz.Height);

            // Merge
            int pos = 0;

            for (int i = 0; i < bitmap.Width * bitmap.Height; i++)
            {
                // Merge average intensity
                int r = (horz.Data[pos + 0] + vert.Data[pos + 0]) / 2;
                int g = (horz.Data[pos + 1] + vert.Data[pos + 1]) / 2;
                int b = (horz.Data[pos + 2] + vert.Data[pos + 2]) / 2;

                // Write destination pixel
                result.Data[pos + 0] = (byte)((r > 255) ? 255 : r);
                result.Data[pos + 1] = (byte)((g > 255) ? 255 : g);
                result.Data[pos + 2] = (byte)((b > 255) ? 255 : b);
                result.Data[pos + 3] = 255;

                pos += bitmap.FormatWidth;
            }

            return(result);
        }