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

Unity中C#实现Mandelbrot集合可视化模糊问题求助

Mandelbrot集合可视化边缘模糊问题排查

我正在用UnityEngine和C#可视化Mandelbrot集合,目前效果没有根本性错误,但不符合预期——比如圆形图形边缘非常模糊。请问这是什么原因?

Mandelbrot可视化效果

使用的参数

  • iterations: 10
  • upperBound: 10
  • width: 800
  • height: 450
  • Texture2D设置:filterMode改为bilinear(试图消除模糊)

核心代码

计算逻辑代码

public void CalcValues(int iterations)
{
    for (int i = 0; i < width; i++)
    {
        for (int j = 0; j < height; j++)
        {
            C c = new C(mapWidthDefault(width - i - 1), mapHeightDefault(j));

            C z = new C(0, 0);

            for (int k = 0; k < iterations; k++)
            {
                z = z * z + c;
                if (z.abs > upperbound)
                {
                    pixels[i + j * width] = Color.white;
                    goto end;
                }
            }
            pixels[i + j * width] = Color.black;
            // Debug.Log(c + ",   " + z + " " + z.abs);
            end:;
        }
    }
    texture.SetPixels(pixels);
    texture.Apply();
}

private float mapWidthDefault(float x)
{
    return map(x, 0, width, -3.516f, 1.516f);
}

private float mapHeightDefault(float x)
{
    return map(x, 0, height, -1.5f, 1.5f);
}

private float map(float x, float a1, float a2, float b1, float b2)
{
    return (x - a1) * (b2 - b1) / (a2 - a1) + b1;
}

复数类C代码

public class C
{
    public readonly double Re;
    public readonly double Im;
    public readonly double abs;

    public C(double real, double imaginary)
    {
        this.Re = real;
        this.Im = imaginary;
        this.abs = Re * Re + Im * Im; // 平方后的模长
    }

    public static C operator +(C c1, C c2)
    {
        return new C(c1.Re + c2.Re, c1.Im + c2.Im);
    }

    public static C operator *(C c1, C c2)
    {
        return new C(c1.Re * c2.Re - c1.Im * c2.Im,
            c1.Re * c2.Im + c1.Im * c2.Re);
    }

    public override bool Equals(object obj)
    {
        if (!(obj is C))
            return false;
        return ((C)obj).Re == Re && ((C)obj).Im == Im;
    }
}

问题原因

  1. 迭代次数严重不足
    你设置的iterations=10远低于需求。Mandelbrot集合的边缘需要足够迭代次数才能准确判断点是否逃逸,次数太少会导致大量本该区分的点被误判,直接造成边缘模糊。通常至少需要50-100次迭代才能得到清晰的边缘细节。

  2. 纹理过滤模式错误
    你把filterMode改成bilinear是反效果——双线性过滤会对相邻像素进行插值混合,反而加剧模糊。要得到清晰的像素边缘,必须设置为FilterMode.Point(点过滤),这样每个像素会直接显示原始计算颜色,没有插值模糊。

  3. 逃逸边界不符合标准
    你的upperbound=10是平方后的模长,而Mandelbrot集合的标准逃逸条件是模长大于2,对应平方后的模长是4。用10会让部分本该逃逸的点被多迭代,但不是边缘模糊的核心原因,不过修正后能更准确匹配集合定义。

  4. 坐标映射精度损失
    map函数使用float类型,而复数类C用的是double。float的精度有限,在坐标映射时会产生微小误差,虽然当前分辨率下影响不大,但会累积导致边缘细节丢失。改用double能避免精度损失。

修改建议

  • 提升迭代次数:将iterations调整为50-100,比如设置为100,测试边缘清晰度的变化。
  • 修正纹理过滤模式:在代码中添加texture.filterMode = FilterMode.Point;,或者在Inspector面板将纹理的Filter Mode改为Point。
  • 调整逃逸边界:把upperbound改为4,符合标准的Mandelbrot逃逸条件。
  • 优化坐标映射精度:修改map函数的参数和返回值为double类型:
private double mapWidthDefault(double x)
{
    return map(x, 0, width, -3.516, 1.516);
}

private double mapHeightDefault(double x)
{
    return map(x, 0, height, -1.5, 1.5);
}

private double map(double x, double a1, double a2, double b1, double b2)
{
    return (x - a1) * (b2 - b1) / (a2 - a1) + b1;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 17:05:38