def histogram(cfg):
    """Histogram using compute shaders"""
    m0 = cfg.medias[0]
    cfg.duration = m0.duration
    cfg.aspect_ratio = (m0.width, m0.height)
    g = ngl.Group()

    m = ngl.Media(cfg.medias[0].filename)
    t = ngl.Texture2D(data_src=m)

    h = ngl.Block(label="histogram_block", layout="std430")
    h.add_fields(
        ngl.BufferUInt(256, label="r"),
        ngl.BufferUInt(256, label="g"),
        ngl.BufferUInt(256, label="b"),
        ngl.UniformUInt(label="maximum"),
    )

    r = ngl.RenderTexture(t)
    proxy_size = 128
    proxy = ngl.Texture2D(width=proxy_size, height=proxy_size)
    rtt = ngl.RenderToTexture(r)
    rtt.add_color_textures(proxy)
    g.add_children(rtt)

    compute_program = ngl.ComputeProgram(cfg.get_comp("histogram-clear"),
                                         workgroup_size=(1, 1, 1))
    compute_program.update_properties(hist=ngl.ResourceProps(writable=True))
    compute = ngl.Compute(workgroup_count=(256, 1, 1),
                          program=compute_program,
                          label="histogram-clear")
    compute.update_resources(hist=h)
    g.add_children(compute)

    local_size = 8
    group_size = proxy_size / local_size
    compute_program = ngl.ComputeProgram(cfg.get_comp("histogram-exec"),
                                         workgroup_size=(local_size,
                                                         local_size, 1))
    compute = ngl.Compute(workgroup_count=(group_size, group_size, 1),
                          program=compute_program,
                          label="histogram-exec")
    compute.update_resources(hist=h, source=proxy)
    compute_program.update_properties(hist=ngl.ResourceProps(writable=True))
    compute_program.update_properties(source=ngl.ResourceProps(as_image=True))
    g.add_children(compute)

    q = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0))
    p = ngl.Program(vertex=cfg.get_vert("histogram-display"),
                    fragment=cfg.get_frag("histogram-display"))
    p.update_vert_out_vars(var_uvcoord=ngl.IOVec2(),
                           var_tex0_coord=ngl.IOVec2())
    render = ngl.Render(q, p)
    render.update_frag_resources(tex0=t, hist=h)
    g.add_children(render)

    return g
예제 #2
0
def histogram(cfg):
    '''Histogram using compute shaders'''
    m0 = cfg.medias[0]
    cfg.duration = m0.duration
    cfg.aspect_ratio = (m0.width, m0.height)
    g = ngl.Group()

    m = ngl.Media(cfg.medias[0].filename)
    t = ngl.Texture2D(data_src=m)

    h = ngl.Block(label='histogram_block', layout='std430')
    h.add_fields(
        ngl.BufferUInt(256, label='r'),
        ngl.BufferUInt(256, label='g'),
        ngl.BufferUInt(256, label='b'),
        ngl.UniformInt(label='maximum'),
    )

    q = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0))
    r = ngl.Render(q)
    r.update_textures(tex0=t)
    proxy_size = 128
    proxy = ngl.Texture2D(width=proxy_size, height=proxy_size)
    rtt = ngl.RenderToTexture(r)
    rtt.add_color_textures(proxy)
    g.add_children(rtt)

    shader_version = '310 es' if cfg.backend == 'gles' else '430'
    shader_header = '#version %s\n' % shader_version
    if cfg.backend == 'gles' and cfg.system == 'Android':
        shader_header += '#extension GL_ANDROID_extension_pack_es31a: require\n'

    compute_program = ngl.ComputeProgram(shader_header + cfg.get_comp('histogram-clear'))
    compute = ngl.Compute(256, 1, 1, compute_program, label='histogram-clear')
    compute.update_blocks(histogram_buffer=h)
    g.add_children(compute)

    local_size = 8
    group_size = proxy_size / local_size
    compute_shader = cfg.get_comp('histogram-exec') % {'local_size': local_size}
    compute_program = ngl.ComputeProgram(shader_header + compute_shader)
    compute = ngl.Compute(group_size, group_size, 1, compute_program, label='histogram-exec')
    compute.update_blocks(histogram_buffer=h)
    compute.update_textures(source=proxy)
    g.add_children(compute)

    q = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0))
    p = ngl.Program(vertex=shader_header + cfg.get_vert('histogram-display'),
                    fragment=shader_header + cfg.get_frag('histogram-display'))
    render = ngl.Render(q, p)
    render.update_textures(tex0=t)
    render.update_blocks(histogram_buffer=h)
    g.add_children(render)

    return g
