Unity中C#实现Mandelbrot集合可视化模糊问题求助
Mandelbrot集合可视化边缘模糊问题排查
我正在用UnityEngine和C#可视化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; } }
问题原因
迭代次数严重不足
你设置的iterations=10远低于需求。Mandelbrot集合的边缘需要足够迭代次数才能准确判断点是否逃逸,次数太少会导致大量本该区分的点被误判,直接造成边缘模糊。通常至少需要50-100次迭代才能得到清晰的边缘细节。纹理过滤模式错误
你把filterMode改成bilinear是反效果——双线性过滤会对相邻像素进行插值混合,反而加剧模糊。要得到清晰的像素边缘,必须设置为FilterMode.Point(点过滤),这样每个像素会直接显示原始计算颜色,没有插值模糊。逃逸边界不符合标准
你的upperbound=10是平方后的模长,而Mandelbrot集合的标准逃逸条件是模长大于2,对应平方后的模长是4。用10会让部分本该逃逸的点被多迭代,但不是边缘模糊的核心原因,不过修正后能更准确匹配集合定义。坐标映射精度损失
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
相关产品推荐
相关产品推荐

