8

我正在尝试使用该trimesh函数在 Matlab 中绘制一个大网格,顶点的 z 坐标控制颜色。不幸的是,当网格的大小超过 120 个三角形时,Matlab 会停止正确插值颜色。这是一张演示问题的图片,左侧有 120 个三角形,右侧有 121 个三角形。

一张图说明问题

如您所见,对于大型网格,Matlab 直接从一个顶点的颜色插值到另一个顶点的颜色。这可能是出于性能原因,但我正在尝试为我的论文生成漂亮的图片,我不在乎计算它们需要多长时间。有没有办法禁用这种近似?

这是生成图片的代码:

function test(n)
    %%% Generate a mesh with n triangles.

    oneTriVerts = [0 0 0;
                   1 0 0;
                   1 0 1];

    offset = [0 (1/n) 0;
              0 (1/n) 0;
              0 (1/n) 0];

    verts = zeros(0,3);
    tris  = zeros(0,3);
    for i = 0:(n-1)
        verts = [verts; (oneTriVerts + i * offset)];
        tris = [tris; i*3+1, i*3+2, i*3+3];
    end

    %%% Draw the mesh, with color corresponding to the z coordinate.

    trimesh(tris, verts(:,1), verts(:,2), verts(:,3), verts(:,3));
    title(sprintf('n = %d', n))
    shading interp
    axis equal
4

1 回答 1

5

我认为在一定的阈值之后,MATLAB 切换到 OpenGL 渲染器以获得更好的性能(硬件加速)。不幸的是,它并非没有错误。

我没有仔细研究过您如何构建三角形面(它们的排序方式可能存在问题),但一个简单的解决方案是显式设置渲染方法。只需在函数末尾添加以下调用:

set(gcf, 'Renderer','zbuffer')

编辑

上面的解决方法应该做得很好。现在真正的问题不是有缺陷的 OpenGL,而是记录在案的限制:

OpenGL 不进行颜色图插值。如果您使用索引颜色和插值面或边缘着色创建表面或面片,OpenGL 会通过 RGB 颜色立方体而不是通过颜色图对颜色进行插值。

请注意,TRIMESH 调用等效于以下内容:

patch('Faces',tris, 'Vertices',verts, 'FaceVertexCData',verts(:,3), ...
    'EdgeColor','none', 'FaceColor','interp', 'CDataMapping','scaled')

因此,对于每个顶点,您指定一个等于其 z 坐标的颜色(您只有两个唯一值,0 或 1)。这被解释为使用缩放映射(默认为喷射颜色图)在当前图形颜色图中的索引颜色。所以这两种颜色最终是:

clr = jet(64);    % default colormap
clr(1,:)          % blueish color [0 0 0.5625] mapped from 0
clr(end,:)        % reddish color [0.5 0 0] mapped from 1

不幸的是,正如上面的引用所解释的,OpenGL 渲染器不会使用颜色图调色板的颜色进行插值,而是在上述两种颜色之间的 RGB 颜色空间中执行插值。因此我们得到了你看到的蓝红色渐变。

因此,您唯一的选择是使用其他两个渲染器之一,这zbuffer是这里最好的方法。


这是查看两种渲染方法之间差异的代码:

% plot patch
clf
patch('Faces',tris, 'Vertices',verts, 'FaceVertexCData',verts(:,3), ...
    'EdgeColor','none', 'FaceColor','interp', 'CDataMapping','scaled')
view(3)
axis vis3d
colorbar

% choose one of the two
set(gcf, 'Renderer','opengl')
set(gcf, 'Renderer','zbuffer')

OpenGL

opengl 渲染器

Z缓冲区

zbuffer 渲染器

于 2013-09-22T11:29:44.773 回答