예제 #3
0
def _compute_animation(cfg, animate_pre_render=True):
    cfg.duration = 5
    cfg.aspect_ratio = (1, 1)
    local_size = 2

    vertices_data = array.array(
        "f",
        [
            # fmt: off
            -0.5,
            -0.5,
            0.0,
            0.5,
            -0.5,
            0.0,
            -0.5,
            0.5,
            0.0,
            0.5,
            0.5,
            0.0,
            # fmt: on
        ],
    )
    nb_vertices = 4

    input_vertices = ngl.BufferVec3(data=vertices_data, label="vertices")
    output_vertices = ngl.BufferVec3(data=vertices_data, label="vertices")
    input_block = ngl.Block(fields=[input_vertices], layout="std140")
    output_block = ngl.Block(fields=[output_vertices], layout="std140")

    rotate_animkf = [
        ngl.AnimKeyFrameFloat(0, 0),
        ngl.AnimKeyFrameFloat(cfg.duration, 360)
    ]
    rotate = ngl.Rotate(ngl.Identity(),
                        axis=(0, 0, 1),
                        angle=ngl.AnimatedFloat(rotate_animkf))
    transform = ngl.UniformMat4(transform=rotate)

    program = ngl.ComputeProgram(_ANIMATION_COMPUTE,
                                 workgroup_size=(local_size, local_size, 1))
    program.update_properties(dst=ngl.ResourceProps(writable=True))
    compute = ngl.Compute(workgroup_count=(nb_vertices / (local_size**2), 1,
                                           1),
                          program=program)
    compute.update_resources(transform=transform,
                             src=input_block,
                             dst=output_block)

    quad_buffer = ngl.BufferVec3(block=output_block, block_field=0)
    geometry = ngl.Geometry(quad_buffer, topology="triangle_strip")
    program = ngl.Program(vertex=cfg.get_vert("color"),
                          fragment=cfg.get_frag("color"))
    render = ngl.Render(geometry, program)
    render.update_frag_resources(color=ngl.UniformVec3(value=COLORS.sgreen),
                                 opacity=ngl.UniformFloat(1))

    children = (compute, render) if animate_pre_render else (render, compute)
    return ngl.Group(children=children)
예제 #4
0
def compute_particules(cfg):
    random.seed(0)
    cfg.duration = 10
    local_size = 4
    nb_particules = 128

    shader_version = '310 es' if cfg.backend == 'gles' else '430'
    shader_data = dict(
        version=shader_version,
        local_size=local_size,
        nb_particules=nb_particules,
    )
    compute_shader = _PARTICULES_COMPUTE % shader_data
    vertex_shader = _PARTICULES_VERT % shader_data
    fragment_shader = _PARTICULES_FRAG % shader_data

    positions = array.array('f')
    velocities = array.array('f')
    for i in range(nb_particules):
        positions.extend([
            random.uniform(-2.0, 1.0),
            random.uniform(-1.0, 1.0),
            0.0,
        ])
        velocities.extend([
            random.uniform(1.0, 2.0),
            random.uniform(0.5, 1.5),
        ])

    ipositions = ngl.Block(
        fields=[
            ngl.BufferVec3(data=positions),
            ngl.BufferVec2(data=velocities),
        ],
        layout='std430',
    )
    opositions = ngl.Block(fields=[ngl.BufferVec3(count=nb_particules)], layout='std430')

    animkf = [
        ngl.AnimKeyFrameFloat(0, 0),
        ngl.AnimKeyFrameFloat(cfg.duration, 1.0),
    ]
    time = ngl.AnimatedFloat(animkf)
    duration = ngl.UniformFloat(cfg.duration)

    group_size = nb_particules / local_size
    program = ngl.ComputeProgram(compute_shader)
    compute = ngl.Compute(nb_particules, 1, 1, program)
    compute.update_uniforms(time=time, duration=duration)
    compute.update_blocks(ipositions_buffer=ipositions, opositions_buffer=opositions)

    circle = ngl.Circle(radius=0.05)
    program = ngl.Program(vertex=vertex_shader, fragment=fragment_shader)
    render = ngl.Render(circle, program, nb_instances=nb_particules)
    render.update_uniforms(color=ngl.UniformVec4(value=COLORS['sgreen']))
    render.update_blocks(positions_buffer=opositions)

    group = ngl.Group()
    group.add_children(compute, render)
    return group
