You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity中从Texture2D生成Mesh时的地形边界异常问题排查

程序化地形纹理采样边界异常排查

之前直接在Mesh创建过程中采样噪声函数,已成功生成可拼接的噪声地形网格(正常瓦片效果:地形连续无边界断层)。但调整为先生成噪声纹理、再采样纹理高度值生成Mesh(纹理可后续复用)后,Mesh整体效果基本一致,但边界出现严重异常(边界处地形断层/高度突变)。

已尝试以下操作,暂未解决问题:

  • 修改TextureFormat、WrapMode、FilterMode
  • 为纹理添加边界空间以避免采样边缘像素
  • 确认噪声纹理本身分布正常(示例纹理显示噪声过渡自然,无边界异常)

两种方案的Mesh生成流程完全一致,仅噪声数据采样逻辑不同,且已确认未采样纹理范围外的点。

纹理生成代码

public static Texture2D GenerateNoiseTexture(Vector3 position, Vector2Int size, NoiseSettings settings, int step = 1)
{
    Texture2D texture = new Texture2D(size.x, size.y, TextureFormat.RGBAFloat, false, false);
    texture.wrapMode = TextureWrapMode.Clamp;
    texture.filterMode = FilterMode.Point;

    for (int z = 0; z < size.y; z += step) {
        for (int x = 0; x < size.x; x += step) {
            Vector3 mapPos = position + new Vector3(x, settings.seed, z);
            Vector3 sample = (mapPos + settings.offset) / settings.scale;
            float n = Noise.Evaluate(sample, settings);
            texture.SetPixel(x, z, new Color(n, 0, 0, 0), 0);
        }
    }

    texture.Apply();
    return texture;
}

Mesh采样代码对比

// 正常生效的代码:直接采样噪声
float y1 = Noise.Evaluate((new Vector3(x, settings.seed, z) + settings.offset) / settings.scale, settings) * heightMultiplier; 

// 导致边界异常的代码:采样纹理
float y1 = texture.GetPixel(x, z, 0).r * heightMultiplier;

排查思路与尝试方向

  • 坐标映射偏移检查:确认Mesh顶点的x/z范围与纹理的size是否完全匹配。例如Mesh顶点数若为(size.x+1)×(size.y+1),则边界顶点的x/z会超出纹理的0~size.x-1/0~size.y-1范围,导致采样错误。
  • 纹理坐标原点验证:Unity中Texture2D的SetPixel/GetPixel的y轴是从下到上的,若Mesh生成时z轴是从上到下遍历,会导致边界行的采样坐标颠倒,出现高度错位。可尝试将纹理采样的y坐标改为texture.height - 1 - z,看是否修复问题。
  • step参数影响排查:若GenerateNoiseTexture的step参数不为1,纹理仅生成间隔step的像素,未填充的像素会保留默认值(如0),Mesh采样时若遍历所有x/z,会导致非step位置的高度错误。需确保step=1,或Mesh采样时同步使用step间隔。
  • 像素值一致性验证:编写调试代码,对比相同x/z下,Noise.Evaluate的结果与texture.GetPixel(x,z).r的结果,重点检查边界点(x=0、x=size.x-1、z=0、z=size.y-1),看是否存在数值偏差。
  • 纹理精度与Apply参数检查:显式调用texture.Apply(false, false),关闭mipmap更新(避免Point过滤下的mipmap干扰),同时确保纹理未被标记为不可读。另外,可尝试改用TextureFormat.RFloat单通道格式,减少精度损失。
  • GetPixel坐标范围确认:严格确保采样时的x/z满足0 ≤ x < texture.width、0 ≤ z < texture.height,Unity的GetPixel对超出范围的坐标会返回Color.clear(r=0),这会导致边界高度突变。

内容的提问来源于stack exchange,提问作者M31

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 00:06:06