基于arcsin函数的三维地形生成算法:从数学原理到工程实践

1次阅读
没有评论

共计 1605 个字符,预计需要花费 5 分钟才能阅读完成。

image.webp

背景痛点

在三维地形生成领域,Perlin 噪声和 Simplex 噪声长期占据主导地位,但它们存在几个显著缺陷:

基于 arcsin 函数的三维地形生成算法:从数学原理到工程实践

  • 形态单一性:Perlin 噪声生成的丘陵结构具有相似的特征尺度,难以同时表现悬崖峭壁和平缓地带
  • 参数耦合 :缩放(scale) 参数同时影响地形起伏幅度和细节频率,调整时需反复试验
  • 性能瓶颈:高频噪声需要多层叠加(octaves),在移动端易造成帧率下降
  • 可控性差:缺乏直接控制地形陡峭度的数学手段

数学原理

arcsin 函数在区间 [-1,1] 内呈现线性与非线性结合的独特特性:

  1. 基础曲线分析(图 1 示意):
  2. 在 x = 0 附近近似线性,对应平缓地形
  3. 在 x =±1 处导数趋近无穷,模拟悬崖突变

  4. 参数化控制

  5. 振幅(amplitude):决定地形最大高度差
  6. 频率(frequency):控制特征尺度分布
  7. 相位偏移(phase shift):实现地形板块位移

  8. 复合函数构造

    height = ∑[a_i * arcsin(sin(π * f_i * (x + p_i)))] / ∑a_i

    其中 i 表示不同频率分量

核心实现

高度场生成 HLSL 代码

// 输入:uv - 地形 UV 坐标 [0,1]^2
// 输出:height - 归一化高度值 [0,1]
float ArcsinTerrain(float2 uv, float amplitude, float frequency) {// 将输入映射到 [-1,1] 区间
    float x = 2.0 * uv.x - 1.0;

    // 基础 arcsin 高度计算
    float h = amplitude * asin(clamp(x, -1, 1)); 

    // 输出映射到 [0,1] 区间
    return h * 0.5 + 0.5; 
}

多图层混合策略

float3 BlendLayers(float2 uv) {
    // 低频基础地形(宏观起伏)float base = ArcsinTerrain(uv, 1.0, 0.2);

    // 中频细节(岩石结构)float mid = ArcsinTerrain(uv * 5.0, 0.3, 1.0);

    // 高频噪声(表面纹理)float high = ArcsinTerrain(uv * 20.0, 0.1, 5.0);

    // 加权混合
    return base * 0.6 + mid * 0.3 + high * 0.1;
}

性能优化

方法 PC 端帧率 移动端帧率
实时计算 120 FPS 28 FPS
预计算 +FFT 144 FPS 45 FPS
LOD 分级(4 级) 135 FPS 52 FPS

移动端适配建议
1. 对远距离地形使用低频率分量
2. 启用 GPU Instancing 减少 Draw Call
3. 采用 Compute Shader 异步计算

避坑指南

定义域保护

// 错误示例:直接计算 asin(x)可能越界
float h = asin(x); 

// 正确做法:强制约束定义域
float h = asin(clamp(x, -0.999, 0.999));

UV 接缝处理

  • 对 UV 边界进行平滑过渡:
    uv = frac(uv) * 0.98 + 0.01;
  • 使用三线性滤波减少接缝可见性

法线计算优化

采用中心差分替代解析求导:

float3 CalculateNormal(float2 uv, float eps) {float hL = HeightAt(uv - float2(eps, 0));
    float hR = HeightAt(uv + float2(eps, 0));
    float hD = HeightAt(uv - float2(0, eps));
    float hU = HeightAt(uv + float2(0, eps));

    return normalize(float3(hL-hR, 2.0*eps, hD-hU));
}

延伸思考

结合符号距离场 (SDF) 实现洞穴系统:
1. 将 arcsin 地形作为 SDF 的输入场
2. 用布尔运算叠加洞穴空间:

float cave = min(terrainSDF, -caveSDF);

3. Marching Cubes 可视化验证:
– 设置等值面阈值 0.5
– 检查生成的网格拓扑连续性

验证指标
– 洞穴厚度需大于角色碰撞体直径
– 地表与洞穴的法线过渡平滑度
– 光照烘焙后的 AO 效果评估

正文完
 0
评论(没有评论)