예제 #5
0
def compute_particles(cfg):
    cfg.duration = 10
    workgroups = (2, 1, 4)
    local_size = (4, 4, 1)
    nb_particles = workgroups[0] * workgroups[1] * workgroups[2] * local_size[
        0] * local_size[1] * local_size[2]

    positions = array.array("f")
    velocities = array.array("f")
    for i in range(nb_particles):
        positions.extend([
            cfg.rng.uniform(-2.0, 1.0),
            cfg.rng.uniform(-1.0, 1.0),
            0.0,
        ])
        velocities.extend([
            cfg.rng.uniform(1.0, 2.0),
            cfg.rng.uniform(0.5, 1.5),
        ])

    ipositions = ngl.Block(
        fields=[
            ngl.BufferVec3(data=positions, label="positions"),
            ngl.BufferVec2(data=velocities, label="velocities"),
        ],
        layout="std430",
    )
    opositions = ngl.Block(
        fields=[ngl.BufferVec3(count=nb_particles, label="positions")],
        layout="std140")

    animkf = [
        ngl.AnimKeyFrameFloat(0, 0),
        ngl.AnimKeyFrameFloat(cfg.duration, 1.0),
    ]
    time = ngl.AnimatedFloat(animkf)
    duration = ngl.UniformFloat(cfg.duration)

    program = ngl.ComputeProgram(_PARTICULES_COMPUTE,
                                 workgroup_size=local_size)
    program.update_properties(odata=ngl.ResourceProps(writable=True))
    compute = ngl.Compute(workgroups, program)
    compute.update_resources(time=time,
                             duration=duration,
                             idata=ipositions,
                             odata=opositions)

    circle = ngl.Circle(radius=0.05)
    program = ngl.Program(vertex=_PARTICULES_VERT,
                          fragment=cfg.get_frag("color"))
    render = ngl.Render(circle, program, nb_instances=nb_particles)
    render.update_frag_resources(color=ngl.UniformVec3(value=COLORS.sgreen),
                                 opacity=ngl.UniformFloat(1))
    render.update_vert_resources(data=opositions)

    group = ngl.Group()
    group.add_children(compute, render)
    return group
예제 #6
0
def compute_particules(cfg):
    random.seed(0)
    cfg.duration = 10
    local_size = 4
    nb_particules = 128

    positions = array.array('f')
    velocities = array.array('f')
    for i in range(nb_particules):
        positions.extend([
            random.uniform(-2.0, 1.0),
            random.uniform(-1.0, 1.0),
            0.0,
        ])
        velocities.extend([
            random.uniform(1.0, 2.0),
            random.uniform(0.5, 1.5),
        ])

    ipositions = ngl.Block(
        fields=[
            ngl.BufferVec3(data=positions, label='positions'),
            ngl.BufferVec2(data=velocities, label='velocities'),
        ],
        layout='std430',
    )
    opositions = ngl.Block(
        fields=[ngl.BufferVec3(count=nb_particules, label='positions')],
        layout='std430')

    animkf = [
        ngl.AnimKeyFrameFloat(0, 0),
        ngl.AnimKeyFrameFloat(cfg.duration, 1.0),
    ]
    time = ngl.AnimatedFloat(animkf)
    duration = ngl.UniformFloat(cfg.duration)

    group_size = nb_particules / local_size
    program = ngl.ComputeProgram(_PARTICULES_COMPUTE %
                                 dict(local_size=local_size))
    compute = ngl.Compute(nb_particules, 1, 1, program)
    compute.update_resources(time=time,
                             duration=duration,
                             idata=ipositions,
                             odata=opositions)

    circle = ngl.Circle(radius=0.05)
    program = ngl.Program(vertex=_PARTICULES_VERT,
                          fragment=cfg.get_frag('color'))
    render = ngl.Render(circle, program, nb_instances=nb_particules)
    render.update_frag_resources(color=ngl.UniformVec4(value=COLORS['sgreen']))
    render.update_vert_resources(data=opositions)

    group = ngl.Group()
    group.add_children(compute, render)
    return group
예제 #7
0
def compute_animation(cfg):
    cfg.duration = 5
    cfg.aspect_ratio = (1, 1)
    local_size = 2

    vertices_data = array.array('f', [
        -0.5,
        -0.5,
        0.0,
        0.5,
        -0.5,
        0.0,
        -0.5,
        0.5,
        0.0,
        0.5,
        0.5,
        0.0,
    ])
    nb_vertices = 4

    input_vertices = ngl.BufferVec3(data=vertices_data, label='vertices')
    output_vertices = ngl.BufferVec3(data=vertices_data, label='vertices')
    input_block = ngl.Block(fields=[input_vertices], layout='std140')
    output_block = ngl.Block(fields=[output_vertices], layout='std140')

    rotate_animkf = [
        ngl.AnimKeyFrameFloat(0, 0),
        ngl.AnimKeyFrameFloat(cfg.duration, 360)
    ]
    rotate = ngl.Rotate(ngl.Identity(),
                        axis=(0, 0, 1),
                        anim=ngl.AnimatedFloat(rotate_animkf))
    transform = ngl.UniformMat4(transform=rotate)

    program = ngl.ComputeProgram(_ANIMATION_COMPUTE,
                                 workgroup_size=(local_size, local_size, 1))
    program.update_properties(dst=ngl.ResourceProps(writable=True))
    compute = ngl.Compute(workgroup_count=(nb_vertices / (local_size**2), 1,
                                           1),
                          program=program)
    compute.update_resources(transform=transform,
                             src=input_block,
                             dst=output_block)

    quad_buffer = ngl.BufferVec3(block=output_block, block_field=0)
    geometry = ngl.Geometry(quad_buffer, topology='triangle_strip')
    program = ngl.Program(vertex=cfg.get_vert('color'),
                          fragment=cfg.get_frag('color'))
    render = ngl.Render(geometry, program)
    render.update_frag_resources(color=ngl.UniformVec4(value=COLORS['sgreen']))

    return ngl.Group(children=(compute, render))
