{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "%gui qt" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n# Example using texture internalformat for higher precision\n\nGenerates a gradient texture with high dynamic range and renders it\nwith a fragment shader that tests for quantization errors by comparing\nadjacent texels and decomposes the gradient values into high and low\nsignificance bits, mapping them to separate display color channels.\n\nPressing the 'f' key cycles through a list of different texture\nformats to show the different levels of precision available.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import numpy as np\nfrom vispy import gloo\nfrom vispy import app\n\nW, H = 1024, 1024\n\n# prepare a gradient field with high dynamic range\ndata = np.zeros((H, W, 3), np.float32)\n\nfor i in range(W):\n data[:, i, :] = i**2\n\nfor i in range(H):\n data[i, :, :] *= i**2\n\ndata *= 1./data.max()\n\n# prepare a simple quad to cover the viewport\nquad = np.zeros(4, dtype=[\n ('a_position', np.float32, 2),\n ('a_texcoord', np.float32, 2)\n])\n\nquad['a_position'] = np.array([[-1, -1], [+1, -1], [-1, +1], [+1, +1]])\nquad['a_texcoord'] = np.array([[0, 0], [1, 0], [0, 1], [1, 1]])\n\nvert_shader = \"\"\"\nattribute vec2 a_position;\nattribute vec2 a_texcoord;\nvarying vec2 v_texcoord;\n\nvoid main()\n{\n v_texcoord = a_texcoord;\n gl_Position = vec4(a_position, 0.0, 1.0);\n}\n\"\"\"\n\nfrag_shader = \"\"\"\nuniform sampler2D u_texture;\nvarying vec2 v_texcoord;\n\nvoid main()\n{\n float ndiff;\n // an adjacent texel is 1/W further over in normalized texture coordinates\n vec2 v_texcoord2 = vec2(clamp(v_texcoord.x + 1.0/%(W)d., 0.0, 1.0),\n v_texcoord.y);\n vec4 texel1 = texture2D(u_texture, v_texcoord);\n vec4 texel2 = texture2D(u_texture, v_texcoord2);\n\n // test for quantized binning of adjacent texels\n if (texel1.r == texel2.r && v_texcoord2.x < 1.0 && v_texcoord.y > 0.0)\n ndiff = 1.0;\n else\n ndiff = 0.0;\n\n gl_FragColor = vec4(\n fract(texel1.r * 255.0), // render low-significance bits as red\n texel1.r, // render high-significance bits as green\n ndiff, // flag quantized bands as blue\n 1);\n}\n\"\"\" % dict(W=W)\n\n\nclass Canvas(app.Canvas):\n\n def __init__(self):\n app.Canvas.__init__(self, size=(W, H), keys='interactive')\n\n self._internalformats = [\n 'rgb8',\n 'rgb16',\n 'rgb16f',\n 'rgb32f'\n ]\n\n self.program = gloo.Program(vert_shader, frag_shader)\n self.program.bind(gloo.VertexBuffer(quad))\n self._internalformat = -1\n self.texture = gloo.Texture2D(\n shape=(H, W, 3),\n interpolation='nearest'\n )\n\n gloo.set_viewport(0, 0, *self.physical_size)\n\n self.toggle_internalformat()\n\n self.show()\n\n def on_key_press(self, event):\n if event.key == 'F':\n self.toggle_internalformat()\n\n def toggle_internalformat(self):\n self._internalformat = (\n (self._internalformat + 1)\n % len(self._internalformats)\n )\n internalformat = self._internalformats[self._internalformat]\n print(\"Requesting texture internalformat %s\" % internalformat)\n self.texture.resize(\n data.shape,\n format='rgb',\n internalformat=internalformat\n )\n self.texture.set_data(data)\n self.program['u_texture'] = self.texture\n self.update()\n\n def on_resize(self, event):\n gloo.set_viewport(0, 0, *event.physical_size)\n\n def on_draw(self, event):\n gloo.clear(color=True, depth=True)\n self.program.draw('triangle_strip')\n\nif __name__ == '__main__':\n c = Canvas()\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 }