<p>I managed to figure it out. A coworker told me that I was misinterpreting the documentation.
<code>layout(max_vertices=3, max_primitives=1) out;</code>
actually means max_vertices and max_primitives per workgroup, not per shader invocation. So I was always only outputting a single triangle, regardless of what I set <code>local_size_x</code> to.</p>

<p>Changing the values to proper numbers resulted in a proper rendering.</p>

CC BY-SA 4.0
2020-06-09T16:52:35.717Z
2020-06-09T16:52:35.717Z
pettersson
<p>I am trying to get up to speed with the NV_mesh_shader extension from NVidia (on my RTX2080). Samples are rare, so I tried to come up with my own small sample.</p>

<p>I am rendering a sphere (20 triangles) using an index buffer and a vertex buffer. I can render it the "usual" way using "vertex pulling" with two shader storage buffers, one for vertices, one for indices, (like I want to do it with a mesh shader) just fine.</p>

<p>When using a mesh shader (no task shader so far) I get the following problem: calling <code>glDrawMeshTaskNV(0,1)</code>with the mesh shader set to <code>layout(local_size_x=20) in</code> I only get a single triangle rendered. It looks like the mesh shader is not being invoked 20 times as I think it should?
If I call <code>glDrawMeshTaskNV(0,20)</code> and set <code>layout(local_size_x=1) in</code> it renders just fine with nothing else changed in the shader. I use <code>gl_GlobalInvocationID.x</code> to pull the proper vertices for a triangle.</p>

<p>Here's the complete shader for the non-working variant:</p>

<pre><code>#version 450
#extension GL_NV_mesh_shader : require

#define GROUP_SIZE 20
// mesh shader setup
layout(local_size_x=GROUP_SIZE) in;

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

// vertex/index data setup
struct Vertex
{
    vec4 position;
    vec4 uv;
};

layout(std430, binding=1) readonly buffer vertex_data
{
    Vertex vertex[];
};

layout(std430, binding=2) readonly buffer index_data
{
    uint indices[];
};

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

// mesh output
out gl_MeshPerVertexNV {
    vec4 gl_Position;
} gl_MeshVerticesNV[];


out uint gl_PrimitiveCountNV;
out uint gl_PrimitiveIndicesNV[];

void main()
{
    // get starting index
    const uint primitive_start_index = gl_GlobalInvocationID.x * 3;

    uint index_A = indices[primitive_start_index];
    uint index_B = indices[primitive_start_index+1];
    uint index_C = indices[primitive_start_index+2];

    // get vertices
    vec3 A = vertex[index_A].position.xyz;
    vec3 B = vertex[index_B].position.xyz;
    vec3 C = vertex[index_C].position.xyz;

    gl_MeshVerticesNV[0].gl_Position = projection * (view * (model * vec4(A, 1.0)));
    gl_MeshVerticesNV[1].gl_Position = projection * (view * (model * vec4(B, 1.0)));
    gl_MeshVerticesNV[2].gl_Position = projection * (view * (model * vec4(C, 1.0)));

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

    gl_PrimitiveCountNV += 1;
}
</code></pre>

<p>Keep in mind this is only a learning sample, I know this is maybe overkill for a mesh shader :)</p>

<p>Thanks for any hints.
pettersson</p>

CC BY-SA 4.0
2020-06-08T17:48:42.650Z
"*with two shader storage buffers*" OpenGL has vertex attribute arrays; why would you use SSBOs for something so trivial?
Nicol Bolas
CC BY-SA 4.0
2020-06-08T18:03:44.747Z
You cannot use vertex attribute arrays with mesh shaders. And I wanted to make sure the buffers are ok before starting with mesh shaders. And again: it‘s for learning.
pettersson
<opengl><glsl>
OpenGL task/mesh shader extension NV_mesh_shader not behaving as I expected
pettersson
# OpenGL task/mesh shader extension NV_mesh_shader not behaving as I expected

(Asked by: username_0 on 2020-06-08)

I am trying to get up to speed with the NV\_mesh\_shader extension from NVidia (on my RTX2080). Samples are rare, so I tried to come up with my own small sample.

I am rendering a sphere (20 triangles) using an index buffer and a vertex buffer. I can render it the "usual" way using "vertex pulling" with two shader storage buffers, one for vertices, one for indices, (like I want to do it with a mesh shader) just fine.

When using a mesh shader (no task shader so far) I get the following problem: calling `glDrawMeshTaskNV(0,1)`with the mesh shader set to `layout(local_size_x=20) in` I only get a single triangle rendered. It looks like the mesh shader is not being invoked 20 times as I think it should?
If I call `glDrawMeshTaskNV(0,20)` and set `layout(local_size_x=1) in` it renders just fine with nothing else changed in the shader. I use `gl_GlobalInvocationID.x` to pull the proper vertices for a triangle.

Here's the complete shader for the non-working variant:

```
#version 450
#extension GL_NV_mesh_shader : require

#define GROUP_SIZE 20
// mesh shader setup
layout(local_size_x=GROUP_SIZE) in;

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

// vertex/index data setup
struct Vertex
{
    vec4 position;
    vec4 uv;
};

layout(std430, binding=1) readonly buffer vertex_data
{
    Vertex vertex[];
};

layout(std430, binding=2) readonly buffer index_data
{
    uint indices[];
};

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

// mesh output
out gl_MeshPerVertexNV {
    vec4 gl_Position;
} gl_MeshVerticesNV[];

out uint gl_PrimitiveCountNV;
out uint gl_PrimitiveIndicesNV[];

void main()
{
    // get starting index
    const uint primitive_start_index = gl_GlobalInvocationID.x * 3;

    uint index_A = indices[primitive_start_index];
    uint index_B = indices[primitive_start_index+1];
    uint index_C = indices[primitive_start_index+2];

    // get vertices
    vec3 A = vertex[index_A].position.xyz;
    vec3 B = vertex[index_B].position.xyz;
    vec3 C = vertex[index_C].position.xyz;

    gl_MeshVerticesNV[0].gl_Position = projection * (view * (model * vec4(A, 1.0)));
    gl_MeshVerticesNV[1].gl_Position = projection * (view * (model * vec4(B, 1.0)));
    gl_MeshVerticesNV[2].gl_Position = projection * (view * (model * vec4(C, 1.0)));

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

    gl_PrimitiveCountNV += 1;
}

```

Keep in mind this is only a learning sample, I know this is maybe overkill for a mesh shader :)

Thanks for any hints.
username_0

**Tags:** opengl, glsl

> **Comments:**
> **username_1**: "*with two shader storage buffers*" OpenGL has vertex attribute arrays; why would you use SSBOs for something so trivial?  
> **username_0**: You cannot use vertex attribute arrays with mesh shaders. And I wanted to make sure the buffers are ok before starting with mesh shaders. And again: it‘s for learning.  

---

## 1 answers

### Answer by username_0 on 2020-06-09. Score: 4 | Accepted answer

I managed to figure it out. A coworker told me that I was misinterpreting the documentation.
`layout(max_vertices=3, max_primitives=1) out;`
actually means max\_vertices and max\_primitives per workgroup, not per shader invocation. So I was always only outputting a single triangle, regardless of what I set `local_size_x` to.

Changing the values to proper numbers resulted in a proper rendering.


---