예제 #8
0
def compute_image_load_store(cfg, show_dbg_points=False):
    size = _N
    texture_data = ngl.BufferFloat(
        data=array.array("f", [x / (size**2) for x in range(size**2)]))
    texture_r = ngl.Texture2D(format="r32_sfloat",
                              width=size,
                              height=size,
                              data_src=texture_data)
    texture_g = ngl.Texture2D(format="r32_sfloat",
                              width=size,
                              height=size,
                              data_src=texture_data)
    texture_b = ngl.Texture2D(format="r32_sfloat",
                              width=size,
                              height=size,
                              data_src=texture_data)
    scale = ngl.Block(
        fields=[ngl.UniformVec2(value=(-1.0, 1.0), label="factors")],
        layout="std140",
    )
    texture_rgba = ngl.Texture2D(width=size, height=size)
    program = ngl.ComputeProgram(_IMAGE_LOAD_STORE_COMPUTE,
                                 workgroup_size=(size, size, 1))
    program.update_properties(
        texture_r=ngl.ResourceProps(as_image=True),
        texture_g=ngl.ResourceProps(as_image=True),
        texture_b=ngl.ResourceProps(as_image=True),
        texture_rgba=ngl.ResourceProps(as_image=True, writable=True),
    )
    compute = ngl.Compute(workgroup_count=(1, 1, 1), program=program)
    compute.update_resources(texture_r=texture_r,
                             texture_g=texture_g,
                             texture_b=texture_b,
                             scale=scale,
                             texture_rgba=texture_rgba)

    render = ngl.RenderTexture(texture_rgba)
    group = ngl.Group(children=(compute, render))

    if show_dbg_points:
        cuepoints = _get_compute_histogram_cuepoints()
        group.add_children(get_debug_points(cfg, cuepoints))

    return group
예제 #9
0
def compute_animation(cfg):
    cfg.duration = 5
    cfg.aspect_ratio = (1, 1)
    local_size = 2

    shader_version = '310 es' if cfg.backend == 'gles' else '430'
    shader_data = dict(
        version=shader_version,
        local_size=local_size,
    )
    compute_shader = _ANIMATION_COMPUTE % shader_data
    vertex_shader = _ANIMATION_VERT % shader_data
    fragment_shader = _ANIMATION_FRAG % shader_data

    vertices_data = array.array('f', [
        -0.5, -0.5, 0.0,
         0.5, -0.5, 0.0,
         0.5,  0.5, 0.0,
        -0.5,  0.5, 0.0,
    ])
    nb_vertices = 4

    input_vertices = ngl.BufferVec3(data=vertices_data)
    output_vertices = ngl.BufferVec3(data=vertices_data)
    input_block = ngl.Block(fields=[input_vertices], layout='std140')
    output_block = ngl.Block(fields=[output_vertices], layout='std430')

    rotate_animkf = [ngl.AnimKeyFrameFloat(0, 0),
                     ngl.AnimKeyFrameFloat(cfg.duration, 360)]
    rotate = ngl.Rotate(ngl.Identity(), axis=(0, 0, 1), anim=ngl.AnimatedFloat(rotate_animkf))
    transform = ngl.UniformMat4(transform=rotate)

    program = ngl.ComputeProgram(compute_shader)
    compute = ngl.Compute(nb_vertices / (local_size ** 2), 1, 1, program)
    compute.update_uniforms(transform=transform)
    compute.update_blocks(input_block=input_block, output_block=output_block)

    quad_buffer = ngl.BufferVec3(block=output_block, block_field=0)
    geometry = ngl.Geometry(quad_buffer, topology='triangle_fan')
    program = ngl.Program(vertex=vertex_shader, fragment=fragment_shader)
    render = ngl.Render(geometry, program)
    render.update_uniforms(color=ngl.UniformVec4(value=COLORS['sgreen']))

    return ngl.Group(children=(compute, render))
