<p>Your geometry shader is broken. Every time you do <code>EmitVertex</code>, all of the <code>out</code> variables acquire unspecified values (ie: implementations aren't required to preserve those values). So you must reset them for every vertex.</p>
<p>That being said, your algorithm is unnecessarily complex. It'd be way easier to just let your GPU's depth test do it. For each vertex in your triangulation, draw a cone with the vertex (in 2D) where the tip of the cone is, and with the tip pointing into the camera using an orthographic projection. The cones need to be pretty wide. Each cone should have its own color.</p>
<p>Where two cones intersect will define the place where two vertices are equal-distances to each other.</p>

CC BY-SA 4.0
2023-01-21T20:15:37.203Z
Oh, that's actually pretty clever. Is that efficient?
Francesco Sollazzi
CC BY-SA 4.0
2023-01-21T20:22:35.073Z
@FrankSoll: Neither method is going to stress even an integrated GPU. The main issue with the cone method is that its accuracy depends on how good of a cone you render. If you start zooming in, you need to use a finer cone.
Nicol Bolas
CC BY-SA 4.0
2023-01-21T20:42:19.967Z
ok, I'll create one cone and use istancing I guess. Thanks.
Francesco Sollazzi
CC BY-SA 4.0
2023-01-21T19:33:15.390Z
2023-01-21T19:33:15.390Z
Nicol Bolas
<p>I have a set of points, which I triangulate to a Delaunay graph to make a mesh.</p>
<p>Every mesh vertex has a unique colour, and I can render it without any problem. But I want Voronoi rendering to be possible too. Ideally, I want to make a shader which computes the distance from every vertex, and colours the vertex fragments with the colour of the nearest vertex, but somehow I get the wrong result.</p>
<p>This is the GLSL shader I'm using:</p>
<p>Vertex:</p>
<pre><code>#version 330

layout (location=0) in vec2 position;
layout (location=1) in vec3 inColour;

flat out vec3 col_in;

void main()
{
    gl_Position = vec4(position, 0.0, 1.0);

    col_in = inColour;
}
</code></pre>
<p>Geometry:</p>
<pre><code>#version 330 core
layout (triangles) in;
layout (triangle_strip, max_vertices = 3) out;

uniform vec2 window_size;

flat in vec3 col_in[];

out vec4 vertex_a;
out vec4 vertex_b;
out vec4 vertex_c;

flat out vec3 colour_a;
flat out vec3 colour_b;
flat out vec3 colour_c;

void main() {    
    vertex_a = (gl_in[0].gl_Position);
    vertex_b = (gl_in[1].gl_Position);
    vertex_c = (gl_in[2].gl_Position);

    gl_Position = vertex_a; 
    colour_a = col_in[0];
    EmitVertex();

    gl_Position = vertex_b;
    colour_b = col_in[1];
    EmitVertex();

    gl_Position = vertex_c;
    colour_c = col_in[2];
    EmitVertex();
    
    EndPrimitive();
} 
</code></pre>
<p>Fragment:</p>
<pre><code>#version 330 core

uniform vec2 window_size;

in vec4 vertex_a;
in vec4 vertex_b;
in vec4 vertex_c;

flat in vec3 colour_a;
flat in vec3 colour_b;
flat in vec3 colour_c;

out vec4 fragColor;

void main()
{   
    vec2 uv = (gl_FragCoord.xy / window_size) - vec2(0.5);

    float da = distance(vertex_a * 0.5, vec4(uv, 0.0, 0.0));
    float db = distance(vertex_b * 0.5, vec4(uv, 0.0, 0.0));
    float dc = distance(vertex_c * 0.5, vec4(uv, 0.0, 0.0));

    if(da &lt; db &amp;&amp; da &lt; dc){
        fragColor = vec4(colour_a, 1.0);
    } else if (db &lt; da &amp;&amp; db &lt; dc){
        fragColor = vec4(colour_b, 1.0);
    } else if(dc &lt; da &amp;&amp; dc &lt; db) {
        fragColor = vec4(colour_c, 1.0);
    } else {
        fragColor = vec4(1.0);
    }
}  
</code></pre>
<p>This is the result:</p>
<p><a href="https://i.sstatic.net/GEMgV.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/GEMgV.png" alt="Result" /></a></p>
<p>Wireframe:</p>
<p><a href="https://i.sstatic.net/hE6fZ.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/hE6fZ.png" alt="Result - Wireframe rendered" /></a></p>
<p>My question is: why is my result not a Voronoi diagram? Does it depend on the shader, or maybe the triangulation is wrong?
Is this the best way to do this? If not, what should I do?</p>

<opengl><shader><glsl><mesh>
Best way for rendering Voronoi diagram from Delaunay graph mesh
Francesco Sollazzi
# Best way for rendering Voronoi diagram from Delaunay graph mesh

(Asked by: username_0 on 2023-01-21)

I have a set of points, which I triangulate to a Delaunay graph to make a mesh.

Every mesh vertex has a unique colour, and I can render it without any problem. But I want Voronoi rendering to be possible too. Ideally, I want to make a shader which computes the distance from every vertex, and colours the vertex fragments with the colour of the nearest vertex, but somehow I get the wrong result.

This is the GLSL shader I'm using:

Vertex:

```
#version 330

layout (location=0) in vec2 position;
layout (location=1) in vec3 inColour;

flat out vec3 col_in;

void main()
{
    gl_Position = vec4(position, 0.0, 1.0);

    col_in = inColour;
}

```

Geometry:

```
#version 330 core
layout (triangles) in;
layout (triangle_strip, max_vertices = 3) out;

uniform vec2 window_size;

flat in vec3 col_in[];

out vec4 vertex_a;
out vec4 vertex_b;
out vec4 vertex_c;

flat out vec3 colour_a;
flat out vec3 colour_b;
flat out vec3 colour_c;

void main() {    
    vertex_a = (gl_in[0].gl_Position);
    vertex_b = (gl_in[1].gl_Position);
    vertex_c = (gl_in[2].gl_Position);

    gl_Position = vertex_a; 
    colour_a = col_in[0];
    EmitVertex();

    gl_Position = vertex_b;
    colour_b = col_in[1];
    EmitVertex();

    gl_Position = vertex_c;
    colour_c = col_in[2];
    EmitVertex();
    
    EndPrimitive();
} 

```

Fragment:

```
#version 330 core

uniform vec2 window_size;

in vec4 vertex_a;
in vec4 vertex_b;
in vec4 vertex_c;

flat in vec3 colour_a;
flat in vec3 colour_b;
flat in vec3 colour_c;

out vec4 fragColor;

void main()
{   
    vec2 uv = (gl_FragCoord.xy / window_size) - vec2(0.5);

    float da = distance(vertex_a * 0.5, vec4(uv, 0.0, 0.0));
    float db = distance(vertex_b * 0.5, vec4(uv, 0.0, 0.0));
    float dc = distance(vertex_c * 0.5, vec4(uv, 0.0, 0.0));

    if(da < db && da < dc){
        fragColor = vec4(colour_a, 1.0);
    } else if (db < da && db < dc){
        fragColor = vec4(colour_b, 1.0);
    } else if(dc < da && dc < db) {
        fragColor = vec4(colour_c, 1.0);
    } else {
        fragColor = vec4(1.0);
    }
}  

```

This is the result:

[![Result](https://i.sstatic.net/GEMgV.png)](https://i.sstatic.net/GEMgV.png)

Wireframe:

[![Result - Wireframe rendered](https://i.sstatic.net/hE6fZ.png)](https://i.sstatic.net/hE6fZ.png)

My question is: why is my result not a Voronoi diagram? Does it depend on the shader, or maybe the triangulation is wrong?
Is this the best way to do this? If not, what should I do?

**Tags:** opengl, shader, glsl, mesh


---

## 1 answers

### Answer by username_1 on 2023-01-21. Score: 2 | Accepted answer

Your geometry shader is broken. Every time you do `EmitVertex`, all of the `out` variables acquire unspecified values (ie: implementations aren't required to preserve those values). So you must reset them for every vertex.

That being said, your algorithm is unnecessarily complex. It'd be way easier to just let your GPU's depth test do it. For each vertex in your triangulation, draw a cone with the vertex (in 2D) where the tip of the cone is, and with the tip pointing into the camera using an orthographic projection. The cones need to be pretty wide. Each cone should have its own color.

Where two cones intersect will define the place where two vertices are equal-distances to each other.

> **Comments:**
> **username_0**: Oh, that's actually pretty clever. Is that efficient?  
> **username_1**: @FrankSoll: Neither method is going to stress even an integrated GPU. The main issue with the cone method is that its accuracy depends on how good of a cone you render. If you start zooming in, you need to use a finer cone.  
> **username_0**: ok, I'll create one cone and use istancing I guess. Thanks.  

---

