Skip to content

Instantly share code, notes, and snippets.

@kmuehlbauer
Created August 18, 2015 15:46
Show Gist options
  • Save kmuehlbauer/6e2cb27c55655d4bdef8 to your computer and use it in GitHub Desktop.
Save kmuehlbauer/6e2cb27c55655d4bdef8 to your computer and use it in GitHub Desktop.
Proof of concept spatial interpolation filter working on VisPy ImageVisual
_interpolation_template = """
#include "misc/spatial-filters.frag"
vec4 texture_lookup_filtered(vec2 texcoord) {
if(texcoord.x < 0.0 || texcoord.x > 1.0 ||
texcoord.y < 0.0 || texcoord.y > 1.0) {
discard;
}
return %s($texture, $shape, texcoord);
}"""
_texture_lookup = """
vec4 texture_lookup(vec2 texcoord) {
if(texcoord.x < 0.0 || texcoord.x > 1.0 ||
texcoord.y < 0.0 || texcoord.y > 1.0) {
discard;
}
return texture2D($texture, texcoord);
}"""
class Interpolation(object):
def __init__(self, interpolation='nearest'):
self.shader = Function("""
""")
# load interpolation kernel
self._kernel, self._interpolation_names = load_spatial_filters()
# create interpolation shader functions for available
# interpolations
fun = [Function(_interpolation_template % n)
for n in self._interpolation_names]
self._interpolation_names = [n.lower()
for n in self._interpolation_names]
self._interpolation_fun = dict(zip(self._interpolation_names, fun))
self.interpolation_filters = self._interpolation_names
# overwrite "nearest" and "bilinear" spatial-filters
# with "hardware" interpolation _data_lookup_fn
self._interpolation_fun['nearest'] = Function(_texture_lookup)
self._interpolation_fun['bilinear'] = Function(_texture_lookup)
# create interpolation kernel Texture2D, using 'r16f'
# as discussed in issue #1017
self._kerneltex = Texture2D(self._kernel, interpolation='nearest',
internalformat='r16f')
if interpolation not in self._interpolation_names:
raise ValueError("interpolation must be one of %s" %
', '.join(self._interpolation_names))
self._interpolation = interpolation
# check texture interpolation
if self._interpolation == 'bilinear':
texture_interpolation = 'linear'
else:
texture_interpolation = 'nearest'
self._attvis = None
def _attach(self, visual):
self._attvis = visual
self._build_interpolation(visual)
@property
def interpolation(self):
return self._interpolation
@interpolation.setter
def interpolation(self, i):
if i not in self._interpolation_names:
raise ValueError("interpolation must be one of %s" % ', '.join(self._interpolation_names))
#if self.interpolation != i:
self._interpolation = i
self._build_interpolation(self._attvis)
print(i)
#self._need_interpolation_update = True
#self.update()
@property
def interpolation_functions(self):
return self._interpolation_names
def _build_interpolation(self, visual):
"""Rebuild the _data_lookup_fn using different interpolations within
the shader
"""
interpolation = self._interpolation
visual._data_lookup_fn = self._interpolation_fun[interpolation]
visual.shared_program.frag['get_data'] = visual._data_lookup_fn
# only 'Bilinear' uses 'linear' texture interpolation
if interpolation == 'bilinear':
texture_interpolation = 'linear'
else:
# 'Nearest' (and also 'Bilinear') doesn't use spatial_filters.frag
# so u_kernel and shape setting is skipped
texture_interpolation = 'nearest'
if interpolation != 'nearest':
visual.shared_program['u_kernel'] = self._kerneltex
visual._data_lookup_fn['shape'] = visual._data.shape[:2][::-1]
if visual._texture.interpolation != texture_interpolation:
visual._texture.interpolation = texture_interpolation
visual._data_lookup_fn['texture'] = visual._texture
visual.update()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment