.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "_gallery/feature_demo/light_spotlight_shadows.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr__gallery_feature_demo_light_spotlight_shadows.py: Spotlight Shadow ================ Spotlights and shadows example .. GENERATED FROM PYTHON SOURCE LINES 9-167 .. image-sg:: /_gallery/feature_demo/images/sphx_glr_light_spotlight_shadows_001.webp :alt: light spotlight shadows :srcset: /_gallery/feature_demo/images/sphx_glr_light_spotlight_shadows_001.webp :class: sphx-glr-single-img .. code-block:: Python import time import math import random import pylinalg as la from rendercanvas.auto import RenderCanvas, loop import pygfx as gfx def update_value(target, dist): for k, v in dist.items(): if isinstance(v, dict): update_value(getattr(target, k), v) else: setattr(target, k, v) return dist def get_value(target, template): vals = {} for k, v in template.items(): if isinstance(v, dict): vals[k] = get_value(getattr(target, k), v) else: vals[k] = getattr(target, k) return vals def lerp(start_vals, to_vals, t): current_vals = {} for key, start_value in start_vals.items(): if isinstance(start_value, (int, float)): to_value = to_vals[key] value = start_value + (to_value - start_value) * t current_vals[key] = value elif isinstance(start_value, dict): current_vals[key] = lerp(start_value, to_vals[key], t) return current_vals class Tween: def __init__(self, target): self.target = target self.starttime = 0 self._lerp_func = None def to(self, to: dict, duration): self.to_val = to self.duration = duration self.starttime = time.time() self.start_val = get_value(self.target, to) return self def lerp_func(self, func): self._lerp_func = func return self def update(self): t = (time.time() - self.starttime) / self.duration if t < 1: if self._lerp_func: t = self._lerp_func(t) current_val = lerp(self.start_val, self.to_val, t) update_value(self.target, current_val) @property def since_last_start(self): return time.time() - self.starttime def init_scene(): renderer = gfx.renderers.WgpuRenderer(RenderCanvas(max_fps=60)) scene = gfx.Scene() camera = gfx.PerspectiveCamera(35, 16 / 9) camera.local.position = (46, 22, -21) camera.show_pos((0, 7, 0)) gfx.OrbitController(camera, register_events=renderer) floor = gfx.Mesh( gfx.plane_geometry(2000, 2000), gfx.MeshPhongMaterial(color="#808080", side="Front"), ) floor.local.rotation = la.quat_from_euler(-math.pi / 2, order="X") floor.local.position = (0, -0.05, 0) floor.receive_shadow = True box = gfx.Mesh( gfx.box_geometry(3, 1, 2), gfx.MeshPhongMaterial(color="#aaaaaa"), ) box.cast_shadow = True box.receive_shadow = True box.local.position = (0, 5, 0) ambient = gfx.AmbientLight("#111111") def create_spot_light(color) -> gfx.SpotLight: light = gfx.SpotLight(color, 2000, angle=0.3, penumbra=0.2, decay=2) light.cast_shadow = True return light spot_light1 = create_spot_light("#ff7f00") spot_light2 = create_spot_light("#00ff7f") spot_light3 = create_spot_light("#7f00ff") spot_light1.local.position = (15, 40, 45) spot_light2.local.position = (0, 40, 35) spot_light3.local.position = (-15, 40, 45) spot_light1.add(gfx.SpotLightHelper()) spot_light2.add(gfx.SpotLightHelper()) spot_light3.add(gfx.SpotLightHelper()) scene.add(box) scene.add(floor) scene.add(ambient) scene.add(spot_light1, spot_light2, spot_light3) tweens = [Tween(spot_light1), Tween(spot_light2), Tween(spot_light3)] def animate(): for tween in tweens: if tween.since_last_start > 5: tween.to( { "angle": random.random() * 0.7 + 0.1, "penumbra": random.random() + 1, "local": { "x": random.random() * 30 - 15, "y": random.random() * 10 + 15, "z": random.random() * 30 - 15, }, }, random.random() * 3 + 2, ).lerp_func(lambda t: t * (2 - t)) tween.update() renderer.render(scene, camera) renderer.request_draw() renderer.request_draw(animate) return renderer if __name__ == "__main__": renderer = init_scene() loop.run() .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.685 seconds) .. _sphx_glr_download__gallery_feature_demo_light_spotlight_shadows.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: light_spotlight_shadows.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: light_spotlight_shadows.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: light_spotlight_shadows.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_ .. only:: html Interactive example ------------------- Try this example in your browser using Pyodide. Might not work with all examples and all devices. Check the output and your browser's console for details. .. raw:: html