gpt4 book ai didi

c# - 从纹理创建法线贴图背后的逻辑是什么?

转载 作者:行者123 更新时间:2023-11-30 17:12:26 24 4
gpt4 key购买 nike

我在 google 上看过,但我唯一能找到的是关于如何使用 photoshop 创建一个的教程。不感兴趣!我需要它背后的逻辑。(而且我不需要如何“使用”凹凸贴图的逻辑,我想知道如何“制作”凹凸贴图!)

我正在编写我自己的 HLSL 着色器,并且已经意识到两个像素之间存在某种渐变,这将显示其正常 - 因此可以相应地照亮光的位置。

我想实时执行此操作,这样当纹理发生变化时,凹凸贴图也会发生变化。

谢谢

最佳答案

我意识到我来晚了,但我最近在尝试为 3ds max 编写自己的法线贴图生成器时也遇到了同样的情况。有庞大且不必要的 C# 库,但没有任何东西妨碍基于数学的简单解决方案。

所以我使用转换背后的数学运算:Sobel 运算符。这就是您希望在着色器脚本中使用的内容。

以下类是我见过的最简单的 C# 实现。它做的正是它应该做的,并完全实现了所期望的:基于高度图、纹理甚至您提供的以编程方式生成的程序的法线贴图。

正如您在代码中看到的那样,我已经实现了 if/else 以减少在边缘检测宽度和高度限制时引发的异常。

它的作用:对每个像素/相邻像素的 HSB 亮度进行采样,以确定输出色调/饱和度值的比例,这些值随后会转换为 RGB 以用于 SetPixel 操作。

顺便说一句:您可以实现一个输入控件来缩放输出色相/饱和度值的强度,以缩放输出法线贴图将提供您的几何/照明的后续影响。

就是这样。无需再处理已弃用的小窗口 PhotoShop 插件。天空是极限。

C# winforms 实现的屏幕截图(源/输出):

enter image description here

C# 类从源图像实现基于 Sobel 的法线贴图:

using System.Drawing;
using System.Windows.Forms;

namespace heightmap.Class
{
class Normal
{
public void calculate(Bitmap image, PictureBox pic_normal)
{
Bitmap image = (Bitmap) Bitmap.FromFile(@"yourpath/yourimage.jpg");
#region Global Variables
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);
#endregion
for (int y = 0; y < w + 1; y++)
{
for (int x = 0; x < h + 1; 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);
}
}
pic_normal.Image = normal; // set as PictureBox image
}
}
}

关于c# - 从纹理创建法线贴图背后的逻辑是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10652797/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com