8

関数を使用してMatlabで大きなメッシュを描画しようとしてtrimeshいます.頂点のz座標が色を制御しています. 残念ながら、メッシュのサイズが 120 三角形を超えると、Matlab は色の補間を正しく停止します。これは問題を示す図で、左側に 120 個の三角形、右側に 121 個の三角形があります。

問題を示す画像

ご覧のとおり、大きなメッシュの場合、Matlab は 1 つの頂点の色から他の頂点の色に直接補間します。これはおそらくパフォーマンス上の理由によるものですが、私は自分の論文用に素敵な画像を生成しようとしており、それらの計算にかかる時間は気にしません。この近似を無効にする方法はありますか?

画像を生成するコードは次のとおりです。

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 の 2 つの一意の値しかありません)。これは、スケーリングされたマッピングを使用して、現在の Figure のカラーマップへのインデックス付きの色として解釈されます (デフォルトは jet カラーマップです)。したがって、2 つの色は次のようになります。

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 レンダラーはカラーマップ パレットの色を使用して補間を行うのではなく、上の 2 つの色の間の RGB 色空間で補間を行います。したがって、見た青赤のグラデーションが得られます。

したがって、唯一のオプションは、他の 2 つのレンダラーのいずれかを使用することであり、zbufferここでは最良の方法です。


2 つのレンダリング方法の違いを確認するためのコードを次に示します。

% 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 に答える