Table Of Contents
EffectWidget¶
New in version 1.9.0.
The EffectWidget
is able to apply a variety of fancy
graphical effects to
its children. It works by rendering to a series of
Fbo
instances with custom opengl fragment shaders.
As such, effects can freely do almost anything, from inverting the
colors of the widget, to anti-aliasing, to emulating the appearance of a
crt monitor!
Warning
This code is still experimental, and its API is subject to change in a future version.
The basic usage is as follows:
w = EffectWidget()
w.add_widget(Button(text='Hello!')
w.effects = [InvertEffect(), HorizontalBlurEffect(size=2.0)]
The equivalent in kv would be:
#: import ew kivy.uix.effectwidget
EffectWidget:
effects: ew.InvertEffect(), ew.HorizontalBlurEffect(size=2.0)
Button:
text: 'Hello!'
The effects can be a list of effects of any length, and they will be applied sequentially.
The module comes with a range of prebuilt effects, but the interface is designed to make it easy to create your own. Instead of writing a full glsl shader, you provide a single function that takes some inputs based on the screen (current pixel color, current widget texture etc.). See the sections below for more information.
Usage Guidelines¶
It is not efficient to resize an EffectWidget
, as
the Fbo
is recreated on each resize event.
If you need to resize frequently, consider doing things a different
way.
Although some effects have adjustable parameters, it is
not efficient to animate these, as the entire
shader is reconstructed every time. You should use glsl
uniform variables instead. The AdvancedEffectBase
may make this easier.
Note
The EffectWidget
cannot draw outside its own
widget area (pos -> pos + size). Any child widgets
overlapping the boundary will be cut off at this point.
Provided Effects¶
The module comes with several pre-written effects. Some have adjustable properties (e.g. blur radius). Please see the individual effect documentation for more details.
MonochromeEffect
- makes the widget grayscale.InvertEffect
- inverts the widget colors.ChannelMixEffect
- swaps color channels.ScanlinesEffect
- displays flickering scanlines.PixelateEffect
- pixelates the image.HorizontalBlurEffect
- Gaussuan blurs horizontally.VerticalBlurEffect
- Gaussuan blurs vertically.FXAAEffect
- applies a very basic anti-aliasing.
Creating Effects¶
Effects are designed to make it easy to create and use your own
transformations. You do this by creating and using an instance of
EffectBase
with your own custom EffectBase.glsl
property.
The glsl property is a string representing part of a glsl fragment
shader. You can include as many functions as you like (the string
is simply spliced into the whole shader), but it
must implement a function effect
as below:
vec4 effect(vec4 color, sampler2D texture, vec2 tex_coords, vec2 coords)
{
// ... your code here
return something; // must be a vec4 representing the new color
}
The full shader will calculate the normal pixel color at each point,
then call your effect
function to transform it. The
parameters are:
- color: The normal color of the current pixel (i.e. texture sampled at tex_coords).
- texture: The texture containing the widget’s normal background.
- tex_coords: The normal texture_coords used to access texture.
- coords: The pixel indices of the current pixel.
The shader code also has access to two useful uniform variables,
time
containing the time (in seconds) since the program start,
and resolution
containing the shape (x pixels, y pixels) of
the widget.
For instance, the following simple string (taken from the InvertEffect) would invert the input color but set alpha to 1.0:
vec4 effect(vec4 color, sampler2D texture, vec2 tex_coords, vec2 coords)
{
return vec4(1.0 - color.xyz, 1.0);
}
You can also set the glsl by automatically loading the string from a
file, simply set the EffectBase.source
property of an effect.
-
class
kivy.uix.effectwidget.
EffectWidget
(**kwargs)[source]¶ Bases:
kivy.uix.relativelayout.RelativeLayout
Widget with the ability to apply a series of graphical effects to its children. See the module documentation for more information on setting effects and creating your own.
-
add_widget
(widget)[source]¶ Add a new widget as a child of this widget.
Parameters: - widget:
Widget
Widget to add to our list of children.
- index: int, defaults to 0
Index to insert the widget in the list. Notice that the default of 0 means the widget is inserted at the beginning of the list and will thus be drawn on top of other sibling widgets. For a full discussion of the index and widget hierarchy, please see the Widgets Programming Guide.
New in version 1.0.5.
- canvas: str, defaults to None
Canvas to add widget’s canvas to. Can be ‘before’, ‘after’ or None for the default canvas.
New in version 1.9.0.
>>> from kivy.uix.button import Button >>> from kivy.uix.slider import Slider >>> root = Widget() >>> root.add_widget(Button()) >>> slider = Slider() >>> root.add_widget(slider)
- widget:
-
background_color
¶ This defines the background color to be used for the fbo in the EffectWidget.
background_color
is aListProperty
defaults to (0, 0, 0, 0)
-
clear_widgets
(children=None)[source]¶ Remove all (or the specified)
children
of this widget. If the ‘children’ argument is specified, it should be a list (or filtered list) of children of the current widget.Changed in version 1.8.0: The children argument can be used to specify the children you want to remove.
-
effects
¶ List of all the effects to be applied. These should all be instances or subclasses of
EffectBase
.effects is a
ListProperty
and defaults to [].
-
fbo_list
¶ (internal) List of all the fbos that are being used to apply the effects.
fbo_list is a
ListProperty
and defaults to [].
-
refresh_fbo_setup
(*args)[source]¶ (internal) Creates and assigns one
Fbo
per effect, and makes sure all sizes etc. are correct and consistent.
-
remove_widget
(widget)[source]¶ Remove a widget from the children of this widget.
Parameters: - widget:
Widget
Widget to remove from our children list.
>>> from kivy.uix.button import Button >>> root = Widget() >>> button = Button() >>> root.add_widget(button) >>> root.remove_widget(button)
- widget:
-
texture
¶ The output texture of the final
Fbo
after all effects have been applied.texture is an
ObjectProperty
and defaults to None.
-
-
class
kivy.uix.effectwidget.
EffectBase
(*args, **kwargs)[source]¶ Bases:
kivy.event.EventDispatcher
The base class for GLSL effects. It simply returns its input.
See the module documentation for more details.
-
fbo
¶ The fbo currently using this effect. The
EffectBase
automatically handles this.fbo
is anObjectProperty
and defaults to None.
-
glsl
¶ The glsl string defining your effect function. See the module documentation for more details.
glsl
is aStringProperty
and defaults to a trivial effect that returns its input.
-
set_fbo_shader
(*args)[source]¶ Sets the
Fbo
’s shader by splicing theglsl
string into a full fragment shader.The full shader is made up of
shader_header + shader_uniforms + self.glsl + shader_footer_effect
.
-
source
¶ The (optional) filename from which to load the
glsl
string.source
is aStringProperty
and defaults to ‘’.
-
-
class
kivy.uix.effectwidget.
AdvancedEffectBase
(*args, **kwargs)[source]¶ Bases:
kivy.uix.effectwidget.EffectBase
An
EffectBase
with additional behavior to easily set and update uniform variables in your shader.This class is provided for convenience when implementing your own effects: it is not used by any of those provided with Kivy.
In addition to your base glsl string that must be provided as normal, the
AdvancedEffectBase
has an extra propertyuniforms
, a dictionary of name-value pairs. Whenever a value is changed, the new value for the uniform variable is uploaded to the shader.You must still manually declare your uniform variables at the top of your glsl string.
-
set_fbo_shader
(*args)[source]¶ Sets the
Fbo
’s shader by splicing theglsl
string into a full fragment shader.The full shader is made up of
shader_header + shader_uniforms + self.glsl + shader_footer_effect
.
-
uniforms
¶ A dictionary of uniform variable names and their values. These are automatically uploaded to the
fbo
shader if appropriate.uniforms is a
DictProperty
and defaults to {}.
-
-
class
kivy.uix.effectwidget.
MonochromeEffect
(*args, **kwargs)[source]¶ Bases:
kivy.uix.effectwidget.EffectBase
Returns its input colors in monochrome.
-
class
kivy.uix.effectwidget.
InvertEffect
(*args, **kwargs)[source]¶ Bases:
kivy.uix.effectwidget.EffectBase
Inverts the colors in the input.
-
class
kivy.uix.effectwidget.
ChannelMixEffect
(*args, **kwargs)[source]¶ Bases:
kivy.uix.effectwidget.EffectBase
Mixes the color channels of the input according to the order property. Channels may be arbitrarily rearranged or repeated.
-
order
¶ The new sorted order of the rgb channels.
order is a
ListProperty
and defaults to [1, 2, 0], corresponding to (g, b, r).
-
-
class
kivy.uix.effectwidget.
ScanlinesEffect
(*args, **kwargs)[source]¶ Bases:
kivy.uix.effectwidget.EffectBase
Adds scanlines to the input.
-
class
kivy.uix.effectwidget.
PixelateEffect
(*args, **kwargs)[source]¶ Bases:
kivy.uix.effectwidget.EffectBase
Pixelates the input according to its
pixel_size
-
pixel_size
¶ Sets the size of a new ‘pixel’ in the effect, in terms of number of ‘real’ pixels.
pixel_size is a
NumericProperty
and defaults to 10.
-
-
class
kivy.uix.effectwidget.
HorizontalBlurEffect
(*args, **kwargs)[source]¶ Bases:
kivy.uix.effectwidget.EffectBase
Blurs the input horizontally, with the width given by
size
.-
size
¶ The blur width in pixels.
size is a
NumericProperty
and defaults to 4.0.
-
-
class
kivy.uix.effectwidget.
VerticalBlurEffect
(*args, **kwargs)[source]¶ Bases:
kivy.uix.effectwidget.EffectBase
Blurs the input vertically, with the width given by
size
.-
size
¶ The blur width in pixels.
size is a
NumericProperty
and defaults to 4.0.
-
-
class
kivy.uix.effectwidget.
FXAAEffect
(*args, **kwargs)[source]¶ Bases:
kivy.uix.effectwidget.EffectBase
Applies very simple anti-aliasing via fxaa.