0

0

c++如何实现一个简单的程序化生成(Procedural Generation)算法_c++柏林噪声应用【游戏开发】

冰火之心

冰火之心

发布时间:2025-12-08 09:53:02

|

391人浏览过

|

来源于php中文网

原创

柏林噪声是一种可重复、平滑连续、可缩放的伪随机函数,适合生成自然地形与纹理;其核心是通过哈希坐标获取梯度、双线性插值及fade函数实现平滑过渡,并支持fbm多层叠加模拟多尺度特征。

c++如何实现一个简单的程序化生成(procedural generation)算法_c++柏林噪声应用【游戏开发】

用 C++ 实现简单的程序化生成,核心是用柏林噪声(Perlin Noise)生成自然、连续、可重复的伪随机地形或纹理。它比纯随机数更“有机”,适合做地形高度图、云层、火焰、纹理扰动等。

一、先理解柏林噪声的关键特性

柏林噪声不是“随机”,而是:
- 可重复:相同坐标输入,永远返回相同浮点值(利于多线程或重载世界);
- 平滑连续:输出值在空间中渐变,没有突兀跳跃;
- 可缩放(octave 控制):通过叠加不同频率/振幅的噪声层(fbm),模拟山脉、小丘、岩石细节等多尺度特征。

二、手写一个轻量级 2D 柏林噪声(适合学习和小项目)

不依赖外部库,用经典 Ken Perlin 原始思路简化实现(非最高效,但逻辑清晰):

  • 定义一个 256 项的随机排列表(perm),用于哈希坐标 → 随机梯度方向;
  • 对每个整数格子角点预设一个单位梯度向量(如 (1,1), (-1,1) 等);
  • 对输入点 (x, y),找到它所在的单位格子(floor(x), floor(y));
  • 计算该点到四个角点的向量,并与对应梯度点乘,得到四个“影响值”;
  • 用平滑插值函数(如 3t²−2t³)混合这四个值,得到最终噪声值 ∈ [-1, 1]。

代码片段(精简版,含注释):

#include 
#include 
#include 

class SimplexNoise { // 注:这里用“SimplexNoise”名更准确,但初学可用 Perlin 思路理解 std::vector perm = { / 256 个 0~255 的 shuffle 后排列 / };

float fade(float t) { return t * t * t * (t * (t * 6 - 15) + 10); }
float lerp(float a, float b, float t) { return a + t * (b - a); }
float grad(int hash, float x, float y) {
    int h = hash & 3;
    float u = h zuojiankuohaophpcn 2 ? x : y;
    float v = h zuojiankuohaophpcn 2 ? y : x;
    return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
}

public: SimplexNoise() { std::vector p(256); for (int i = 0; i

float noise(float x, float y) const {
    int X = (int)floor(x) & 255;
    int Y = (int)floor(y) & 255;
    x -= floor(x); y -= floor(y);
    float u = fade(x), v = fade(y);

    int A = perm[X] + Y, AA = perm[A] & 255, AB = perm[A+1] & 255;
    int B = perm[X+1] + Y, BA = perm[B] & 255, BB = perm[B+1] & 255;

    float x1 = grad(perm[AA], x, y);
    float x2 = grad(perm[BA], x-1, y);
    float y1 = lerp(x1, x2, u);

    float x3 = grad(perm[AB], x, y-1);
    float x4 = grad(perm[BB], x-1, y-1);
    float y2 = lerp(x3, x4, u);

    return lerp(y1, y2, v);
}

// fbm:叠加多层噪声(octaves)
float fbm(float x, float y, int octaves = 4, float lacunarity = 2.0f, float persistence = 0.5f) const {
    float total = 0.0f;
    float frequency = 1.0f;
    float amplitude = 1.0f;
    float norm = 0.0f;
    float sum = 0.0f;

    for (int i = 0; i zuojiankuohaophpcn octaves; ++i) {
        sum += noise(x * frequency, y * frequency) * amplitude;
        norm += amplitude;
        amplitude *= persistence;
        frequency *= lacunarity;
    }
    return sum / norm;
}

};

AI发型设计
AI发型设计

虚拟发型试穿工具和发型模拟器

下载

立即学习C++免费学习笔记(深入)”;

三、生成地形高度图(2D 数组示例)

用 fbm 填充一个 128×128 的 heightmap:

  • 遍历每个 (i, j),映射为世界坐标(如 i*0.05f, j*0.05f);
  • 调用 fbm(x, y),结果归一化到 [0.0, 1.0] 或 [-0.5, 0.5];
  • 可加偏移/缩放控制山峰高度,例如:height[i][j] = (fbm(i*0.03f,j*0.03f) + 0.7f) * 0.5f;
  • 后续可按高度阈值划分:0.6→岩石/雪地。

四、实用技巧 & 注意事项

  • 种子控制:把 perm 表的 shuffle 种子(如 default_random_engine(1234))换成可配置参数,就能切换不同世界;
  • 性能优化:实际项目建议用开源库如 webgl-noise 的 C++ 移植版stegu/perlin-noise,支持 SIMD 和 3D/4D;
  • 避免“网格感”:确保采样间距远小于噪声基频(比如用 0.01–0.05 缩放因子),否则会看到明显方块;
  • 结合其他技术:噪声输出可作为 mask 输入到 Voronoi、Worley 噪声,或驱动 Marching Squares 生成等高线。

基本上就这些。从一个可运行的 fbm 函数开始,再叠加规则(如河流侵蚀、生物群系分布),就能搭建出有表现力的程序化世界。不复杂但容易忽略的是——噪声只是“原料”,真正让生成有意义的,是你怎么解释和组合它。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

318

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

538

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

52

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

197

2025.08.29

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

481

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

143

2025.12.24

页面置换算法
页面置换算法

页面置换算法是操作系统中用来决定在内存中哪些页面应该被换出以便为新的页面提供空间的算法。本专题为大家提供页面置换算法的相关文章,大家可以免费体验。

402

2023.08.14

PHP 高并发与性能优化
PHP 高并发与性能优化

本专题聚焦 PHP 在高并发场景下的性能优化与系统调优,内容涵盖 Nginx 与 PHP-FPM 优化、Opcode 缓存、Redis/Memcached 应用、异步任务队列、数据库优化、代码性能分析与瓶颈排查。通过实战案例(如高并发接口优化、缓存系统设计、秒杀活动实现),帮助学习者掌握 构建高性能PHP后端系统的核心能力。

98

2025.10.16

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

43

2026.01.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 6.9万人学习

C 教程
C 教程

共75课时 | 4.1万人学习

C++教程
C++教程

共115课时 | 12.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号