如果网格大于120个三角形,则Matlab会正确停止在网格上插入颜色

Nei*_*ter 8 3d matlab plot mesh

我正在尝试使用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
Run Code Online (Sandbox Code Playgroud)

Amr*_*mro 5

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

我没有仔细研究过你是如何构建三角形面的(它们可能是ordererd的问题),但一个简单的解决方案是显式设置渲染方法.只需在功能结束时添加以下调用:

set(gcf, 'Renderer','zbuffer')
Run Code Online (Sandbox Code Playgroud)

编辑

上面的解决方法应该没问题.现在真正的问题不是一个有缺陷的OpenGL,而是一个记录在案的限制:

OpenGL不进行色彩图插值.如果使用索引颜色和插值的面或边颜色创建曲面或面片,OpenGL会通过RGB颜色立方体而不是通过颜色图插入颜色.

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

patch('Faces',tris, 'Vertices',verts, 'FaceVertexCData',verts(:,3), ...
    'EdgeColor','none', 'FaceColor','interp', 'CDataMapping','scaled')
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

不幸的是,正如上面引用的解释,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')
Run Code Online (Sandbox Code Playgroud)

OpenGL的

opengl渲染器

Z缓冲区

zbuffer渲染器