def _get_random_compute(cfg, rng, t0, t1):
    count = 10
    fragment_shader = cfg.get_frag("texture")

    vertex_shader = textwrap.dedent(
        """
        void main()
        {
            vec4 position = vec4(ngl_position, 1.0) + vec4(pos.data[ngl_instance_index], 0.0, 0.0);
            ngl_out_pos = ngl_projection_matrix * ngl_modelview_matrix * position;
            var_tex0_coord = (tex0_coord_matrix * vec4(ngl_uvcoord, 0.0, 1.0)).xy;
        }
        """
    )

    funcs = ("snake", "circle", "spread")

    compute_shader = textwrap.dedent(
        """
        #define TAU (2.0 * 3.14159265358979323846)

        vec2 snake(float i)
        {
            return vec2(i * 2.0 - 1.0, sin((time + i) * TAU));
        }

        vec2 circle(float i)
        {
            float angle = (time + i) * TAU;
            return vec2(sin(angle), cos(angle));
        }

        vec2 spread(float i)
        {
            float angle = i * TAU;
            return vec2(sin(angle), cos(angle)) * (time + i);
        }

        void main()
        {
            uint wg = gl_WorkGroupID.x;
            float i = float(wg) / float(gl_NumWorkGroups.x - 1U);
            pos.data[wg] = FUNC(i);
        }
        """.replace(
            "FUNC", rng.choice(funcs)
        )
    )

    pos = ngl.Block(fields=[ngl.BufferVec2(count=count, label="data")])

    time_animkf = [ngl.AnimKeyFrameFloat(t0, 0), ngl.AnimKeyFrameFloat(t1, 1)]

    compute_prog = ngl.ComputeProgram(compute_shader, workgroup_size=(1, 1, 1))
    compute_prog.update_properties(pos=ngl.ResourceProps(writable=True))

    compute = ngl.Compute(workgroup_count=(count, 1, 1), program=compute_prog)
    compute.update_resources(time=ngl.AnimatedFloat(time_animkf), pos=pos)

    geometry = _get_random_geometry(rng)
    program = ngl.Program(vertex=vertex_shader, fragment=cfg.get_frag("texture"))
    program.update_vert_out_vars(var_tex0_coord=ngl.IOVec2())
    render = ngl.Render(geometry, program, nb_instances=count, blending="src_over")
    render.update_frag_resources(tex0=_get_random_texture(cfg, rng))
    render.update_vert_resources(pos=pos)
    render = ngl.Scale(render, factors=(0.5, 0.5, 0))

    return ngl.Group(children=(compute, render))
예제 #11
0
def compute_histogram(cfg, show_dbg_points=False):
    cfg.duration = 10
    cfg.aspect_ratio = (1, 1)
    hsize, size, local_size = _N * _N, _N, _N // 2
    data = array.array("f")
    for i in range(size * size):
        data.extend((
            cfg.rng.uniform(0.0, 0.5),
            cfg.rng.uniform(0.25, 0.75),
            cfg.rng.uniform(0.5, 1.0),
            1.0,
        ))
    texture_buffer = ngl.BufferVec4(data=data)
    texture = ngl.Texture2D(width=size, height=size, data_src=texture_buffer)
    texture.set_format("r32g32b32a32_sfloat")

    histogram_block = ngl.Block(layout="std140", label="histogram")
    histogram_block.add_fields(
        ngl.BufferUInt(hsize, label="r"),
        ngl.BufferUInt(hsize, label="g"),
        ngl.BufferUInt(hsize, label="b"),
        ngl.UniformUIVec3(label="max"),
    )

    shader_params = dict(hsize=hsize, size=size, local_size=local_size)

    group_size = hsize // local_size
    clear_histogram_shader = _COMPUTE_HISTOGRAM_CLEAR % shader_params
    clear_histogram_program = ngl.ComputeProgram(clear_histogram_shader,
                                                 workgroup_size=(local_size, 1,
                                                                 1))
    clear_histogram_program.update_properties(hist=ngl.ResourceProps(
        writable=True))
    clear_histogram = ngl.Compute(
        workgroup_count=(group_size, 1, 1),
        program=clear_histogram_program,
        label="clear_histogram",
    )
    clear_histogram.update_resources(hist=histogram_block)

    group_size = size // local_size
    exec_histogram_shader = _COMPUTE_HISTOGRAM_EXEC % shader_params
    exec_histogram_program = ngl.ComputeProgram(exec_histogram_shader,
                                                workgroup_size=(local_size,
                                                                local_size, 1))
    exec_histogram_program.update_properties(hist=ngl.ResourceProps(
        writable=True))
    exec_histogram = ngl.Compute(workgroup_count=(group_size, group_size, 1),
                                 program=exec_histogram_program,
                                 label="compute_histogram")
    exec_histogram.update_resources(hist=histogram_block, source=texture)
    exec_histogram_program.update_properties(source=ngl.ResourceProps(
        as_image=True))

    quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0))
    program = ngl.Program(
        vertex=_RENDER_HISTOGRAM_VERT,
        fragment=_RENDER_HISTOGRAM_FRAG % shader_params,
    )
    program.update_vert_out_vars(var_uvcoord=ngl.IOVec2())
    render = ngl.Render(quad, program, label="render_histogram")
    render.update_frag_resources(hist=histogram_block)

    group = ngl.Group(children=(clear_histogram, exec_histogram, render))
    if show_dbg_points:
        cuepoints = _get_compute_histogram_cuepoints()
        group.add_children(get_debug_points(cfg, cuepoints))
    return group
