- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在尝试用 C++ 实现 Perlin Noise。
首先,问题(我认为)是输出不是我所期望的。目前我只是在灰度图像中使用生成的 Perlin 噪声值,这是我得到的结果:
也就是说,我目前产生的噪音似乎更符合“标准”不规则噪音。
这是我目前已经实现的 Perlin 噪声算法:
float perlinNoise2D(float x, float y)
{
// Find grid cell coordinates
int x0 = (x > 0.0f ? static_cast<int>(x) : (static_cast<int>(x) - 1));
int x1 = x0 + 1;
int y0 = (y > 0.0f ? static_cast<int>(y) : (static_cast<int>(y) - 1));
int y1 = y0 + 1;
float s = calculateInfluence(x0, y0, x, y);
float t = calculateInfluence(x1, y0, x, y);
float u = calculateInfluence(x0, y1, x, y);
float v = calculateInfluence(x1, y1, x, y);
// Local position in the grid cell
float localPosX = 3 * ((x - (float)x0) * (x - (float)x0)) - 2 * ((x - (float)x0) * (x - (float)x0) * (x - (float)x0));
float localPosY = 3 * ((y - (float)y0) * (y - (float)y0)) - 2 * ((y - (float)y0) * (y - (float)y0) * (y - (float)y0));
float a = s + localPosX * (t - s);
float b = u + localPosX * (v - u);
return lerp(a, b, localPosY);
}
calculateInfluence 函数负责为当前网格单元的角点之一生成随机梯度 vector 和距离 vector ,并返回它们的点积。它被实现为:
float calculateInfluence(int xGrid, int yGrid, float x, float y)
{
// Calculate gradient vector
float gradientXComponent = dist(rdEngine);
float gradientYComponent = dist(rdEngine);
// Normalize gradient vector
float magnitude = sqrt( pow(gradientXComponent, 2) + pow(gradientYComponent, 2) );
gradientXComponent = gradientXComponent / magnitude;
gradientYComponent = gradientYComponent / magnitude;
magnitude = sqrt(pow(gradientXComponent, 2) + pow(gradientYComponent, 2));
// Calculate distance vectors
float dx = x - (float)xGrid;
float dy = y - (float)yGrid;
// Compute dot product
return (dx * gradientXComponent + dy * gradientYComponent);
}
这里,dist 是来自 C++11 的随机数生成器:
std::mt19937 rdEngine(1);
std::normal_distribution<float> dist(0.0f, 1.0f);
lerp 简单地实现为:
float lerp(float v0, float v1, float t)
{
return ( 1.0f - t ) * v0 + t * v1;
}
为了实现该算法,我主要使用了以下两个资源:
Perlin Noise FAQ Perlin Noise Pseudo Code
我很难准确指出我似乎搞砸了的地方。可能是我错误地生成了梯度 vector ,因为我不太确定它们应该具有哪种类型的分布。我尝试过均匀分布,但这似乎会在纹理中产生重复的图案!
同样,可能是我错误地平均了影响值。从 Perlin Noise FAQ 文章中很难准确地辨别应该如何完成。
有人对代码可能有什么问题有任何提示吗? :)
最佳答案
您似乎只生成了一个 Octave 的柏林噪声。要获得如图所示的结果,您需要生成 multiple octaves并将它们加在一起。在一系列 Octave 音程中,每个 Octave 音程的网格单元大小应是最后一个 Octave 音程的两倍。
要生成多倍频程噪声,请使用与此类似的东西:
float multiOctavePerlinNoise2D(float x, float y, int octaves)
{
float v = 0.0f;
float scale = 1.0f;
float weight = 1.0f;
float weightTotal = 0.0f;
for(int i = 0; i < octaves; i++)
{
v += perlinNoise2D(x * scale, y * scale) * weight;
weightTotal += weight;
// "ever-increasing frequencies and ever-decreasing amplitudes"
// (or conversely decreasing freqs and increasing amplitudes)
scale *= 0.5f;
weight *= 2.0f;
}
return v / weightTotal;
}
为了获得额外的随机性,您可以为每个 Octave 音程使用不同种子的随机生成器。此外,可以改变赋予每个 Octave 音阶的权重,以调整噪声的美学质量。如果每次迭代都不调整权重变量,那么上面的例子就是"pink noise" (每次频率加倍都具有相同的权重)。
此外,您需要使用随机数生成器,每次为给定的 xGrid、yGrid 对返回相同的值。
关于c++ - Perlin Noise 算法似乎不会产生梯度噪声,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37508938/
关闭。这个问题不符合 Stack Overflow guidelines 。它目前不接受答案。 想改进这个问题?更新问题,使其成为 Stack Overflow 的 on-topic。 5年前关闭。
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
我正在尝试使3D Perlin噪声算法适应较低的尺寸,但是由于我不完全了解其原因,我在使用梯度函数时遇到了麻烦。 原始的Perlin梯度函数采用四个参数:hash和三维坐标(x, y, z)。该函数的
我想为音频文件添加噪音。有没有办法在 SoX(或其他工具)中实现这一点? 我正在进行机器学习研究,需要在存在噪声的情况下测试我的算法。理想情况下,我想指定一个信噪比并添加噪声以达到该目标 SNR。 我
关闭。这个问题是off-topic .它目前不接受答案。 想改善这个问题吗? Update the question所以它是 on-topic对于堆栈溢出。 8年前关闭。 Improve this q
我正在编写以字符串形式接收数据段的代码。该字符串的大小不同,但始终以相同的字符开头和结尾( start: '' )。我想防止用户在段开始和结束之前输入无效字符时出错。例如 "fdslkjds" "df
我正在尝试寻找一种无需借助宏即可减少语法“噪音”的方法。对于以下代码: struct base { base() = delete; }; struct tag1 final : private
我正在 C# winforms 项目中使用“不安全”代码创建(然后更改)位图。每 30 毫秒左右执行一次。我遇到的问题是“噪音”或随机像素有时会出现在生成的位图中,而我没有特别更改任何内容。 例如,我
我的任务似乎是琐碎的 找出给定录音的“噪音”。 录音是通过录音机, OLYMPUS VN-733 PC相当便宜(我没有在做 广告,我只提到这一点,因为我绝不 打算在这里做任何“专业”的事情,我只需要
如何使用 MatLab 计算信噪比? 更新 我只有一个文件,而不是示例中的两个,它是一个 .tif。 最佳答案 Matlab SNR 的第一个 Google 结果.从那里复制,以 dB 为单位: sn
我想使用 Perlin Noise 创建一个 2D float 列表。我希望每次运行程序时生成的值都不同。但是,我不确定如何为我在 GitHub here 上找到的噪声库提供随机种子。 . 如何让程序
我正在准备一个文本文件语料库,其中包含 170 部荷兰小说。我是一名文学学者,对 Python 以及一般编程也比较陌生。我想做的是编写一个 Python 脚本,用于删除每个 .txt 文件中不属于小说
上周我正在开发一个世界生成器(用于 Minecraft 模组)。但是,我不只是在寻找 Perlin 噪声,而是在寻找基于细胞噪声的东西。我想生成一种地下实验室,存在几个不同大小的房间。 为了解释这个问
我已经实现了 native Android SIP solution在我的 Android 应用中。 SipProfile.Builder builder = new SipProfile.Build
我正在尝试用 C++ 实现 Perlin Noise。 首先,问题(我认为)是输出不是我所期望的。目前我只是在灰度图像中使用生成的 Perlin 噪声值,这是我得到的结果: 但是,根据我的理解,它应该
我正在寻找一种算法(或其他技术)来阅读网站上新闻文章的实际内容并忽略页面上的任何其他内容。简而言之,我正在以编程方式从 Google 新闻阅读 RSS 提要。我有兴趣抓取基础文章的实际内容。在我的第一
当我使用 valgrind 帮助调试我正在开发的应用程序时,我注意到大量噪音似乎是在提示标准库。作为测试,我这样做了; echo 'int main() {return 0;}' | gcc -x c
我知道什么是柏林噪音(我写了一些代码来生成它)。 我认为分形噪声是按比例缩放并求和的 Perlin 噪声,对吗? 我有时会在同一篇文章中看到湍流噪声和柏林噪声,但随后这篇文章只讨论了柏林噪声。它们有什
有没有详细介绍 Perlin 噪声生成的好资源?我知道大多数语言都有可用的噪声生成库,但我有兴趣创建自己的库以获取乐趣/体验。我已经看过this ,这看起来很流行,但它只给出了一维噪声的深入解释。到目
许多 Perlin Noise 教程和实现( here 、 here 、 here 等)使用函数来生成如下伪随机值: function Noise(integer x, integer y)
我是一名优秀的程序员,十分优秀!