示例#1
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)
示例#2
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
示例#3
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
示例#4
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
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))
示例#6
0
def get_random_block_info(spec, seed=0, layout=LAYOUTS[0], color_tint=True):

    # Seed only defines the random for the position of the fields
    random.seed(seed)
    fields_pos = random.sample(range(len(spec)), len(spec))

    # Always the same colors whatever the user seed
    random.seed(0)

    fields_info = []
    max_id_len = 0
    for i, field_info in enumerate(spec):
        node = field_info['func'](field_info.get('data'))
        node.set_label(field_info['name'])
        field_info['node'] = node
        field_info['decl'] = _get_field_decl(layout, field_info)
        field_info['pos'] = fields_pos.index(i)
        max_id_len = max(len(field_info['decl']), max_id_len)
        if color_tint:
            hue = random.uniform(0, 1)
            field_info['color'] = colorsys.hls_to_rgb(hue, 0.6, 1.0)
        else:
            field_info['color'] = (1, 1, 1)
        fields_info.append(field_info)

    shuf_fields = [fields_info[pos] for pos in fields_pos]
    color_fields = [(f['name'], ngl.UniformVec3(f['color'], label=f['name']))
                    for f in fields_info]
    block_fields = [(f['name'], f['node']) for f in shuf_fields]
    if layout == 'uniform':
        color_fields = dict(color_fields)
        block_fields = dict(block_fields)
    else:
        color_fields = ngl.Block(fields=[f for n, f in color_fields],
                                 layout=layout,
                                 label='colors_block')
        block_fields = ngl.Block(fields=[f for n, f in block_fields],
                                 layout=layout,
                                 label='fields_block')

    pad = lambda s: (max_id_len - len(s)) * ' '
    block_definition = '\n'.join('%s;%s // #%02d' %
                                 (f['decl'], pad(f['decl']), i)
                                 for i, f in enumerate(shuf_fields))

    color_prefix = 'color_' if layout == 'uniform' else ''
    color_u = 'uniform ' if layout == 'uniform' else ''
    color_definition = '\n'.join(
        color_u + 'vec3 %s;' % (color_prefix + f['name']) for f in fields_info)

    return fields_info, block_fields, color_fields, block_definition, color_definition
示例#7
0
def _get_live_shared_uniform_with_block_scene(cfg, color, layout,
                                              debug_positions):
    vertex = '''
void main()
{
    ngl_out_pos = ngl_projection_matrix * ngl_modelview_matrix * ngl_position;
}
'''
    fragment = '''
void main()
{
    ngl_out_color = data.color;
}
'''
    program = ngl.Program(vertex=vertex, fragment=fragment)
    group = ngl.Group()
    for i in range(2):
        block = ngl.Block(fields=[color], layout=layout)
        quad = ngl.Quad((-1 + i, -1 + i, 0), (1, 0, 0), (0, 1, 0))
        render = ngl.Render(quad, program)
        render.update_frag_resources(data=block)
        group.add_children(render)
    if debug_positions:
        group.add_children(get_debug_points(cfg, _SHARED_UNIFORM_CUEPOINTS))
    return group
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
示例#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))
示例#10
0
def _data_vertex_and_fragment_blocks(cfg, layout):
    """
    This test ensures that the block bindings are properly set by pgcraft
    when UBOs or SSBOs are bound to different stages.
    """
    cfg.aspect_ratio = (1, 1)

    src = ngl.Block(
        fields=[
            ngl.UniformVec3(value=COLORS.red, label="color"),
            ngl.UniformFloat(value=0.5, label="opacity"),
        ],
        layout="std140",
    )
    dst = ngl.Block(
        fields=[
            ngl.UniformVec3(value=COLORS.white, label="color"),
        ],
        layout=layout,
    )
    vert = textwrap.dedent("""\
        void main()
        {
            ngl_out_pos = ngl_projection_matrix * ngl_modelview_matrix * vec4(ngl_position, 1.0);
            var_src = vec4(src.color, 1.0) * src.opacity;
        }
        """)
    frag = textwrap.dedent("""\
        void main()
        {
            vec3 color = var_src.rgb + (1.0 - var_src.a) * dst.color;
            ngl_out_color = vec4(color, 1.0);
        }
        """)

    program = ngl.Program(vertex=vert, fragment=frag)
    program.update_vert_out_vars(var_src=ngl.IOVec4(), )
    geometry = ngl.Quad(corner=(-1, -1, 0), width=(2, 0, 0), height=(0, 2, 0))
    render = ngl.Render(geometry, program)
    render.update_vert_resources(src=src)
    render.update_frag_resources(dst=dst)

    return render