예제 #12
0
def particules(cfg, particules=32):
    '''Particules demo using compute shaders and instancing'''
    random.seed(0)

    shader_version = '310 es' if cfg.backend == 'gles' else '430'
    shader_header = '#version %s\n' % shader_version
    compute_shader = shader_header + cfg.get_comp('particules')
    vertex_shader = shader_header + cfg.get_vert('particules')
    fragment_shader = shader_header + cfg.get_frag('particules')

    cfg.duration = 6

    x = 64
    p = x * particules

    positions = array.array('f')
    velocities = array.array('f')

    for i in range(p):
        positions.extend([
            random.uniform(-1.0, 1.0),
            random.uniform(0.0, 1.0),
            0.0,
        ])

        velocities.extend([
            random.uniform(-0.01, 0.01),
            random.uniform(-0.05, 0.05),
        ])

    ipositions = ngl.Block(fields=[ngl.BufferVec3(data=positions)], layout='std430')
    ivelocities = ngl.Block(fields=[ngl.BufferVec2(data=velocities)], layout='std430')
    opositions = ngl.Block(fields=[ngl.BufferVec3(count=p)], layout='std430')

    animkf = [ngl.AnimKeyFrameFloat(0, 0),
              ngl.AnimKeyFrameFloat(cfg.duration, 1)]
    utime = ngl.AnimatedFloat(animkf)
    uduration = ngl.UniformFloat(cfg.duration)

    cp = ngl.ComputeProgram(compute_shader)

    c = ngl.Compute(x, particules, 1, cp)
    c.update_uniforms(
        time=utime,
        duration=uduration,
    )
    c.update_blocks(
        ipositions_buffer=ipositions,
        ivelocities_buffer=ivelocities,
        opositions_buffer=opositions,
    )

    quad_width = 0.01
    quad = ngl.Quad(
        corner=(-quad_width/2, -quad_width/2, 0),
        width=(quad_width, 0, 0),
        height=(0, quad_width, 0)
    )
    p = ngl.Program(
        vertex=vertex_shader,
        fragment=fragment_shader,
    )
    r = ngl.Render(quad, p, nb_instances=particules)
    r.update_uniforms(color=ngl.UniformVec4(value=(0, .6, .8, .9)))
    r.update_blocks(positions_buffer=opositions)

    r = ngl.GraphicConfig(r,
                          blend=True,
                          blend_src_factor='src_alpha',
                          blend_dst_factor='one_minus_src_alpha',
                          blend_src_factor_a='zero',
                          blend_dst_factor_a='one')

    g = ngl.Group()
    g.add_children(c, r)

    return ngl.Camera(g)
