Vizard 7 » Reference » Shaders » Post-Process Effects » Composite effects
7.6

Composite effects

The vizfx.postprocess.composite library is a collection of effects that combine multiple effects into a single effect pass. This library can also be used to create your own composite effect.

 

All the composite effects listed in this section accept a value of None as an input effect, causing the incoming image color to be used instead. Calling remove() on a composite effect will automatically remove all the contained effects as well.

Horizontal Split

Split the image horizontally and apply separate effects to the left and right portions.

Constructor

Description

HorizontalSplitEffect(

    left = None,

    right = None,

    offset = 0.5

)

Create the horizontal split effect using the left and right effects. The effect will split the image at the specified horizontal offset.

 

Method

Description

<effect>.setOffset(offset)

Set the horizontal split offset in normalized (0-1) image units.

<effect>.getOffset()

Get the horizontal split offset in normalized (0-1) image units.

<effect>.getLeftEffect()

Get effect assigned to left of split.

<effect>.getRightEffect()

Get effect assigned to right of split.

This effect can be registered with vizconfig.

import vizfx.postprocess
from vizfx.postprocess.color import GrayscaleEffect
from vizfx.postprocess.composite import HorizontalSplitEffect
effect = HorizontalSplitEffect(left=GrayscaleEffect())
vizfx.postprocess.addEffect(effect)

Vertical Split

Split the image vertically and apply separate effects to the top and bottom portions.

Constructor

Description

VerticalSplitEffect(

    bottom = None,

    top = None,

    offset = 0.5

)

Create the vertical split effect using the bottom and top effects. The effect will split the image at the specified vertical offset.

 

Method

Description

<effect>.setOffset(offset)

Set the vertical split offset in normalized (0-1) image units.

<effect>.getOffset()

Get the vertical split offset in normalized (0-1) image units.

<effect>.getBottomEffect()

Get effect assigned to bottom of split.

<effect>.getTopEffect()

Get effect assigned to top of split.

This effect can be registered with vizconfig.

import vizfx.postprocess
from vizfx.postprocess.color import GrayscaleEffect
from vizfx.postprocess.composite import VerticalSplitEffect
effect = VerticalSplitEffect(top=GrayscaleEffect())
vizfx.postprocess.addEffect(effect)

Viewport

Split the image using a rectangular viewport and apply separate effects to the inside and outside portions.

Constructor

Description

ViewportEffect(

    inside = None,

    outside = None,

    pos = (0.25,0.25),

    size = (0.5,0.5)

)

Create the viewport effect using the inside and outside effects. The lower-left corner of the viewport will be positioned at pos with the specified size, both in normalized (0-1) image units.

 

Method

Description

<effect>.setPosition(pos)

Set the viewport lower-left (x,y) position in normalized image units.

<effect>.getPosition()

Get the viewport lower-left (x,y) position in normalized image units.

<effect>.setSize(size)

Set the viewport (width,height) in normalized image units.

<effect>.getSize()

Get the viewport (width,height) in normalized image units.

<effect>.getInsideEffect()

Get effect assigned to inside of viewport.

<effect>.getOutsideEffect()

Get effect assigned to outside of viewport.

This effect can be registered with vizconfig.

import vizfx.postprocess
from vizfx.postprocess.color import GrayscaleEffect
from vizfx.postprocess.composite import ViewportEffect
effect = ViewportEffect(inside=GrayscaleEffect())
vizfx.postprocess.addEffect(effect)

Blend

Blend between two effects.

Constructor

Description

BlendEffect(

    effect1 = None,

    effect2 = None,

    blend = 0.5

)

Create the blend effect using the effect1 and effect2 effects. The effects will be linearly blended by the specified blend amount. If the amount is 0, then 100% of effect1 will be displayed. If the amount is 1, then 100% of effect2 will be displayed.

 

Method

Description

<effect>.setBlend(amount)

Set the blend amount (0-1).

<effect>.getBlend()

Get the blend amount (0-1).

<effect>.getEffect1()

Get the effect assigned to 0% blend.

<effect>.getEffect2()

Get the effect assigned to 100% blend.

This effect can be registered with vizconfig.

import vizfx.postprocess
from vizfx.postprocess.color import GrayscaleEffect
from vizfx.postprocess.composite import BlendEffect
effect = BlendEffect(effect1=GrayscaleEffect())
vizfx.postprocess.addEffect(effect)

Blend Mask

Blend between two effects using a grayscale texture mask. The texture mask is stretched to fit the dimensions of the image.

 

Texture mask used for the image above:

Constructor

Description

