{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%gui qt" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n# Animate an Image\n\nUse a timer to trigger updating an image.\n\nThis example demonstrates a 3D Texture. The volume contains noise that\nis smoothed in the z-direction. Shown is one slice through that volume\nto give the effect of \"morphing\" noise.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import numpy as np\n\nfrom vispy.util.transforms import ortho\nfrom vispy import gloo\nfrom vispy import app\nfrom vispy.visuals.shaders import ModularProgram\n\n\n# Shape of image to be displayed\nD, H, W = 30, 60, 90\n\n# Modulated image\nimg_array = np.random.uniform(0, 0.1, (D, H, W, 3)).astype(np.float32)\n# Depth slices are dark->light\nimg_array[...] += np.linspace(0, 0.9, D)[:, np.newaxis, np.newaxis, np.newaxis]\n# Make vertical direction more green moving upward\nimg_array[..., 1] *= np.linspace(0, 1, H)[np.newaxis, :, np.newaxis]\n# Make horizontal direction more red moving rightward\nimg_array[..., 0] *= np.linspace(0, 1, W)[np.newaxis, np.newaxis, :]\n\n# A simple texture quad\ndata = np.zeros(4, dtype=[('a_position', np.float32, 2),\n ('a_texcoord', np.float32, 2)])\ndata['a_position'] = np.array([[0, 0], [W, 0], [0, H], [W, H]])\ndata['a_texcoord'] = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])\n\n\nVERT_SHADER = \"\"\"\n// Uniforms\nuniform mat4 u_model;\nuniform mat4 u_view;\nuniform mat4 u_projection;\n\n// Attributes\nattribute vec2 a_position;\nattribute vec2 a_texcoord;\n\n// Varyings\nvarying vec2 v_texcoord;\n\n// Main\nvoid main (void)\n{\n v_texcoord = a_texcoord;\n gl_Position = u_projection * u_view * u_model * vec4(a_position,0.0,1.0);\n}\n\"\"\"\n\nFRAG_SHADER = \"\"\"\nuniform $sampler_type u_texture;\nuniform float i;\nvarying vec2 v_texcoord;\nvoid main()\n{\n // step through gradient with i, note that slice (depth) comes last here!\n gl_FragColor = $sample(u_texture, vec3(v_texcoord, i));\n gl_FragColor.a = 1.0;\n}\n\n\"\"\"\n\n\nclass Canvas(app.Canvas):\n\n def __init__(self, emulate3d=True):\n app.Canvas.__init__(self, keys='interactive', size=((W*5), (H*5)))\n\n if emulate3d:\n tex_cls = gloo.TextureEmulated3D\n else:\n tex_cls = gloo.Texture3D\n self.texture = tex_cls(img_array, interpolation='nearest',\n wrapping='clamp_to_edge')\n\n self.program = ModularProgram(VERT_SHADER, FRAG_SHADER)\n self.program.frag['sampler_type'] = self.texture.glsl_sampler_type\n self.program.frag['sample'] = self.texture.glsl_sample\n self.program['u_texture'] = self.texture\n self.program['i'] = 0.0\n self.program.bind(gloo.VertexBuffer(data))\n\n self.view = np.eye(4, dtype=np.float32)\n self.model = np.eye(4, dtype=np.float32)\n self.projection = np.eye(4, dtype=np.float32)\n\n self.program['u_model'] = self.model\n self.program['u_view'] = self.view\n self.projection = ortho(0, W, 0, H, -1, 1)\n self.program['u_projection'] = self.projection\n\n self.i = 0\n\n gloo.set_clear_color('white')\n\n self._timer = app.Timer('auto', connect=self.on_timer, start=True)\n\n self.show()\n\n def on_resize(self, event):\n width, height = event.physical_size\n gloo.set_viewport(0, 0, width, height)\n self.projection = ortho(0, width, 0, height, -100, 100)\n self.program['u_projection'] = self.projection\n\n # Compute the new size of the quad\n r = width / float(height)\n R = W / float(H)\n if r < R:\n w, h = width, width / R\n x, y = 0, int((height - h) / 2)\n else:\n w, h = height * R, height\n x, y = int((width - w) / 2), 0\n data['a_position'] = np.array(\n [[x, y], [x + w, y], [x, y + h], [x + w, y + h]])\n self.program.bind(gloo.VertexBuffer(data))\n\n def on_timer(self, event):\n # cycle every 2 sec\n self.i = (self.i + 1./120.) % 1.0\n self.update()\n\n def on_draw(self, event):\n gloo.clear(color=True, depth=True)\n self.program['i'] = 1.9 * np.abs(0.5 - self.i)\n self.program.draw('triangle_strip')\n\n\nif __name__ == '__main__':\n # Use emulated3d to switch from an emulated 3D texture to an actual one\n canvas = Canvas(emulate3d=True)\n app.run()" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.19" } }, "nbformat": 4, "nbformat_minor": 0 }