예제 #13
0
def histogram(cfg):
    '''Histogram using compute shaders'''
    m0 = cfg.medias[0]
    cfg.duration = m0.duration
    cfg.aspect_ratio = (m0.width, m0.height)
    g = ngl.Group()

    m = ngl.Media(cfg.medias[0].filename)
    t = ngl.Texture2D(data_src=m)

    h = ngl.Block(label='histogram_block', layout='std430')
    h.add_fields(
        ngl.BufferUInt(256, label='r'),
        ngl.BufferUInt(256, label='g'),
        ngl.BufferUInt(256, label='b'),
        ngl.UniformUInt(label='maximum'),
    )

    q = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0))
    p = ngl.Program(vertex=cfg.get_vert('texture'),
                    fragment=cfg.get_frag('texture'))
    p.update_vert_out_vars(var_uvcoord=ngl.IOVec2(),
                           var_tex0_coord=ngl.IOVec2())
    r = ngl.Render(q, p)
    r.update_frag_resources(tex0=t)
    proxy_size = 128
    proxy = ngl.Texture2D(width=proxy_size, height=proxy_size)
    rtt = ngl.RenderToTexture(r)
    rtt.add_color_textures(proxy)
    g.add_children(rtt)

    compute_program = ngl.ComputeProgram(cfg.get_comp('histogram-clear'))
    compute = ngl.Compute(256, 1, 1, compute_program, label='histogram-clear')
    compute.update_resources(hist=h)
    g.add_children(compute)

    local_size = 8
    group_size = proxy_size / local_size
    compute_shader = cfg.get_comp('histogram-exec') % {
        'local_size': local_size
    }
    compute_program = ngl.ComputeProgram(compute_shader)
    compute = ngl.Compute(group_size,
                          group_size,
                          1,
                          compute_program,
                          label='histogram-exec')
    compute.update_resources(hist=h, source=proxy)
    compute_program.update_properties(source=ngl.ResourceProps(as_image=True))
    g.add_children(compute)

    q = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0))
    p = ngl.Program(vertex=cfg.get_vert('histogram-display'),
                    fragment=cfg.get_frag('histogram-display'))
    p.update_vert_out_vars(var_uvcoord=ngl.IOVec2(),
                           var_tex0_coord=ngl.IOVec2())
    render = ngl.Render(q, p)
    render.update_frag_resources(tex0=t, hist=h)
    g.add_children(render)

    return g
예제 #14
0
def particles(cfg, particles=32):
    '''Particules demo using compute shaders and instancing'''
    random.seed(0)

    compute_shader = cfg.get_comp('particles')
    vertex_shader = cfg.get_vert('particles')
    fragment_shader = cfg.get_frag('color')

    cfg.duration = 6

    x = 64
    p = x * particles

    positions = array.array('f')
    velocities = array.array('f')

    for i in range(p):
        positions.extend([
            random.uniform(-1.0, 1.0),
            random.uniform(0.0, 1.0),
            0.0,
        ])

        velocities.extend([
            random.uniform(-0.01, 0.01),
            random.uniform(-0.05, 0.05),
        ])

    ipositions = ngl.Block(fields=[ngl.BufferVec3(data=positions, label='data')], layout='std430')
    ivelocities = ngl.Block(fields=[ngl.BufferVec2(data=velocities, label='data')], layout='std430')
    opositions = ngl.Block(fields=[ngl.BufferVec3(count=p, label='data')], layout='std430')

    animkf = [ngl.AnimKeyFrameFloat(0, 0),
              ngl.AnimKeyFrameFloat(cfg.duration, 1)]
    utime = ngl.AnimatedFloat(animkf)
    uduration = ngl.UniformFloat(cfg.duration)

    cp = ngl.ComputeProgram(compute_shader, workgroup_size=(1, 1, 1))
    cp.update_properties(opositions=ngl.ResourceProps(writable=True))

    c = ngl.Compute(workgroup_count=(x, particles, 1), program=cp)
    c.update_resources(
        time=utime,
        duration=uduration,
        ipositions=ipositions,
        ivelocities=ivelocities,
        opositions=opositions,
    )

    quad_width = 0.01
    quad = ngl.Quad(
        corner=(-quad_width/2, -quad_width/2, 0),
        width=(quad_width, 0, 0),
        height=(0, quad_width, 0)
    )
    p = ngl.Program(
        vertex=vertex_shader,
        fragment=fragment_shader,
    )
    p.update_vert_out_vars(var_uvcoord=ngl.IOVec2(), var_tex0_coord=ngl.IOVec2())
    r = ngl.Render(quad, p, nb_instances=particles)
    r.update_frag_resources(color=ngl.UniformVec4(value=(0, .6, .8, .9)))
    r.update_vert_resources(positions=opositions)

    r = ngl.GraphicConfig(r,
                          blend=True,
                          blend_src_factor='src_alpha',
                          blend_dst_factor='one_minus_src_alpha',
                          blend_src_factor_a='zero',
                          blend_dst_factor_a='one')

    g = ngl.Group()
    g.add_children(c, r)

    return ngl.Camera(g)