BlendMaskEffect(

    mask,

    black = None,

    white = None,

    offset = (0,0)

)

Create the blend effect that uses the specified mask to combine the black and white effects. The effects will be linearly blended using the grayscale value of the mask at each pixel of the image. The mask can be moved across the image using an offset value in normalized image units.

 

Method

Description

<effect>.setMaskOffset(offset)

Set the (x,y) offset of the mask in normalized image units.

<effect>.getMaskOffset()

Get the (x,y) offset of the mask in normalized image units.

<effect>.getBlackEffect()

Get effect assigned to black color of mask.

<effect>.getWhiteEffect()

Get effect assigned to white color of mask.

This effect can be registered with vizconfig.

import vizfx.postprocess
from vizfx.postprocess.color import GrayscaleEffect
from vizfx.postprocess.composite import BlendMaskEffect
mask = viz.addTexture('mask.png')
effect = BlendMaskEffect(mask,black=GrayscaleEffect())
vizfx.postprocess.addEffect(effect)

Color Channel

Apply separate effects for each RGB color channel.

Constructor

Description

ColorChannelEffect(

    red = None,

    green = None,

    blue = None

)

Create the color channel effect using the red, green, and blue effects.

 

Method

Description

<effect>.getRedEffect()

Get effect assigned to red channel.

<effect>.getGreenEffect()

Get effect assigned to green channel.

<effect>.getBlueEffect()

Get effect assigned to blue channel.

import vizfx.postprocess
from vizfx.postprocess.color import ContrastEffect
from vizfx.postprocess.composite import ColorChannelEffect
effect = ColorChannelEffect(red=ContrastEffect(0.5))
vizfx.postprocess.addEffect(effect)

Stereo

Apply separate effects for the left and right eyes when viewing in stereo.

Constructor

Description

StereoEffect(

    left = None,

    right = None

)

Create the stereo effect using the left and right eye effects.

 

Method

Description

<effect>.getLeftEffect()

Get effect assigned to left eye.

<effect>.getRightEffect()

Get effect assigned to right eye.

import vizfx.postprocess
from vizfx.postprocess.color import GrayscaleEffect
from vizfx.postprocess.composite import StereoEffect
effect = StereoEffect(left=GrayscaleEffect())
vizfx.postprocess.addEffect(effect)

Custom composite effects

You can create your own composite effect using the CompositeEffect base class found in the vizfx.postprocess.composite library.

 

For example, let's create a composite effect that splits the image diagonally. The first thing to do is to define a class that inherits from CompositeEffect:

from vizfx.postprocess.composite import CompositeEffect

class DiagonalSplitEffect(CompositeEffect):
    pass

The next step is to create a constructor for our class that initializes the base class with a list of effects to be composited. In our example we will be compositing two effects, one for the upper left corner and another for the lower right corner:

from vizfx.postprocess.composite import CompositeEffect

class DiagonalSplitEffect(CompositeEffect):

    def __init__(self,upperLeft=None,lowerRight=None,**kw):
        CompositeEffect.__init__(self,[upperLeft,lowerRight],**kw)

The last and most important step is to specify the shader code that will be used to combine the effects. This code is specified through the _getCompositeCode method. The compositing code uses special tags as a placeholder for inserting the composited effects. The tags are of the form <effectX>, where X is the 0-based index of the effect passed to the CompositeEffect constructor. The line after the effect placeholder will contain the output color of that effect in the gl_FragColor variable.

 

For our diagonal split example, we use the incoming image coordinates to determine whether to display the upper left effect, <effect0>, or the lower right effect, <effect1>:

from vizfx.postprocess.composite import CompositeEffect

class DiagonalSplitEffect(CompositeEffect):

    def __init__(self,upperLeft=None,lowerRight=None,**kw):
        CompositeEffect.__init__(self,[upperLeft,lowerRight],**kw)

    def _getCompositeCode(self):
        return """
        void main()
        {
            vec2 uv = gl_TexCoord[0].st;
            if(uv.x < uv.y) {
                <effect0>
            } else {
                <effect1>
            }
        }
        """

Since CompositeEffect inherits from BaseShaderEffect, you can optionally add a _createUniforms method to add uniform parameters to your composite code.

 

Finally, here is our custom composite effect in action:

import vizfx.postprocess
from vizfx.postprocess.color import GrayscaleEffect
effect = DiagonalSplitEffect(GrayscaleEffect())
vizfx.postprocess.addEffect(effect)

Post-Process Basics

Color Effects

Distort Effects

Blur Effects

Transform Effects

Composite Effects