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 velocity_circle_distort_2d(cfg): cfg.duration = 4.0 cfg.aspect_ratio = (1, 1) coords = list(equilateral_triangle_coords()) coords.append(coords[0]) pos_kf = [ ngl.AnimKeyFrameVec2(cfg.duration * i / 3.0, pos[0:2], "exp_in_out") for i, pos in enumerate(coords) ] anim = ngl.AnimatedVec2(pos_kf) velocity = ngl.VelocityVec2(anim) vert = textwrap.dedent("""\ void main() { float distort_max = 0.1; float velocity_l = length(velocity); float direction_l = length(ngl_position); vec2 normed_velocity = velocity_l == 0.0 ? vec2(0.0) : -velocity / velocity_l; vec2 normed_direction = direction_l == 0.0 ? vec2(0.0) : ngl_position.xy / direction_l; float distort = clamp(dot(normed_velocity, normed_direction) / 2.0 * distort_max, 0.0, 1.0); vec4 pos = vec4(ngl_position, 1.0) + vec4(translate, 0.0, 0.0) + vec4(-distort * velocity, 0.0, 0.0); ngl_out_pos = ngl_projection_matrix * ngl_modelview_matrix * pos; } """) geom = ngl.Circle(radius=0.2, npoints=128) prog = ngl.Program(vertex=vert, fragment=cfg.get_frag("color")) shape = ngl.Render(geom, prog) shape.update_frag_resources(color=ngl.UniformVec3(COLORS.white), opacity=ngl.UniformFloat(1)) shape.update_vert_resources(velocity=velocity, translate=anim) return shape
def get_debug_points(cfg, points, radius=0.025, color=COLORS['green'], text_size=(0.1, 0.1)): prog = ngl.Program(vertex=cfg.get_vert('color'), fragment=cfg.get_frag('color')) g = ngl.Group() circle = ngl.Circle(radius=radius) circle_render = ngl.Render(circle, prog) circle_render.update_uniforms(color=ngl.UniformVec4(value=color)) box_w = (text_size[0], 0, 0) box_h = (0, text_size[1], 0) for pos_name, position in points.items(): text = ngl.Text(pos_name, box_width=box_w, box_height=box_h, bg_color=(0, 0, 0, 0), valign='top') text = ngl.Translate(text, (1 + radius, 1 - radius - text_size[1], 0)) point = ngl.Group(children=(circle_render, text)) point = ngl.Translate(point, list(position) + [0]) g.add_children(point) return ngl.GraphicConfig(g, blend=True, blend_src_factor='src_alpha', blend_dst_factor='one_minus_src_alpha', blend_src_factor_a='zero', blend_dst_factor_a='one', label='Debug circles')
def gradient_eval(cfg, mode="ramp", c0=(1, 0.5, 0.5), c1=(0.5, 1, 0.5)): """Animate a gradient and objects using CPU evaluation""" pos_res = dict(t=ngl.Time()) pos0_x = ngl.EvalFloat("sin( 0.307*t - 0.190)", resources=pos_res) pos0_y = ngl.EvalFloat("sin( 0.703*t - 0.957)", resources=pos_res) pos1_x = ngl.EvalFloat("sin(-0.236*t + 0.218)", resources=pos_res) pos1_y = ngl.EvalFloat("sin(-0.851*t - 0.904)", resources=pos_res) trf0 = ngl.EvalVec3("x", "y", "0", resources=dict(x=pos0_x, y=pos0_y)) trf1 = ngl.EvalVec3("x", "y", "0", resources=dict(x=pos1_x, y=pos1_y)) geom = ngl.Circle(radius=0.02, npoints=64) p0 = ngl.RenderColor(color=(1 - c0[0], 1 - c0[1], 1 - c0[2]), geometry=geom) p1 = ngl.RenderColor(color=(1 - c1[0], 1 - c1[1], 1 - c1[2]), geometry=geom) p0 = ngl.Scale(p0, factors=(1 / cfg.aspect_ratio_float, 1, 1)) p1 = ngl.Scale(p1, factors=(1 / cfg.aspect_ratio_float, 1, 1)) p0 = ngl.Translate(p0, vector=trf0) p1 = ngl.Translate(p1, vector=trf1) pos0 = ngl.EvalVec2("x/2+.5", ".5-y/2", resources=dict(x=pos0_x, y=pos0_y)) pos1 = ngl.EvalVec2("x/2+.5", ".5-y/2", resources=dict(x=pos1_x, y=pos1_y)) grad = ngl.RenderGradient(pos0=pos0, pos1=pos1, mode=mode, color0=c0, color1=c1) return ngl.Group(children=(grad, p0, p1))
def _path_scene(cfg, path, points=None, controls=None, easing="linear"): cfg.aspect_ratio = (1, 1) anim_kf = [ ngl.AnimKeyFrameFloat(0, 0), ngl.AnimKeyFrameFloat(cfg.duration, 1, easing), ] geom = ngl.Circle(radius=0.03, npoints=32) shape = ngl.RenderColor(COLORS.orange, geometry=geom) moving_shape = ngl.Translate(shape, vector=ngl.AnimatedPath(anim_kf, path)) objects = [] if points: debug_points = {f"P{i}": p[:2] for i, p in enumerate(points)} objects.append(get_debug_points(cfg, debug_points)) if controls: debug_controls = {f"C{i}": p[:2] for i, p in enumerate(controls)} objects.append(get_debug_points(cfg, debug_controls, color=COLORS.cyan)) objects.append(moving_shape) return ngl.Group(children=objects)
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
def buffer_dove(cfg, bgcolor1=(0.6, 0, 0), bgcolor2=(0.8, 0.8, 0), bilinear_filtering=True): """Blending of a Render using a Buffer as data source""" cfg.duration = 3.0 # Credits: https://icons8.com/icon/40514/dove # (Raw data is the premultiplied) icon_filename = op.join(op.dirname(__file__), "data", "icons8-dove.raw") cfg.files.append(icon_filename) w, h = (96, 96) cfg.aspect_ratio = (w, h) img_buf = ngl.BufferUBVec4(filename=icon_filename, label="icon raw buffer") img_tex = ngl.Texture2D(data_src=img_buf, width=w, height=h) if bilinear_filtering: img_tex.set_mag_filter("linear") quad = ngl.Quad((-0.5, -0.5, 0.1), (1, 0, 0), (0, 1, 0)) render = ngl.RenderTexture(img_tex, geometry=quad, blending="src_over") shape_bg = ngl.Circle(radius=0.6, npoints=256) color_animkf = [ ngl.AnimKeyFrameColor(0, bgcolor1), ngl.AnimKeyFrameColor(cfg.duration / 2.0, bgcolor2), ngl.AnimKeyFrameColor(cfg.duration, bgcolor1), ] ucolor = ngl.AnimatedColor(color_animkf) render_bg = ngl.RenderColor(ucolor, geometry=shape_bg, label="background") return ngl.Group(children=(render_bg, render))
def _get_userlive_switch_func(): scene0 = ngl.RenderColor(COLORS.white, geometry=ngl.Circle()) scene1 = ngl.RenderColor(COLORS.red, geometry=ngl.Quad()) scene2 = ngl.RenderColor(COLORS.azure, geometry=ngl.Triangle()) switch0 = ngl.UserSwitch( ngl.Scale(scene0, factors=(1 / 3, 1 / 3, 1 / 3), anchor=(-1, 0, 0))) switch1 = ngl.UserSwitch(ngl.Scale(scene1, factors=(1 / 2, 1 / 2, 1 / 2))) switch2 = ngl.UserSwitch( ngl.Scale(scene2, factors=(1 / 3, 1 / 3, 1 / 3), anchor=(1, 0, 0))) def keyframes_callback(t_id): # Build a "random" composition of switches switch0.set_enabled(t_id % 2 == 0) switch1.set_enabled(t_id % 3 == 0) switch2.set_enabled(t_id % 4 == 0) @test_fingerprint(nb_keyframes=10, keyframes_callback=keyframes_callback, tolerance=1, exercise_serialization=False) @scene(s0=scene.Bool(), s1=scene.Bool(), s2=scene.Bool()) def scene_func(cfg, s0_enabled=True, s1_enabled=True, s2_enabled=True): cfg.aspect_ratio = (1, 1) switch0.set_enabled(s0_enabled) switch1.set_enabled(s1_enabled) switch2.set_enabled(s2_enabled) return ngl.Group(children=(switch0, switch1, switch2)) return scene_func
def shape_diamond_colormask(cfg): color_write_masks = ('r+g+b+a', 'r+g+a', 'g+b+a', 'r+b+a') geometry = ngl.Circle(npoints=5) prog = ngl.Program(vertex=cfg.get_vert('color'), fragment=cfg.get_frag('color')) render = ngl.Render(geometry, prog) render.update_frag_resources(color=ngl.UniformVec4(value=COLORS['white'])) scenes = [ngl.GraphicConfig(render, color_write_mask=cwm) for cwm in color_write_masks] return autogrid_simple(scenes)
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
def _get_blending_base_objects(): circle = ngl.Circle(radius=_CIRCLE_RADIUS, npoints=100) positions = _equilateral_triangle_coords(_CIRCLE_RADIUS * 2.0 / 3.0) colored_circles = ngl.Group(label="colored circles") for position, color in zip(positions, _CIRCLES_COLORS): render = ngl.RenderColor(color, geometry=circle) render = ngl.Translate(render, position + (0.0, )) colored_circles.add_children(render) return colored_circles, circle, positions
def shape_diamond_colormask(_): color_write_masks = ("r+g+b+a", "r+g+a", "g+b+a", "r+b+a") geometry = ngl.Circle(npoints=5) render = ngl.RenderColor(COLORS.white, geometry=geometry) scenes = [ ngl.GraphicConfig(render, color_write_mask=cwm) for cwm in color_write_masks ] return autogrid_simple(scenes)
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 _get_blending_base_objects(cfg): circle = ngl.Circle(radius=_CIRCLE_RADIUS, npoints=100) prog = ngl.Program(vertex=cfg.get_vert('color'), fragment=cfg.get_frag('color')) positions = _equilateral_triangle_coords(_CIRCLE_RADIUS * 2.0 / 3.0) colored_circles = ngl.Group(label='colored circles') for position, color in zip(positions, _CIRCLES_COLORS): render = ngl.Render(circle, prog) render.update_frag_resources(color=ngl.UniformVec4(value=color)) render = ngl.Translate(render, position) colored_circles.add_children(render) return colored_circles, circle, prog, positions
def transform_eye_camera(cfg): cfg.duration = 3.0 cfg.aspect_ratio = (1, 1) node = ngl.RenderGradient4(geometry=ngl.Circle(radius=0.7, npoints=128)) animkf = [ ngl.AnimKeyFrameVec3(0, (0, -0.5, 0)), ngl.AnimKeyFrameVec3(cfg.duration / 2, (0, 1, 0)), ngl.AnimKeyFrameVec3(cfg.duration, (0, -0.5, 0)), ] return ngl.Camera(node, eye=ngl.AnimatedVec3(animkf))
def _get_random_geometry(rng): circle = lambda rng: ngl.Circle( radius=rng.uniform(1 / 4, 3 / 4), npoints=rng.randint(5, 25), ) quad = lambda rng: ngl.Quad( corner=_get_random_position(rng), width=(rng.uniform(-0.5, 0.5), rng.uniform(-0.5, 0.5), 0), height=(rng.uniform(-0.5, 0.5), rng.uniform(-0.5, 0.5), 0), ) triangle = lambda rng: ngl.Triangle( edge0=_get_random_position(rng), edge1=_get_random_position(rng), edge2=_get_random_position(rng), ) shape_func = rng.choice((circle, quad, triangle)) return shape_func(rng)
def buffer_dove(cfg, bgcolor1=(.6, 0, 0, 1), bgcolor2=(.8, .8, 0, 1), bilinear_filtering=True): '''Blending of a Render using a Buffer as data source''' cfg.duration = 3. # Credits: https://icons8.com/icon/40514/dove icon_filename = op.join(op.dirname(__file__), 'data', 'icons8-dove.raw') cfg.files.append(icon_filename) w, h = (96, 96) cfg.aspect_ratio = (w, h) img_buf = ngl.BufferUBVec4(filename=icon_filename, label='icon raw buffer') img_tex = ngl.Texture2D(data_src=img_buf, width=w, height=h) if bilinear_filtering: img_tex.set_mag_filter('linear') quad = ngl.Quad((-.5, -.5, 0.1), (1, 0, 0), (0, 1, 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, label='dove') render.update_frag_resources(tex0=img_tex) render = ngl.GraphicConfig(render, blend=True, blend_src_factor='src_alpha', blend_dst_factor='one_minus_src_alpha', blend_src_factor_a='zero', blend_dst_factor_a='one') prog_bg = ngl.Program(vertex=cfg.get_vert('color'), fragment=cfg.get_frag('color')) shape_bg = ngl.Circle(radius=.6, npoints=256) render_bg = ngl.Render(shape_bg, prog_bg, label='background') color_animkf = [ ngl.AnimKeyFrameVec4(0, bgcolor1), ngl.AnimKeyFrameVec4(cfg.duration / 2.0, bgcolor2), ngl.AnimKeyFrameVec4(cfg.duration, bgcolor1) ] ucolor = ngl.AnimatedVec4(color_animkf) render_bg.update_frag_resources(color=ucolor) return ngl.Group(children=(render_bg, render))
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 get_debug_points(cfg, points, radius=0.025, color=COLORS.green, text_size=(0.1, 0.1)): g = ngl.Group(label="Debug circles") circle = ngl.Circle(radius=radius) circle_render = ngl.RenderColor(color, geometry=circle) box_w = (text_size[0], 0, 0) box_h = (0, text_size[1], 0) for pos_name, position in points.items(): text = ngl.Text(pos_name, box_width=box_w, box_height=box_h, bg_opacity=0, valign="top") text = ngl.Translate(text, (1 + radius, 1 - radius - text_size[1], 0)) point = ngl.Group(children=(circle_render, text)) point = ngl.Translate(point, list(position) + [0]) g.add_children(point) return g
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 data_noise_wiggle(cfg): cfg.aspect_ratio = (1, 1) cfg.duration = 3 vert = textwrap.dedent("""\ void main() { ngl_out_pos = ngl_projection_matrix * ngl_modelview_matrix * vec4(ngl_position, 1.0); ngl_out_pos += vec4(wiggle, 0.0, 0.0); } """) frag = textwrap.dedent("""\ void main() { ngl_out_color = vec4(color, 1.0); } """) geometry = ngl.Circle(radius=0.25, npoints=6) program = ngl.Program(vertex=vert, fragment=frag) render = ngl.Render(geometry, program) render.update_vert_resources(wiggle=ngl.NoiseVec2(octaves=8)) render.update_frag_resources(color=ngl.UniformVec3(value=COLORS.white)) return render
def data_noise_wiggle(cfg): cfg.aspect_ratio = (1, 1) cfg.duration = 3 vert = ''' void main() { ngl_out_pos = ngl_projection_matrix * ngl_modelview_matrix * ngl_position; ngl_out_pos += vec4(wiggle, 0.0, 0.0); } ''' frag = ''' void main() { ngl_out_color = color; } ''' geometry = ngl.Circle(radius=0.25, npoints=6) program = ngl.Program(vertex=vert, fragment=frag) render = ngl.Render(geometry, program) render.update_vert_resources(wiggle=ngl.NoiseVec2(octaves=8)) render.update_frag_resources(color=ngl.UniformVec4(value=COLORS['white'])) return render
def blending_and_stencil(cfg): '''Scene using blending and stencil graphic features''' cfg.duration = 5 random.seed(0) fragment = cfg.get_frag('color') program = ngl.Program(fragment=fragment) circle = ngl.Circle(npoints=256) cloud_color = ngl.UniformVec4(value=(1, 1, 1, 0.4)) main_group = ngl.Group() quad = ngl.Quad((-1, -1, 0), (2, 0, 0), (0, 2, 0)) render = ngl.Render(quad, program, label='sky') render.update_uniforms(color=ngl.UniformVec4(value=(0.2, 0.6, 1, 1))) config = ngl.GraphicConfig(render, stencil_test=True, stencil_write_mask=0xFF, stencil_func='always', stencil_ref=1, stencil_read_mask=0xFF, stencil_fail='replace', stencil_depth_fail='replace', stencil_depth_pass='******') main_group.add_children(config) render = ngl.Render(circle, program, label='sun') render.update_uniforms(color=ngl.UniformVec4(value=(1, 0.8, 0, 1))) scale = ngl.Scale(render, (0.15, 0.15, 0.0)) translate = ngl.Translate(scale, (0.4, 0.3, 0)) main_group.add_children(translate) cloud_group = ngl.Group(label='clouds') centers = [ (-1.0, 0.85, 0.4), (-0.5, 2.0, 1.0), ( 0, 0.85, 0.4), ( 1.0, 1.55, 0.8), ( 0.6, 0.65, 0.075), ( 0.5, 1.80, 1.25), ] for center in centers: render = ngl.Render(circle, program) render.update_uniforms(color=cloud_color) factor = random.random() * 0.4 + center[2] keyframe = cfg.duration * (random.random() * 0.4 + 0.2) animkf = (ngl.AnimKeyFrameVec3(0, (factor, factor, 0)), ngl.AnimKeyFrameVec3(keyframe, (factor + 0.1, factor + 0.1, 0)), ngl.AnimKeyFrameVec3(cfg.duration, (factor, factor, 0))) scale = ngl.Scale(render, anim=ngl.AnimatedVec3(animkf)) translate = ngl.Translate(scale, vector=(center[0], center[1], 0)) cloud_group.add_children(translate) config = ngl.GraphicConfig(cloud_group, blend=True, blend_src_factor='src_alpha', blend_dst_factor='one_minus_src_alpha', blend_src_factor_a='zero', blend_dst_factor_a='one', stencil_test=True, stencil_write_mask=0x0, stencil_func='equal', stencil_ref=1, stencil_read_mask=0xFF, stencil_fail='keep', stencil_depth_fail='keep', stencil_depth_pass='******') main_group.add_children(config) camera = ngl.Camera(main_group) 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_orthographic(-cfg.aspect_ratio_float, cfg.aspect_ratio_float, -1.0, 1.0) camera.set_clipping(1.0, 10.0) return camera
def blending_and_stencil(cfg): """Scene using blending and stencil graphic features""" cfg.duration = 5 vertex = cfg.get_vert("color") fragment = cfg.get_frag("color") program = ngl.Program(vertex=vertex, fragment=fragment) circle = ngl.Circle(npoints=256) cloud_color = ngl.UniformVec3(value=(1, 1, 1)) cloud_opacity = ngl.UniformFloat(0.4) main_group = ngl.Group() render = ngl.RenderColor(color=(0.2, 0.6, 1), label="sky") config = ngl.GraphicConfig( render, stencil_test=True, stencil_write_mask=0xFF, stencil_func="always", stencil_ref=1, stencil_read_mask=0xFF, stencil_fail="replace", stencil_depth_fail="replace", stencil_depth_pass="******", ) main_group.add_children(config) render = ngl.RenderColor(color=(1, 0.8, 0), geometry=circle, label="sun") scale = ngl.Scale(render, (0.15, 0.15, 0.0)) translate = ngl.Translate(scale, (0.4, 0.3, 0)) main_group.add_children(translate) cloud_group = ngl.Group(label="clouds") centers = [ (-1.0, 0.85, 0.4), (-0.5, 2.0, 1.0), (0, 0.85, 0.4), (1.0, 1.55, 0.8), (0.6, 0.65, 0.075), (0.5, 1.80, 1.25), ] for center in centers: render = ngl.Render(circle, program, blending="src_over") render.update_frag_resources(color=cloud_color, opacity=cloud_opacity) factor = cfg.rng.random() * 0.4 + center[2] keyframe = cfg.duration * (cfg.rng.random() * 0.4 + 0.2) animkf = ( ngl.AnimKeyFrameVec3(0, (factor, factor, 0)), ngl.AnimKeyFrameVec3(keyframe, (factor + 0.1, factor + 0.1, 0)), ngl.AnimKeyFrameVec3(cfg.duration, (factor, factor, 0)), ) scale = ngl.Scale(render, factors=ngl.AnimatedVec3(animkf)) translate = ngl.Translate(scale, vector=(center[0], center[1], 0)) cloud_group.add_children(translate) config = ngl.GraphicConfig( cloud_group, stencil_test=True, stencil_write_mask=0x0, stencil_func="equal", stencil_ref=1, stencil_read_mask=0xFF, stencil_fail="keep", stencil_depth_fail="keep", stencil_depth_pass="******", ) main_group.add_children(config) camera = ngl.Camera(main_group) 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_orthographic(-cfg.aspect_ratio_float, cfg.aspect_ratio_float, -1.0, 1.0) camera.set_clipping(1.0, 10.0) return camera
def shape_circle(cfg, radius=0.5, color=COLORS.azure): cfg.aspect_ratio = (1, 1) geometry = ngl.Circle(radius, npoints=64) return _render_shape(geometry, color)