# Populating a vertexBuffer with a compute shader

**URL:** <https://openrndr.discourse.group/t/populating-a-vertexbuffer-with-a-compute-shader/628>\
**Category:** Tutorials\
**Created:** [February 22, 2024, 5:45pm UTC](https://openrndr.discourse.group/t/populating-a-vertexbuffer-with-a-compute-shader/628 "2024-02-22T17:45:28Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![abe](https://yyz2.discourse-cdn.com/free1/user_avatar/openrndr.discourse.group/abe/32/700_2.png) [@abe](https://openrndr.discourse.group/u/abe)\
**Post date:** [February 22, 2024, 5:45pm UTC](https://openrndr.discourse.group/t/populating-a-vertexbuffer-with-a-compute-shader/628/1 "2024-02-22T17:45:28Z")

</div>

![simple.cs04generateVertices.ComputeGenerateTriangleStrip-2024-02-22-18.30.16](https://global.discourse-cdn.com/free1/uploads/openrndr/original/1X/7e8fcd7796575fd2af56565e54a5bc3cc0d11869.jpeg)

Until I add more demos related to compute shaders and vertex buffers, I’ll leave this short example.  
The program creates a vertex buffer for 1000 vertices. Then, on every animation frame, we call a compute shader multiple times to populate the buffer, then draw it in 2D. To avoid the compute shader generating always the same result I pass a `vec2` uniform containing the time. A shade style is used to modulate the color along the triangle strip. I [ab]use the vertex color alpha property to encode an increasing value. I could have used a float, but I was planning to generate colors for the strips as well. In the current iteration the colors come from a generated palette in which the hue shifts 360 degrees.

Notice that the compute shader runs in parallel, and each produced vertex depends only on its index (and the uniform). If you wanted a vertex to depend on the previous vertex then it couldn’t be calculated in parallel.

Feel free to ask questions. Maybe I even know the answer 🙂

> **imports**
>
> ```kotlin
> import org.intellij.lang.annotations.Language
> import org.openrndr.application
> import org.openrndr.color.ColorRGBa
> import org.openrndr.draw.*
> import org.openrndr.extensions.Screenshots
> import org.openrndr.extra.color.palettes.analogous
> import org.openrndr.extra.color.presets.YELLOW_GREEN
> import org.openrndr.extra.color.spaces.HSLuv
> import org.openrndr.extra.color.tools.shadeLuminosity
> import org.openrndr.math.Vector2
> import kotlin.math.pow
> 
> ```

```kotlin
fun main() = application {
    configure {
        width = 1000
        height = 1000
    }
    program {
        val vb = vertexBuffer(vertexFormat {
            position(3)
            padding(4)
            color(4)
        }, 1000)

        val copies = 50

        @Language("GLSL")
        val glsl = """
            #version 450 core
            
            struct Vertex {
                vec3 position;
                vec4 color;
            };

            layout (local_size_x = 64, local_size_y = 1) in;
            layout (std430, binding=0) buffer VertexBuffer {
                Vertex verts[];
            };
            
            uniform vec2 off;
            
            void main(void) {
                uint idx = gl_GlobalInvocationID.x;
                float t = float(idx) * 0.01 + off.x;
                float k = float(idx % 2) * 0.2 * (sin(t * 5) * 0.4 + 0.6) + 1.0;
                float r = sin(t * 0.11) * 350 + 460;
                verts[idx].position.x = sin(t) * cos(t * 0.51 + sin(-t * 0.25 + off.y)) * r * k + 500.0; 
                verts[idx].position.y = cos(t) * sin(t * 0.49 + off.x * 0.05) * r * k + 500.0;
                verts[idx].color.a = float(idx + off.x);
            }
        """

        val cs2 = ComputeShader.fromCode(glsl, "Comp2")
        cs2.buffer("VertexBuffer", vb)

        val style = shadeStyle {
            fragmentTransform = "x_fill *= sin(va_color.a / $copies.0) * 0.5 + 0.5;"
        }
        val palette = ColorRGBa.YELLOW_GREEN.analogous<HSLuv>(360.0, copies).mapIndexed { i, c ->
            c.shadeLuminosity<HSLuv>((i / (copies - 1.0)).pow(2.0))
        }

        extend {
            repeat(copies) {
                cs2.uniform("off", Vector2(seconds + it, seconds * 0.33 + it / copies.toDouble()))
                cs2.execute(vb.vertexCount)
                drawer.shadeStyle = style
                drawer.fill = palette[it]
                drawer.vertexBuffer(vb, DrawPrimitive.TRIANGLE_STRIP)
            }
        }
    }
}

```