示例#11
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
示例#12
0
def _get_data_streamed_buffer_vec4_scene(cfg, scale, show_dbg_points):
    duration = _N
    cfg.duration = duration * scale
    cfg.aspect_ratio = (1, 1)
    size, data_size, = _N, _N * _N

    time_anim = None
    if scale != 1:
        kfs = [
            ngl.AnimKeyFrameFloat(0, 0),
            ngl.AnimKeyFrameFloat(cfg.duration, duration),
        ]
        time_anim = ngl.AnimatedTime(kfs)

    pts_data = array.array('q')
    assert pts_data.itemsize == 8

    for i in range(duration):
        offset = 10000 if i == 0 else 0
        pts_data.extend([i * 1000000 + offset])

    vec4_data = array.array('f')
    for i in range(duration):
        for j in range(data_size):
            v = i / float(duration) + j / float(data_size * duration)
            vec4_data.extend([v, v, v, v])

    pts_buffer = ngl.BufferInt64(data=pts_data)
    vec4_buffer = ngl.BufferVec4(data=vec4_data)
    streamed_buffer = ngl.StreamedBufferVec4(data_size,
                                             pts_buffer,
                                             vec4_buffer,
                                             time_anim=time_anim,
                                             label='data')
    streamed_block = ngl.Block(layout='std140',
                               label='streamed_block',
                               fields=(streamed_buffer, ))

    shader_params = dict(data_size=data_size, size=size)

    quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0))
    program = ngl.Program(
        vertex=_RENDER_STREAMEDBUFFER_VERT,
        fragment=_RENDER_STREAMEDBUFFER_FRAG % shader_params,
    )
    program.update_vert_out_vars(var_uvcoord=ngl.IOVec2())
    render = ngl.Render(quad, program)
    render.update_frag_resources(streamed=streamed_block)

    group = ngl.Group(children=(render, ))
    if show_dbg_points:
        cuepoints = _get_data_streamed_buffer_cuepoints()
        group.add_children(get_debug_points(cfg, cuepoints))
    return group
示例#13
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
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)
示例#15
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
def get_field_scene(cfg, spec, category, field_type, seed, debug_positions,
                    layout, color_tint):
    """
    Build a scene testing that a given data has been properly uploaded to the
    GPU memory.

    - `spec` contains all the fields that should also be declared (either in a
      block or as uniforms). All the fields are shuffled such that the field we
      are testing is always in a random position. This makes sure that we get
      the data alignment right.
    - `category` and `field_type` are filters in the spec to select the
      field(s) from which we want to read the data
    - `seed` is used to control the fields shuffling
    - `debug_positions` controls whether there are debug circles in the scene
      in order to make sure we are reading back the data colors at the
      appropriate position
    - `layout` controls the block layout or whether we are working with uniforms
    - `color_tint` is a debug helper to give a different color for each field
      (because if they have the same data, it is hard to indiscriminate them).
    """

    cfg.aspect_ratio = (1, 1)

    # Seed only defines the random for the position of the fields
    fields_pos = random.Random(seed).sample(range(len(spec)), len(spec))

    # Always the same colors whatever the user seed
    clr_rng = random.Random(0)

    fields_info = []
    for i, field_info in enumerate(spec):
        create_func = field_info.get("func")
        if create_func is None:
            create_func = _FUNCS["{category}_{type}".format(**field_info)]
        node = create_func(field_info.get("data"))
        node.set_label(field_info["name"])
        field_info["node"] = node
        if color_tint:
            hue = clr_rng.uniform(0, 1)
            field_info["color"] = colorsys.hls_to_rgb(hue, 0.6, 1.0)
        else:
            field_info["color"] = (1, 1, 1)
        fields_info.append(field_info)

    shuf_fields = [fields_info[pos] for pos in fields_pos]
    color_fields = [(f["name"], ngl.UniformVec3(f["color"], label=f["name"]))
                    for f in fields_info]
    block_fields = [(f["name"], f["node"]) for f in shuf_fields]
    if layout == "uniform":
        color_fields = dict(color_fields)
        block_fields = dict(block_fields)
    else:
        color_fields = ngl.Block(fields=[f for n, f in color_fields],
                                 layout=layout,
                                 label="colors_block")
        block_fields = ngl.Block(fields=[f for n, f in block_fields],
                                 layout=layout,
                                 label="fields_block")

    fields = match_fields(fields_info, category, field_type)

    func_calls = []
    func_definitions = []
    for i, field in enumerate(fields):
        field_len = field.get("len")
        func_calls.append("get_color_{}(w, h, 0.0, {:f} * h)".format(
            field["name"], i))
        func_definitions.append(
            _get_display_glsl_func(layout,
                                   field["name"],
                                   field["type"],
                                   field_len=field_len))

    frag_data = dict(
        func_definitions="\n".join(func_definitions),
        func_calls=" + ".join(func_calls),
    )

    fragment = _FIELDS_FRAG % frag_data
    vertex = _FIELDS_VERT

    program = ngl.Program(vertex=vertex, fragment=fragment)
    program.update_vert_out_vars(var_uvcoord=ngl.IOVec2())
    quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0))
    render = ngl.Render(quad, program)

    if isinstance(color_fields, dict):
        assert isinstance(block_fields, dict)
        field_names = {f["name"] for f in fields}
        d = {}
        d.update(("color_" + n, u) for (n, u) in color_fields.items()
                 if n in field_names)
        d.update(("field_" + n, u) for (n, u) in block_fields.items()
                 if n in field_names)
        render.update_frag_resources(**d)
    else:
        render.update_frag_resources(fields=block_fields, colors=color_fields)

    render.update_frag_resources(nb_fields=ngl.UniformInt(len(fields)))

    if debug_positions:
        debug_points = get_data_debug_positions(fields)
        dbg_circles = get_debug_points(cfg, debug_points, text_size=(0.2, 0.1))
        g = ngl.Group(children=(render, dbg_circles))
        return g

    return render
示例#17
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)
示例#18
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
示例#19
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
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))
示例#21
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)