【问题标题】:Looking for more efficient Normal Map generation using System.Drawing使用 System.Drawing 寻找更高效的法线贴图生成
【发布时间】:2023-02-19 23:52:16
【问题描述】:

我目前正在开发一种工具,如果用户没有自己的法线贴图可以使用,它会自动为用户生成法线贴图。这主要基于漫反射纹理。

我能够从另一篇文章 here 找到解决方案,虽然它按预期工作,但其编写方式并不是最有效的。

我研究了 Color Matrix 和 Bitmap LockBits,但不太明白我将如何使用这些解决方案 1:1 转换此逻辑以提高性能。不幸的是,像素数学不是我在这里最强的技能。

据我所知,当前的解决方案使用 Sobel 算法来生成法线。

        public static Bitmap Calculate(string file) {
            using (Bitmap image = (Bitmap)Bitmap.FromFile(file)) {
                int w = image.Width - 1;
                int h = image.Height - 1;
                float sample_l;
                float sample_r;
                float sample_u;
                float sample_d;
                float x_vector;
                float y_vector;
                Bitmap normal = new Bitmap(image.Width, image.Height);
                for (int y = 0; y < h; y++) {
                    for (int x = 0; x < w; x++) {
                        if (x > 0) {
                            sample_l = image.GetPixel(x - 1, y).GetBrightness();
                        } else {
                            sample_l = image.GetPixel(x, y).GetBrightness();
                        }
                        if (x < w) {
                            sample_r = image.GetPixel(x + 1, y).GetBrightness();
                        } else {
                            sample_r = image.GetPixel(x, y).GetBrightness();
                        }
                        if (y > 1) {
                            sample_u = image.GetPixel(x, y - 1).GetBrightness();
                        } else {
                            sample_u = image.GetPixel(x, y).GetBrightness();
                        }
                        if (y < h) {
                            sample_d = image.GetPixel(x, y + 1).GetBrightness();
                        } else {
                            sample_d = image.GetPixel(x, y).GetBrightness();
                        }
                        x_vector = (((sample_l - sample_r) + 1) * .5f) * 255;
                        y_vector = (((sample_u - sample_d) + 1) * .5f) * 255;
                        Color col = Color.FromArgb(255, (int)x_vector, (int)y_vector, 255);
                        normal.SetPixel(x, y, col);
                    }
                }
                return normal;
            }
        }

我主要是想找到这个算法的一个版本,它是用 Color Matrix 或 Bitmap LockBits 编写的。

该算法按预期工作,但需要更高效。

【问题讨论】:

    标签: bitmap textures


    【解决方案1】:

    最终找到了 this 类,它允许我保持代码大部分不变,同时仍然能够让代码运行得更快。

            public static Bitmap Calculate(string file) {
            using (Bitmap image = (Bitmap)Bitmap.FromFile(file)) {
                int w = image.Width - 1;
                int h = image.Height - 1;
                float sample_l;
                float sample_r;
                float sample_u;
                float sample_d;
                float x_vector;
                float y_vector;
                Bitmap normal = new Bitmap(image.Width, image.Height);
                LockBitmap source = new LockBitmap(image);
                LockBitmap destination = new LockBitmap(normal);
                source.LockBits();
                destination.LockBits();
                for (int y = 0; y < h; y++) {
                    for (int x = 0; x < w; x++) {
                        if (x > 0) {
                            sample_l = source.GetPixel(x - 1, y).GetBrightness();
                        } else {
                            sample_l = source.GetPixel(x, y).GetBrightness();
                        }
                        if (x < w) {
                            sample_r = source.GetPixel(x + 1, y).GetBrightness();
                        } else {
                            sample_r = source.GetPixel(x, y).GetBrightness();
                        }
                        if (y > 1) {
                            sample_u = source.GetPixel(x, y - 1).GetBrightness();
                        } else {
                            sample_u = source.GetPixel(x, y).GetBrightness();
                        }
                        if (y < h) {
                            sample_d = source.GetPixel(x, y + 1).GetBrightness();
                        } else {
                            sample_d = source.GetPixel(x, y).GetBrightness();
                        }
                        x_vector = (((sample_l - sample_r) + 1) * .5f) * 255;
                        y_vector = (((sample_u - sample_d) + 1) * .5f) * 255;
                        Color col = Color.FromArgb(255, (int)x_vector, (int)y_vector, 255);
                        destination.SetPixel(x, y, col);
                    }
                }
                destination.UnlockBits();
                source.UnlockBits();
                return normal;
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-11
      • 2012-04-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-03
      • 2022-12-24
      • 1970-01-01
      相关资源
      最近更新 更多