1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

OpenGLでMesh Shaderを使ってみる

Last updated at Posted at 2024-08-14

インターネットに転がっているMesh ShaderのサンプルはDirectX 12やVulkanが多いが、実はOpenGLでも特定環境ではMesh Shaderが使える。簡単なサンプルとしてMesh Shaderを用いた三角形の描画を行う。

描画コマンド

NV_mesh_shader拡張を利用する。NVIDIAのTuring以降のGPUであれば使えるはず。

描画コマンドはCompute ShaderのDispatchに似ており、WorkGroupの数を指定する。

void DrawMeshTasksNV( uint first, uint count );

Compute Shaderとは異なり、WorkGroupは一次元で、gl_WorkGroupID.ygl_WorkGroupID.zは0になる。
gl_WorkGroupID.xは [first, first+count-1] の範囲に設定される。

シェーダー

#version 460
#extension GL_NV_mesh_shader : require

layout(local_size_x = 1) in;
layout(max_vertices = 3, max_primitives = 1) out;
layout(triangles) out;

out VertexOut
{
	vec4 color;
} vertexOuts[];

void main() 
{
    // 頂点位置
    gl_MeshVerticesNV[0].gl_Position = vec4(-0.5, -0.5, 0.0, 1.0);
    gl_MeshVerticesNV[1].gl_Position = vec4( 0.5, -0.5, 0.0, 1.0);
    gl_MeshVerticesNV[2].gl_Position = vec4( 0.0,  0.5, 0.0, 1.0);

    // プリミティブのインデックス
    gl_PrimitiveIndicesNV[0] = 0;
    gl_PrimitiveIndicesNV[1] = 1;
    gl_PrimitiveIndicesNV[2] = 2;

    // プリミティブの数
    gl_PrimitiveCountNV = 1;

    // 頂点カラー
    vertexOuts[0].color = vec4(1.0, 0.0, 0.0, 1.0);
    vertexOuts[1].color = vec4(0.0, 1.0, 0.0, 1.0);
    vertexOuts[2].color = vec4(0.0, 0.0, 1.0, 1.0);
}

コードの解説

Mesh ShaderではCompute Shaderのようにスレッド数を設定する。

layout(local_size_x = 1) in;

出力する最大頂点数と最大プリミティブ数を設定する。

layout(max_vertices = 3, max_primitives = 1) out;

プリミティブのタイプを三角形に指定する。他にもpointsとlinesを指定することができる。

layout(triangles) out;

頂点位置の出力

gl_MeshVerticesNV[0].gl_Position = vec4(-0.5, -0.5, 0.0, 1.0);
gl_MeshVerticesNV[1].gl_Position = vec4( 0.5, -0.5, 0.0, 1.0);
gl_MeshVerticesNV[2].gl_Position = vec4( 0.0,  0.5, 0.0, 1.0);

頂点インデックスの出力

gl_PrimitiveIndicesNV[0] = 0;
gl_PrimitiveIndicesNV[1] = 1;
gl_PrimitiveIndicesNV[2] = 2;

出力するプリミティブ数を設定する

gl_PrimitiveCountNV = 1;

独自にデータの出力をして、Fragment Shaderに渡すこともできる。

out VertexOut
{
	vec4 color;
} vertexOuts[];

void main() 
{
    ...
    vertexOuts[0].color = vec4(1.0, 0.0, 0.0, 1.0);
    vertexOuts[1].color = vec4(0.0, 1.0, 0.0, 1.0);
    vertexOuts[2].color = vec4(0.0, 0.0, 1.0, 1.0);
}

実行すると以下のような三角形が描画される。
MeshShader Sample 2024_08_14 19_14_36.png

全体のコードはここに置いておきます。
https://github.com/molimolily/GL_MeshShaderSample

おわり

低レベルなAPIを使用せずとも、Mesh Shaderが使用できるのでめちゃくちゃ楽
気が向いたらモデルの描画とかTask Shaderを用いたcullingについても書くかも

参考

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?