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)
def velocity_triangle_rotate(cfg): cfg.duration = 5.0 cfg.aspect_ratio = (1, 1) anim_kf = [ ngl.AnimKeyFrameFloat(0, 0), ngl.AnimKeyFrameFloat(cfg.duration, 360 * 3, "circular_in_out"), ] anim = ngl.AnimatedFloat(anim_kf) velocity = ngl.VelocityFloat(anim) frag = textwrap.dedent("""\ void main() { float v = clamp(velocity / 3000., 0.0, 1.0); ngl_out_color = vec4(v, v / 2.0, 0.0, 1.0); } """) p0, p1, p2 = equilateral_triangle_coords(2.0) triangle = ngl.RenderColor(COLORS.white, geometry=ngl.Triangle(p0, p1, p2)) triangle = ngl.Rotate(triangle, angle=anim) prog_c = ngl.Program(vertex=cfg.get_vert("color"), fragment=frag) circle = ngl.Render(ngl.Circle(radius=1.0, npoints=128), prog_c) circle.update_frag_resources(velocity=velocity) return ngl.Group(children=(circle, triangle))
def triangle(cfg, size=0.5): '''Rotating triangle with edge coloring specified in a vertex attribute''' b = size * math.sqrt(3) / 2.0 c = size * 1 / 2. cfg.duration = 3. cfg.aspect_ratio = (1, 1) colors_data = array.array( 'f', [0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0]) colors_buffer = ngl.BufferVec4(data=colors_data) triangle = ngl.Triangle((-b, -c, 0), (b, -c, 0), (0, size, 0)) p = ngl.Program(fragment=cfg.get_frag('color'), vertex=cfg.get_vert('triangle')) p.update_vert_out_vars(color=ngl.IOVec4()) node = ngl.Render(triangle, p) node.update_attributes(edge_color=colors_buffer) animkf = [ ngl.AnimKeyFrameFloat(0, 0), ngl.AnimKeyFrameFloat(cfg.duration / 3., -360 / 3., 'exp_in_out'), ngl.AnimKeyFrameFloat(2 * cfg.duration / 3., -2 * 360 / 3., 'exp_in_out'), ngl.AnimKeyFrameFloat(cfg.duration, -360, 'exp_in_out') ] node = ngl.Rotate(node, anim=ngl.AnimatedFloat(animkf)) return node
def _get_rtt_scene(cfg, features='depth', texture_ds_format=None, samples=0, mipmap_filter='none', sample_depth=False): cfg.duration = 10 cfg.aspect_ratio = (1, 1) cube = _get_cube() program = ngl.Program(vertex=_RENDER_CUBE_VERT, fragment=_RENDER_CUBE_FRAG) program.update_vert_out_vars(var_normal=ngl.IOVec3()) render = ngl.Render(cube, program) render = ngl.Scale(render, (0.5, 0.5, 0.5)) for i in range(3): rot_animkf = ngl.AnimatedFloat([ ngl.AnimKeyFrameFloat(0, 0), ngl.AnimKeyFrameFloat(cfg.duration, 360 * (i + 1)) ]) axis = [int(i == x) for x in range(3)] render = ngl.Rotate(render, axis=axis, anim=rot_animkf) config = ngl.GraphicConfig(render, depth_test=True) camera = ngl.Camera( config, eye=(0.0, 0.0, 3.0), center=(0.0, 0.0, 0.0), up=(0.0, 1.0, 0.0), perspective=(45.0, cfg.aspect_ratio_float), clipping=(1.0, 10.0), ) size = 1024 texture_depth = None if texture_ds_format: texture_depth = ngl.Texture2D(width=size, height=size, format=texture_ds_format) texture = ngl.Texture2D( width=size, height=size, min_filter='linear', mipmap_filter=mipmap_filter, ) rtt = ngl.RenderToTexture( camera, [texture], features=features, depth_texture=texture_depth, samples=samples, clear_color=(0, 0, 0, 1), ) quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0)) if sample_depth: program = ngl.Program(vertex=cfg.get_vert('texture'), fragment=_RENDER_DEPTH) program.update_vert_out_vars(var_tex0_coord=ngl.IOVec2(), var_uvcoord=ngl.IOVec2()) render = ngl.Render(quad, program) render.update_frag_resources(tex0=texture_depth) else: program = ngl.Program(vertex=cfg.get_vert('texture'), fragment=cfg.get_frag('texture')) program.update_vert_out_vars(var_tex0_coord=ngl.IOVec2(), var_uvcoord=ngl.IOVec2()) render = ngl.Render(quad, program) render.update_frag_resources(tex0=texture) return ngl.Group(children=(rtt, render))
def animated_uniform(cfg): '''Uniform mat4 animated with a transform chain''' m0 = cfg.medias[0] cfg.aspect_ratio = (m0.width, m0.height) q = ngl.Quad((-0.5, -0.5, 0), (1, 0, 0), (0, 1, 0)) m = ngl.Media(m0.filename) t = ngl.Texture2D(data_src=m) p = ngl.Program(vertex=cfg.get_vert('texture'), fragment=cfg.get_frag('matrix-transform')) ts = ngl.Render(q, p) ts.update_textures(tex0=t) scale_animkf = [ ngl.AnimKeyFrameVec3(0, (1, 1, 1)), ngl.AnimKeyFrameVec3(cfg.duration, (0.1, 0.1, 0.1), 'quartic_out') ] s = ngl.Scale(ngl.Identity(), anim=ngl.AnimatedVec3(scale_animkf)) rotate_animkf = [ ngl.AnimKeyFrameFloat(0, 0), ngl.AnimKeyFrameFloat(cfg.duration, 360, 'exp_out') ] r = ngl.Rotate(s, axis=(0, 0, 1), anim=ngl.AnimatedFloat(rotate_animkf)) u = ngl.UniformMat4(transform=r) ts.update_uniforms(matrix=u) return ts
def animated_uniform(cfg): """Uniform mat4 animated with a transform chain""" m0 = cfg.medias[0] cfg.aspect_ratio = (m0.width, m0.height) q = ngl.Quad((-0.5, -0.5, 0), (1, 0, 0), (0, 1, 0)) m = ngl.Media(m0.filename) t = ngl.Texture2D(data_src=m) p = ngl.Program(vertex=cfg.get_vert("texture"), fragment=cfg.get_frag("matrix-transform")) p.update_vert_out_vars(var_uvcoord=ngl.IOVec2(), var_tex0_coord=ngl.IOVec2()) ts = ngl.Render(q, p) ts.update_frag_resources(tex0=t) scale_animkf = [ ngl.AnimKeyFrameVec3(0, (1, 1, 1)), ngl.AnimKeyFrameVec3(cfg.duration, (0.1, 0.1, 0.1), "quartic_out"), ] s = ngl.Scale(ngl.Identity(), factors=ngl.AnimatedVec3(scale_animkf)) rotate_animkf = [ ngl.AnimKeyFrameFloat(0, 0), ngl.AnimKeyFrameFloat(cfg.duration, 360, "exp_out") ] r = ngl.Rotate(s, axis=(0, 0, 1), angle=ngl.AnimatedFloat(rotate_animkf)) u = ngl.UniformMat4(transform=r) ts.update_frag_resources(matrix=u) return ts
def py_bindings_allow_node(): c = ngl.Camera(eye=(0, 1, 0)) assert c.set_eye(ngl.EvalVec3()) == 0 assert c.set_eye(1, 0, 0) == 0 c = ngl.Camera(eye=ngl.NoiseVec3()) assert c.set_eye(1, 0, 0) == 0 assert c.set_eye(ngl.UniformVec3()) == 0 r = ngl.Rotate(angle=30) assert r.set_angle(ngl.NoiseFloat()) == 0 assert r.set_angle(-45) == 0 r = ngl.Rotate(angle=ngl.EvalFloat()) assert r.set_angle(90) == 0 assert r.set_angle(ngl.UniformFloat()) == 0
def triangle(cfg, size=4 / 3): """Rotating triangle with edge coloring specified in a vertex attribute""" cfg.duration = 3.0 cfg.aspect_ratio = (1, 1) colors_data = array.array("f", [0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0]) colors_buffer = ngl.BufferVec3(data=colors_data) p0, p1, p2 = equilateral_triangle_coords(size) triangle = ngl.Triangle(p0, p1, p2) p = ngl.Program(fragment=cfg.get_frag("color"), vertex=cfg.get_vert("triangle")) p.update_vert_out_vars(color=ngl.IOVec3()) node = ngl.Render(triangle, p) node.update_attributes(edge_color=colors_buffer) node.update_frag_resources(opacity=ngl.UniformFloat(1)) animkf = [ ngl.AnimKeyFrameFloat(0, 0), ngl.AnimKeyFrameFloat(cfg.duration / 3.0, -360 / 3.0, "exp_in_out"), ngl.AnimKeyFrameFloat(2 * cfg.duration / 3.0, -2 * 360 / 3.0, "exp_in_out"), ngl.AnimKeyFrameFloat(cfg.duration, -360, "exp_in_out"), ] node = ngl.Rotate(node, angle=ngl.AnimatedFloat(animkf)) return node
def rtt_clear_attachment_with_timeranges(cfg): cfg.aspect_ratio = (1, 1) # Time-disabled full screen white quad render = ngl.RenderColor(COLORS.white) time_range_filter = ngl.TimeRangeFilter(render) time_range_filter.add_ranges(ngl.TimeRangeModeNoop(0)) # Intermediate no-op RTT to force the use of a different render pass internally texture = ngl.Texture2D(width=32, height=32) rtt_noop = ngl.RenderToTexture(ngl.Identity(), [texture]) # Centered rotating quad quad = ngl.Quad((-0.5, -0.5, 0), (1, 0, 0), (0, 1, 0)) render = ngl.RenderColor(COLORS.orange, geometry=quad) animkf = [ngl.AnimKeyFrameFloat(0, 0), ngl.AnimKeyFrameFloat(cfg.duration, -360)] render = ngl.Rotate(render, angle=ngl.AnimatedFloat(animkf)) group = ngl.Group(children=(time_range_filter, rtt_noop, render)) # Root RTT texture = ngl.Texture2D(width=512, height=512) rtt = ngl.RenderToTexture(group, [texture]) # Full screen render of the root RTT result render = ngl.RenderTexture(texture) return ngl.Group(children=(rtt, render))
def animated_square(cfg, color=(1, 0.66, 0), rotate=True, scale=True, translate=True): """Animated Translate/Scale/Rotate on a square""" cfg.duration = 5.0 cfg.aspect_ratio = (1, 1) sz = 1 / 3.0 q = ngl.Quad((-sz / 2, -sz / 2, 0), (sz, 0, 0), (0, sz, 0)) node = ngl.RenderColor(color, geometry=q) coords = [(-1, 1), (1, 1), (1, -1), (-1, -1), (-1, 1)] if rotate: animkf = (ngl.AnimKeyFrameFloat(0, 0), ngl.AnimKeyFrameFloat(cfg.duration, 360)) node = ngl.Rotate(node, angle=ngl.AnimatedFloat(animkf)) if scale: animkf = ( ngl.AnimKeyFrameVec3(0, (1, 1, 1)), ngl.AnimKeyFrameVec3(cfg.duration / 2, (2, 2, 2)), ngl.AnimKeyFrameVec3(cfg.duration, (1, 1, 1)), ) node = ngl.Scale(node, factors=ngl.AnimatedVec3(animkf)) if translate: animkf = [] tscale = 1.0 / float(len(coords) - 1) * cfg.duration for i, xy in enumerate(coords): pos = (xy[0] * 0.5, xy[1] * 0.5, 0) t = i * tscale animkf.append(ngl.AnimKeyFrameVec3(t, pos)) node = ngl.Translate(node, vector=ngl.AnimatedVec3(animkf)) return node
def cube(cfg, display_depth_buffer=False): ''' Cube with a common media Texture but a different color tainting on each side. Also includes a depth map visualization. ''' cube = ngl.Group(label='cube') frag_data = cfg.get_frag('tex-tint') program = ngl.Program(fragment=frag_data) texture = ngl.Texture2D(data_src=ngl.Media(cfg.medias[0].filename)) children = [_get_cube_side(texture, program, qi[0], qi[1], qi[2], qi[3]) for qi in _get_cube_quads()] cube.add_children(*children) for i in range(3): rot_animkf = ngl.AnimatedFloat([ngl.AnimKeyFrameFloat(0, 0), ngl.AnimKeyFrameFloat(cfg.duration, 360 * (i + 1))]) axis = [int(i == x) for x in range(3)] cube = ngl.Rotate(cube, axis=axis, anim=rot_animkf) config = ngl.GraphicConfig(cube, depth_test=True) camera = ngl.Camera(config) camera.set_eye(0.0, 0.0, 2.0) camera.set_center(0.0, 0.0, 0.0) camera.set_up(0.0, 1.0, 0.0) camera.set_perspective(45.0, cfg.aspect_ratio_float) camera.set_clipping(1.0, 10.0) if not display_depth_buffer: return camera else: group = ngl.Group() depth_texture = ngl.Texture2D() depth_texture.set_format('d16_unorm') depth_texture.set_width(640) depth_texture.set_height(480) texture = ngl.Texture2D() texture.set_width(640) texture.set_height(480) rtt = ngl.RenderToTexture(camera) rtt.add_color_textures(texture) rtt.set_depth_texture(depth_texture) quad = ngl.Quad((-1.0, -1.0, 0), (1, 0, 0), (0, 1, 0)) program = ngl.Program() render = ngl.Render(quad, program) render.update_textures(tex0=texture) group.add_children(rtt, render) quad = ngl.Quad((0.0, 0.0, 0), (1, 0, 0), (0, 1, 0)) program = ngl.Program() render = ngl.Render(quad, program) render.update_textures(tex0=depth_texture) group.add_children(rtt, render) return group
def animated_camera(cfg, rotate=True): '''Animated camera around a scene''' g = ngl.Group() q = ngl.Quad((-0.5, -0.5, 0), (1, 0, 0), (0, 1, 0)) m = ngl.Media(cfg.medias[0].filename) t = ngl.Texture2D(data_src=m) program = ngl.Program(vertex=cfg.get_vert('texture'), fragment=cfg.get_frag('texture')) program.update_vert_out_vars(var_uvcoord=ngl.IOVec2(), var_tex0_coord=ngl.IOVec2()) node = ngl.Render(q, program) node.update_frag_resources(tex0=t) g.add_children(node) translate = ngl.Translate(node, vector=(-0.6, 0.8, -1)) g.add_children(translate) translate = ngl.Translate(node, vector=(0.6, 0.8, -1)) g.add_children(translate) translate = ngl.Translate(node, vector=(-0.6, -0.5, -1)) g.add_children(translate) translate = ngl.Translate(node, vector=(0.6, -0.5, -1)) g.add_children(translate) g = ngl.GraphicConfig(g, depth_test=True) camera = ngl.Camera(g) camera.set_eye(0, 0, 2) camera.set_center(0.0, 0.0, 0.0) camera.set_up(0.0, 1.0, 0.0) camera.set_perspective(45.0, cfg.aspect_ratio_float) camera.set_clipping(0.1, 10.0) tr_animkf = [ ngl.AnimKeyFrameVec3(0, (0.0, 0.0, 0.0)), ngl.AnimKeyFrameVec3(10, (0.0, 0.0, 3.0), 'exp_out') ] node = ngl.Translate(ngl.Identity(), anim=ngl.AnimatedVec3(tr_animkf)) if rotate: rot_animkf = [ ngl.AnimKeyFrameFloat(0, 0), ngl.AnimKeyFrameFloat(cfg.duration, 360, 'exp_out') ] node = ngl.Rotate(node, axis=(0, 1, 0), anim=ngl.AnimatedFloat(rot_animkf)) camera.set_eye_transform(node) fov_animkf = [ ngl.AnimKeyFrameFloat(0.5, 60.0), ngl.AnimKeyFrameFloat(cfg.duration, 45.0, 'exp_out') ] camera.set_fov_anim(ngl.AnimatedFloat(fov_animkf)) return camera
def stl(cfg, stl=None, scale=0.8): """Load and display a sphere generated with OpenSCAD""" if stl is None: # generated with: echo 'sphere($fn=15);'>sphere.scad; openscad sphere.scad -o sphere.stl stl = op.join(op.dirname(__file__), "data", "sphere.stl") normals_data = array.array("f") vertices_data = array.array("f") solid_label = None normal = None with open(stl) as fp: for line in fp.readlines(): line = line.strip() if line.startswith("solid"): solid_label = line.split(None, 1)[1] elif line.startswith("facet normal"): _, _, normal = line.split(None, 2) normal = [float(f) for f in normal.split()] elif normal and line.startswith("vertex"): _, vertex = line.split(None, 1) vertex = [float(f) for f in vertex.split()] normals_data.extend(normal) vertices_data.extend(vertex) vertices = ngl.BufferVec3(data=vertices_data) normals = ngl.BufferVec3(data=normals_data) g = ngl.Geometry(vertices=vertices, normals=normals) p = ngl.Program(vertex=cfg.get_vert("colored-normals"), fragment=cfg.get_frag("colored-normals")) p.update_vert_out_vars(var_normal=ngl.IOVec3(), var_uvcoord=ngl.IOVec2(), var_tex0_coord=ngl.IOVec2()) solid = ngl.Render(g, p, label=solid_label) solid = ngl.GraphicConfig(solid, depth_test=True) solid = ngl.Scale(solid, [scale] * 3) for i in range(3): rot_animkf = ngl.AnimatedFloat([ ngl.AnimKeyFrameFloat(0, 0), ngl.AnimKeyFrameFloat(cfg.duration, 360 * (i + 1)) ]) axis = [int(i == x) for x in range(3)] solid = ngl.Rotate(solid, axis=axis, angle=rot_animkf) camera = ngl.Camera(solid) camera.set_eye(2.0, 2.0, 2.0) camera.set_center(0.0, 0.0, 0.0) camera.set_up(0.0, 1.0, 0.0) camera.set_perspective(45.0, cfg.aspect_ratio_float) camera.set_clipping(1.0, 10.0) return camera
def transform_animated_camera(cfg): cfg.duration = 5. g = ngl.Group() elems = ( ('red', None), ('yellow', (-0.6, 0.8, -1)), ('green', (0.6, 0.8, -1)), ('cyan', (-0.6, -0.5, -1)), ('magenta', (0.6, -0.5, -1)), ) quad = ngl.Quad((-0.5, -0.5, 0), (1, 0, 0), (0, 1, 0)) prog = ngl.Program(vertex=cfg.get_vert('color'), fragment=cfg.get_frag('color')) for color, vector in elems: node = ngl.Render(quad, prog) node.update_uniforms(color=ngl.UniformVec4(value=COLORS[color])) if vector: node = ngl.Translate(node, vector=vector) g.add_children(node) g = ngl.GraphicConfig(g, depth_test=True) camera = ngl.Camera(g) camera.set_eye(0, 0, 2) camera.set_center(0.0, 0.0, 0.0) camera.set_up(0.0, 1.0, 0.0) camera.set_perspective(45.0, cfg.aspect_ratio_float) camera.set_clipping(0.1, 10.0) tr_animkf = [ ngl.AnimKeyFrameVec3(0, (0.0, 0.0, 0.0)), ngl.AnimKeyFrameVec3(cfg.duration, (0.0, 0.0, 3.0)) ] eye_transform = ngl.Translate(ngl.Identity(), anim=ngl.AnimatedVec3(tr_animkf)) rot_animkf = [ ngl.AnimKeyFrameFloat(0, 0), ngl.AnimKeyFrameFloat(cfg.duration, 360) ] eye_transform = ngl.Rotate(eye_transform, axis=(0, 1, 0), anim=ngl.AnimatedFloat(rot_animkf)) camera.set_eye_transform(eye_transform) fov_animkf = [ ngl.AnimKeyFrameFloat(0.5, 60.0), ngl.AnimKeyFrameFloat(cfg.duration, 45.0) ] camera.set_fov_anim(ngl.AnimatedFloat(fov_animkf)) return camera
def animated_camera(cfg, rotate=True): """Animated camera around a scene""" g = ngl.Group() q = ngl.Quad((-0.5, -0.5, 0), (1, 0, 0), (0, 1, 0)) m = ngl.Media(cfg.medias[0].filename) t = ngl.Texture2D(data_src=m) node = ngl.RenderTexture(t, geometry=q) g.add_children(node) translate = ngl.Translate(node, vector=(-0.6, 0.8, -1)) g.add_children(translate) translate = ngl.Translate(node, vector=(0.6, 0.8, -1)) g.add_children(translate) translate = ngl.Translate(node, vector=(-0.6, -0.5, -1)) g.add_children(translate) translate = ngl.Translate(node, vector=(0.6, -0.5, -1)) g.add_children(translate) g = ngl.GraphicConfig(g, depth_test=True) camera = ngl.Camera(g) camera.set_eye(0, 0, 2) camera.set_center(0.0, 0.0, 0.0) camera.set_up(0.0, 1.0, 0.0) camera.set_clipping(0.1, 10.0) tr_animkf = [ ngl.AnimKeyFrameVec3(0, (0.0, 0.0, 0.0)), ngl.AnimKeyFrameVec3(10, (0.0, 0.0, 3.0), "exp_out") ] node = ngl.Translate(ngl.Identity(), vector=ngl.AnimatedVec3(tr_animkf)) if rotate: rot_animkf = [ ngl.AnimKeyFrameFloat(0, 0), ngl.AnimKeyFrameFloat(cfg.duration, 360, "exp_out") ] node = ngl.Rotate(node, axis=(0, 1, 0), angle=ngl.AnimatedFloat(rot_animkf)) camera.set_eye_transform(node) perspective_animkf = [ ngl.AnimKeyFrameVec2(0.5, (60.0, cfg.aspect_ratio_float)), ngl.AnimKeyFrameVec2(cfg.duration, (45.0, cfg.aspect_ratio_float), "exp_out"), ] camera.set_perspective(ngl.AnimatedVec2(perspective_animkf)) return camera
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))
def transform_animated_camera(cfg): cfg.duration = 5.0 g = ngl.Group() elems = ( # fmt: off (COLORS.red, None), (COLORS.yellow, (-0.6, 0.8, -1)), (COLORS.green, (0.6, 0.8, -1)), (COLORS.cyan, (-0.6, -0.5, -1)), (COLORS.magenta, (0.6, -0.5, -1)), # fmt: on ) quad = ngl.Quad((-0.5, -0.5, 0), (1, 0, 0), (0, 1, 0)) for color, vector in elems: node = ngl.RenderColor(color, geometry=quad) if vector: node = ngl.Translate(node, vector=vector) g.add_children(node) g = ngl.GraphicConfig(g, depth_test=True) camera = ngl.Camera(g) camera.set_eye(0, 0, 2) camera.set_center(0.0, 0.0, 0.0) camera.set_up(0.0, 1.0, 0.0) camera.set_clipping(0.1, 10.0) tr_animkf = [ ngl.AnimKeyFrameVec3(0, (0.0, 0.0, 0.0)), ngl.AnimKeyFrameVec3(cfg.duration, (0.0, 0.0, 3.0)) ] eye_transform = ngl.Translate(ngl.Identity(), vector=ngl.AnimatedVec3(tr_animkf)) rot_animkf = [ ngl.AnimKeyFrameFloat(0, 0), ngl.AnimKeyFrameFloat(cfg.duration, 360) ] eye_transform = ngl.Rotate(eye_transform, axis=(0, 1, 0), angle=ngl.AnimatedFloat(rot_animkf)) camera.set_eye_transform(eye_transform) perspective_animkf = [ ngl.AnimKeyFrameVec2(0.5, (60.0, cfg.aspect_ratio_float)), ngl.AnimKeyFrameVec2(cfg.duration, (45.0, cfg.aspect_ratio_float)), ] camera.set_perspective(ngl.AnimatedVec2(perspective_animkf)) return camera
def rtt_clear_attachment_with_timeranges(cfg): cfg.aspect_ratio = (1, 1) # Time-disabled full screen white quad quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0)) program = ngl.Program(vertex=cfg.get_vert('color'), fragment=cfg.get_frag('color')) program.update_vert_out_vars(var_tex0_coord=ngl.IOVec2(), var_uvcoord=ngl.IOVec2()) render = ngl.Render(quad, program) render.update_frag_resources(color=ngl.UniformVec4(value=COLORS['white'])) time_range_filter = ngl.TimeRangeFilter(render) time_range_filter.add_ranges(ngl.TimeRangeModeNoop(0)) # Intermediate no-op RTT to force the use of a different render pass internally texture = ngl.Texture2D(width=32, height=32) rtt_noop = ngl.RenderToTexture(ngl.Identity(), [texture]) # Centered rotating quad quad = ngl.Quad((-0.5, -0.5, 0), (1, 0, 0), (0, 1, 0)) program = ngl.Program(vertex=cfg.get_vert('color'), fragment=cfg.get_frag('color')) program.update_vert_out_vars(var_tex0_coord=ngl.IOVec2(), var_uvcoord=ngl.IOVec2()) render = ngl.Render(quad, program) render.update_frag_resources(color=ngl.UniformVec4(value=COLORS['orange'])) animkf = [ ngl.AnimKeyFrameFloat(0, 0), ngl.AnimKeyFrameFloat(cfg.duration, -360) ] render = ngl.Rotate(render, anim=ngl.AnimatedFloat(animkf)) group = ngl.Group(children=(time_range_filter, rtt_noop, render)) # Root RTT texture = ngl.Texture2D(width=512, height=512) rtt = ngl.RenderToTexture(group, [texture]) # Full screen render of the root RTT result quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0)) program = ngl.Program(vertex=cfg.get_vert('texture'), fragment=cfg.get_frag('texture')) program.update_vert_out_vars(var_tex0_coord=ngl.IOVec2(), var_uvcoord=ngl.IOVec2()) render = ngl.Render(quad, program) render.update_frag_resources(tex0=texture) return ngl.Group(children=(rtt, render))
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 fibo(cfg, n=8): '''Fibonacci with a recursive tree (nodes inherit transforms)''' cfg.duration = 5.0 cfg.aspect_ratio = (1, 1) p = ngl.Program(vertex=cfg.get_vert('color'), fragment=cfg.get_frag('color')) fib = [0, 1, 1] for i in range(2, n): fib.append(fib[i] + fib[i - 1]) fib = fib[::-1] shift = 1 / 3. # XXX: what's the exact math here? shape_scale = 1. / ((2. - shift) * sum(fib)) orig = (-shift, -shift, 0) g = None root = None for i, x in enumerate(fib[:-1]): w = x * shape_scale gray = 1. - i / float(n) color = [gray, gray, gray, 1] q = ngl.Quad(orig, (w, 0, 0), (0, w, 0)) render = ngl.Render(q, p) render.update_frag_resources(color=ngl.UniformVec4(value=color)) new_g = ngl.Group() animkf = [ ngl.AnimKeyFrameFloat(0, 90), ngl.AnimKeyFrameFloat(cfg.duration / 2, -90, 'exp_in_out'), ngl.AnimKeyFrameFloat(cfg.duration, 90, 'exp_in_out') ] rot = ngl.Rotate(new_g, anchor=orig, anim=ngl.AnimatedFloat(animkf)) if g: g.add_children(rot) else: root = rot g = new_g new_g.add_children(render) orig = (orig[0] + w, orig[1] + w, 0) return root
def animated_circles(cfg): '''Simple cyclic circles animation''' group = ngl.Group() cfg.duration = 5. cfg.aspect_ratio = (1, 1) radius = 0.2 n = 10 step = 360. / n shape = ngl.Circle(radius=radius, npoints=128) prog = ngl.Program(vertex=cfg.get_vert('color'), fragment=cfg.get_frag('color')) render = ngl.Render(shape, prog) render.update_uniforms(color=ngl.UniformVec4([1.0] * 4)) for i in range(n): mid_time = cfg.duration / 2.0 start_time = mid_time / (i + 2) end_time = cfg.duration - start_time scale_animkf = [ ngl.AnimKeyFrameVec3(start_time, (0, 0, 0)), ngl.AnimKeyFrameVec3(mid_time, (1.0, 1.0, 1.0), 'exp_out'), ngl.AnimKeyFrameVec3(end_time, (0, 0, 0), 'exp_in'), ] angle = i * step rotate_animkf = [ ngl.AnimKeyFrameFloat(start_time, 0), ngl.AnimKeyFrameFloat(mid_time, angle, 'exp_out'), ngl.AnimKeyFrameFloat(end_time, 0, 'exp_in'), ] tnode = render tnode = ngl.Scale(tnode, anim=ngl.AnimatedVec3(scale_animkf)) tnode = ngl.Translate(tnode, vector=(1 - radius, 0, 0)) tnode = ngl.Rotate(tnode, anim=ngl.AnimatedFloat(rotate_animkf)) group.add_children(tnode) return group
def obj(cfg, n=0.5, model=None): """Load and display a cube object (generated with Blender)""" if model is None: model = op.join(op.dirname(__file__), "data", "model.obj") with open(model) as fp: vertices_data, uvs_data, normals_data = _load_model(fp) vertices = ngl.BufferVec3(data=vertices_data) texcoords = ngl.BufferVec2(data=uvs_data) normals = ngl.BufferVec3(data=normals_data) q = ngl.Geometry(vertices, texcoords, normals) m = ngl.Media(cfg.medias[0].filename) t = ngl.Texture2D(data_src=m) p = ngl.Program(vertex=cfg.get_vert("tex-tint-normals"), fragment=cfg.get_frag("tex-tint-normals")) p.update_vert_out_vars(var_normal=ngl.IOVec3(), var_uvcoord=ngl.IOVec2(), var_tex0_coord=ngl.IOVec2()) render = ngl.Render(q, p) render.update_frag_resources(tex0=t) render = ngl.GraphicConfig(render, depth_test=True) animkf = [ ngl.AnimKeyFrameFloat(0, 0), ngl.AnimKeyFrameFloat(cfg.duration, 360 * 2) ] rot = ngl.Rotate(render, label="roty", axis=(0, 1, 0), angle=ngl.AnimatedFloat(animkf)) camera = ngl.Camera(rot) camera.set_eye(2.0, 2.0, 2.0) camera.set_center(0.0, 0.0, 0.0) camera.set_up(0.0, 1.0, 0.0) camera.set_perspective(45.0, cfg.aspect_ratio_float) camera.set_clipping(1.0, 10.0) return camera
def _get_random_transform(cfg, rng, t0, t1, child): translate = lambda rng, child: ngl.Translate( child, vector=_get_random_animated_vec3(rng, t0, t1, _get_random_position), ) scale = lambda rng, child: ngl.Scale( child, factors=_get_random_animated_vec3(rng, t0, t1, _get_random_factors), anchor=_get_random_anchor(rng), ) rotate = lambda rng, child: ngl.Rotate( child, angle=_get_random_animated_float(rng, t0, t1, _get_random_angle), anchor=_get_random_anchor(rng), ) for i in range(rng.randint(1, 2)): trf_func = rng.choice((translate, scale, rotate)) child = trf_func(rng, child) return child
def _shape_geometry(cfg, set_normals=False, set_indices=False): # Fake cube (3 faces only) obtained from: # echo 'cube();'>x.scad; openscad x.scad -o x.stl vertices = array.array('f', [x - 0.5 for x in [ 1,1,0, 0,1,1, 1,1,1, 0,1,1, 1,1,0, 0,1,0, 0,0,0, 0,1,1, 0,1,0, 0,1,1, 0,0,0, 0,0,1, 0,1,1, 1,0,1, 1,1,1, 1,0,1, 0,1,1, 0,0,1, ]]) normals = array.array('f', [ 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, -1,0,0, -1,0,0, -1,0,0, -1,0,0, -1,0,0, -1,0,0, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, ]) vertices_buffer = ngl.BufferVec3(data=vertices) normals_buffer = ngl.BufferVec3(data=normals) cfg.aspect_ratio = (1, 1) geometry = ngl.Geometry(vertices=vertices_buffer) if set_normals: geometry.set_normals(normals_buffer) prog = ngl.Program(vertex=cfg.get_vert('colored-normals'), fragment=cfg.get_frag('colored-normals')) prog.update_vert_out_vars(var_normal=ngl.IOVec3()) render = ngl.Render(geometry, prog) else: render = _render_shape(cfg, geometry, COLORS['magenta']) if set_indices: indices = array.array('H', list(range(3 * 6))) indices_buffer = ngl.BufferUShort(data=indices) geometry.set_indices(indices_buffer) return ngl.Rotate(render, 45, axis=(1, 1, 1))
def fibo(cfg, n=8): """Fibonacci with a recursive tree (nodes inherit transforms)""" cfg.duration = 5.0 cfg.aspect_ratio = (1, 1) fib = [0, 1, 1] for i in range(2, n): fib.append(fib[i] + fib[i - 1]) fib = fib[::-1] shift = 1 / 3.0 # XXX: what's the exact math here? shape_scale = 1.0 / ((2.0 - shift) * sum(fib)) orig = (-shift, -shift, 0) g = None root = None for i, x in enumerate(fib[:-1]): w = x * shape_scale gray = 1.0 - i / float(n) color = (gray, gray, gray) q = ngl.Quad(orig, (w, 0, 0), (0, w, 0)) render = ngl.RenderColor(color, geometry=q) new_g = ngl.Group() animkf = [ ngl.AnimKeyFrameFloat(0, 90), ngl.AnimKeyFrameFloat(cfg.duration / 2, -90, "exp_in_out"), ngl.AnimKeyFrameFloat(cfg.duration, 90, "exp_in_out"), ] rot = ngl.Rotate(new_g, anchor=orig, angle=ngl.AnimatedFloat(animkf)) if g: g.add_children(rot) else: root = rot g = new_g new_g.add_children(render) orig = (orig[0] + w, orig[1] + w, 0) assert root is not None return root
def animated_square(cfg, color=(1, 0.66, 0, 1), rotate=True, scale=True, translate=True): '''Animated Translate/Scale/Rotate on a square''' cfg.duration = 5.0 cfg.aspect_ratio = (1, 1) sz = 1 / 3. q = ngl.Quad((-sz / 2, -sz / 2, 0), (sz, 0, 0), (0, sz, 0)) p = ngl.Program(vertex=cfg.get_vert('color'), fragment=cfg.get_frag('color')) node = ngl.Render(q, p) ucolor = ngl.UniformVec4(value=color) node.update_uniforms(color=ucolor) coords = [(-1, 1), (1, 1), (1, -1), (-1, -1), (-1, 1)] if rotate: animkf = (ngl.AnimKeyFrameFloat(0, 0), ngl.AnimKeyFrameFloat(cfg.duration, 360)) node = ngl.Rotate(node, anim=ngl.AnimatedFloat(animkf)) if scale: animkf = (ngl.AnimKeyFrameVec3(0, (1, 1, 1)), ngl.AnimKeyFrameVec3(cfg.duration / 2, (2, 2, 2)), ngl.AnimKeyFrameVec3(cfg.duration, (1, 1, 1))) node = ngl.Scale(node, anim=ngl.AnimatedVec3(animkf)) if translate: animkf = [] tscale = 1. / float(len(coords) - 1) * cfg.duration for i, xy in enumerate(coords): pos = (xy[0] * .5, xy[1] * .5, 0) t = i * tscale animkf.append(ngl.AnimKeyFrameVec3(t, pos)) node = ngl.Translate(node, anim=ngl.AnimatedVec3(animkf)) return node
def animated_circles(cfg): """Simple cyclic circles animation""" group = ngl.Group() cfg.duration = 5.0 cfg.aspect_ratio = (1, 1) radius = 0.2 n = 10 step = 360.0 / n shape = ngl.Circle(radius=radius, npoints=128) render = ngl.RenderColor(geometry=shape) for i in range(n): mid_time = cfg.duration / 2.0 start_time = mid_time / (i + 2) end_time = cfg.duration - start_time scale_animkf = [ ngl.AnimKeyFrameVec3(start_time, (0, 0, 0)), ngl.AnimKeyFrameVec3(mid_time, (1.0, 1.0, 1.0), "exp_out"), ngl.AnimKeyFrameVec3(end_time, (0, 0, 0), "exp_in"), ] angle = i * step rotate_animkf = [ ngl.AnimKeyFrameFloat(start_time, 0), ngl.AnimKeyFrameFloat(mid_time, angle, "exp_out"), ngl.AnimKeyFrameFloat(end_time, 0, "exp_in"), ] tnode = render tnode = ngl.Scale(tnode, factors=ngl.AnimatedVec3(scale_animkf)) tnode = ngl.Translate(tnode, vector=(1 - radius, 0, 0)) tnode = ngl.Rotate(tnode, angle=ngl.AnimatedFloat(rotate_animkf)) group.add_children(tnode) return group
def _shape_geometry(cfg, set_normals=False, set_indices=False): # Fake cube (3 faces only) obtained from: # echo 'cube();'>x.scad; openscad x.scad -o x.stl vertices = array.array( "f", [ x - 0.5 for x in [ # fmt: off 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, # fmt: on ] ], ) normals = array.array( "f", [ # fmt: off 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, # fmt: on ], ) vertices_buffer = ngl.BufferVec3(data=vertices) normals_buffer = ngl.BufferVec3(data=normals) cfg.aspect_ratio = (1, 1) geometry = ngl.Geometry(vertices=vertices_buffer) if set_normals: geometry.set_normals(normals_buffer) prog = ngl.Program(vertex=cfg.get_vert("colored-normals"), fragment=cfg.get_frag("colored-normals")) prog.update_vert_out_vars(var_normal=ngl.IOVec3()) render = ngl.Render(geometry, prog) else: prog = ngl.Program(vertex=cfg.get_vert("color"), fragment=cfg.get_frag("color")) render = ngl.Render(geometry, prog) render.update_frag_resources( color=ngl.UniformVec3(value=COLORS.magenta), opacity=ngl.UniformFloat(1)) if set_indices: indices = array.array("H", list(range(3 * 6))) indices_buffer = ngl.BufferUShort(data=indices) geometry.set_indices(indices_buffer) return ngl.Rotate(render, 45, axis=(1, 1, 1))
def _get_live_trf_spec(layout): t0 = ngl.Identity() t1 = ngl.Transform(t0) t2 = ngl.Translate(t1) t3 = ngl.Rotate(t2) t4 = ngl.Scale(t3) t5 = ngl.RotateQuat(t4) return [ dict( name='m4', type='mat4', category='single', func=lambda data: ngl.UniformMat4(data, transform=t5), livechange=( lambda: t1.set_matrix( # trf_step=1 0.1, 0.2, 0.0, 0.0, 0.0, 0.3, 0.4, 0.0, 0.0, 0.0, 0.5, 0.0, 0.8, 0.7, 0.0, 0.6, ), lambda: t2.set_vector(0.2, 0.7, -0.4), # trf_step=2 lambda: t3.set_angle(123.4), # trf_step=3 lambda: t4.set_factors(0.7, 1.4, 0.2), # trf_step=4 lambda: t5.set_quat(0, 0, -0.474, 0.880), # trf_step=5 lambda: t5.set_quat(0, 0, 0, 1), lambda: t4.set_factors(1, 1, 1), lambda: t3.set_angle(0), lambda: t2.set_vector(0, 0, 0), lambda: t1.set_matrix( 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, )), ), ]
def transform_rotate_anchor(cfg, angle=123.4, anchor=(0.15, 0.35, 0.7)): cfg.aspect_ratio = (1, 1) shape = _transform_shape(cfg) return ngl.Rotate(shape, angle, anchor=anchor)