def particles(cfg, particles=32):
    """Particules demo using compute shaders and instancing"""

    compute_shader = cfg.get_comp("particles")
    vertex_shader = cfg.get_vert("particles")
    fragment_shader = cfg.get_frag("color")

    cfg.duration = 6

    x = 64
    p = x * particles

    positions = array.array("f")
    velocities = array.array("f")

    for i in range(p):
        positions.extend([
            cfg.rng.uniform(-1.0, 1.0),
            cfg.rng.uniform(0.0, 1.0),
            0.0,
        ])

        velocities.extend([
            cfg.rng.uniform(-0.01, 0.01),
            cfg.rng.uniform(-0.05, 0.05),
        ])

    ipositions = ngl.Block(
        fields=[ngl.BufferVec3(data=positions, label="data")], layout="std430")
    ivelocities = ngl.Block(
        fields=[ngl.BufferVec2(data=velocities, label="data")],
        layout="std430")
    opositions = ngl.Block(fields=[ngl.BufferVec3(count=p, label="data")],
                           layout="std430")

    animkf = [
        ngl.AnimKeyFrameFloat(0, 0),
        ngl.AnimKeyFrameFloat(cfg.duration, 1)
    ]
    utime = ngl.AnimatedFloat(animkf)
    uduration = ngl.UniformFloat(cfg.duration)

    cp = ngl.ComputeProgram(compute_shader, workgroup_size=(1, 1, 1))
    cp.update_properties(opositions=ngl.ResourceProps(writable=True))

    c = ngl.Compute(workgroup_count=(x, particles, 1), program=cp)
    c.update_resources(
        time=utime,
        duration=uduration,
        ipositions=ipositions,
        ivelocities=ivelocities,
        opositions=opositions,
    )

    quad_width = 0.01
    quad = ngl.Quad(corner=(-quad_width / 2, -quad_width / 2, 0),
                    width=(quad_width, 0, 0),
                    height=(0, quad_width, 0))
    p = ngl.Program(
        vertex=vertex_shader,
        fragment=fragment_shader,
    )
    p.update_vert_out_vars(var_uvcoord=ngl.IOVec2(),
                           var_tex0_coord=ngl.IOVec2())
    r = ngl.Render(quad, p, nb_instances=particles, blending="src_over")
    r.update_frag_resources(color=ngl.UniformVec3(value=(0, 0.6, 0.8)),
                            opacity=ngl.UniformFloat(0.9))
    r.update_vert_resources(positions=opositions)

    g = ngl.Group()
    g.add_children(c, r)

    return ngl.Camera(g)
예제 #16
0
def compute_histogram(cfg, show_dbg_points=False):
    random.seed(0)
    cfg.duration = 10
    cfg.aspect_ratio = (1, 1)
    hsize, size, local_size = _N * _N, _N, _N // 2
    data = array.array('f')
    for i in range(size * size):
        data.extend((
            random.uniform(0.0, 0.5),
            random.uniform(0.25, 0.75),
            random.uniform(0.5, 1.0),
            1.0,
        ))
    texture_buffer = ngl.BufferVec4(data=data)
    texture = ngl.Texture2D(width=size, height=size, data_src=texture_buffer)

    histogram_block = ngl.Block(layout='std430', label='histogram')
    histogram_block.add_fields(
        ngl.BufferUInt(hsize),
        ngl.BufferUInt(hsize),
        ngl.BufferUInt(hsize),
        ngl.UniformUIVec3(),
    )

    shader_version = '310 es' if cfg.backend == 'gles' else '430'
    shader_header = '#version %s\n' % shader_version
    if cfg.backend == 'gles' and cfg.system == 'Android':
        shader_header += '#extension GL_ANDROID_extension_pack_es31a: require\n'
    shader_params = dict(hsize=hsize, size=size, local_size=local_size)

    group_size = hsize // local_size
    clear_histogram_shader = _COMPUTE_HISTOGRAM_CLEAR % shader_params
    clear_histogram_program = ngl.ComputeProgram(shader_header + clear_histogram_shader)
    clear_histogram = ngl.Compute(
        group_size,
        1,
        1,
        clear_histogram_program,
        label='clear_histogram',
    )
    clear_histogram.update_blocks(histogram=histogram_block)

    group_size = size // local_size
    exec_histogram_shader = _COMPUTE_HISTOGRAM_EXEC % shader_params
    exec_histogram_program = ngl.ComputeProgram(shader_header + exec_histogram_shader)
    exec_histogram = ngl.Compute(
        group_size,
        group_size,
        1,
        exec_histogram_program,
        label='compute_histogram'
    )
    exec_histogram.update_blocks(histogram=histogram_block)
    exec_histogram.update_textures(source=texture)

    quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0))
    program = ngl.Program(
        vertex=shader_header + _RENDER_HISTOGRAM_VERT,
        fragment=shader_header + _RENDER_HISTOGRAM_FRAG % shader_params,
    )
    render = ngl.Render(quad, program, label='render_histogram')
    render.update_blocks(histogram=histogram_block)

    group = ngl.Group(children=(clear_histogram, exec_histogram, render,))
    if show_dbg_points:
        cuepoints = _get_compute_histogram_cuepoints()
        group.add_children(get_debug_points(cfg, cuepoints))
    return group