Adjazent | Alan Ross


More Pixel Bender

Here are some more Pixel Bender experiments and variations of the shaders from my previous Pixel Bender post, again using the cow Collada model from Papervision2.
But first before we look further into pixel bender source code here is the actionscript part to integrate and make use of the shader (.pbj).

private const _buffer: BitmapData = new BitmapData( 600, 400, false );

private var _shader: Shader;
private var _loader: URLLoader;
private var _view: BasicView;

//...

private function loadShader( shaderUrl: String )
{
	_loader = new URLLoader();
	_loader.dataFormat = URLLoaderDataFormat.BINARY;
	_loader.addEventListener(Event.COMPLETE, onLoadComplete );
	_loader.load( new URLRequest( shaderUrl ) );
}

private function onLoadComplete( event: Event ): void
{
	_shader = new Shader( _loader.data );
	//... get Shader info, if you wish
	//... setup the 3d stuff
	_view = new BasicView( 600, 400, false );
	//...
	stage.addEventListener( Event.ENTER_FRAME, render );
}

private function render( e: Event ): void
{
	_view.singleRender();
	applyShader();
}

private function applyShader(): void
{
	_buffer.fillRect( _dim, 0xffffff );
	//whatever you want to have as input for pb
	_buffer.draw( _view );
	//in the pb file you will find something like 'input image3 src;'
	_shader.data.src.input = _buffer;

	graphics.clear();
	graphics.beginShaderFill( _shader );
	graphics.drawRect( 0, 0, dim.width, dim.height );
	graphics.endFill();
}

That is all you need to make use of the pbj. If you use the Shader as a ShaderFilter you will adjust the code.

Pixel Bender Shader Contrast Outline
You can view the Pixel Bender ‘Contrast Outline’ example in action here. The Pixel Bender code is as follows:

<languageVersion : 1.0;>

kernel Outline
<   namespace : "ar.shader.outline";
    vendor : "Alan Ross";
    version : 1;
    description : "Outline";
>{
    parameter float n0
    <
        minValue: 0.0;
        maxValue: 1.0;
        defaultValue: 0.0;
    >;
    parameter float n1
    <
        minValue: 0.2;
        maxValue: 1.0;
        defaultValue: 0.5;
    >;

    input image3 src;
    output pixel3 dst;

    void evaluatePixel()
    {
        float2 p = outCoord();
        float2 offset;
        float dist;
        float3 c, m, p0, p1, p2, p3, p4, p5, p6, p7, p8;

        float3 w = float3( 1.0, 1.0, 1.0 );
        float3 b = float3( 0.0, 0.0, 0.0 );
        c = float3( n0, n0, n0 );

        dist = n1 * 1.0;
        offset.x = 0.0; offset.y = 0.0;
        p0 = sample( src, p + offset ); offset.x = -dist; offset.y = -dist;
        p1 = sample( src, p + offset ); offset.x =  0.0;  offset.y = -dist;
        p2 = sample( src, p + offset ); offset.x =  dist; offset.y = -dist;
        p3 = sample( src, p + offset ); offset.x =  dist; offset.y =  0.0;
        p4 = sample( src, p + offset ); offset.x =  dist; offset.y =  dist;
        p5 = sample( src, p + offset ); offset.x =  0.0;  offset.y =  dist;
        p6 = sample( src, p + offset ); offset.x = -dist; offset.y =  dist;
        p7 = sample( src, p + offset ); offset.x = -dist; offset.y =  0.0;
        p8 = sample( src, p + offset ); 

        c = w;

        if( all( greaterThan( p0, p1 ) ) ){ c = b; }
        if( all( greaterThan( p0, p3 ) ) ){ c = b; }
        if( all( greaterThan( p0, p5 ) ) ){ c = b; }
        if( all( greaterThan( p0, p7 ) ) ){ c = b; }

        c.r = c.r * p0.r / 0.5;
        c.g = c.g * p0.g / 0.5;
        c.b = c.b * p0.b / 0.5;

        dst = c;
    }
}

Pixel Bender Shader Pencil

This shader resembles something like a pencil/charcoal drawing. Here is the Pixel Bender source:

<languageVersion : 1.0;>

kernel Pencil
<   namespace : "ar.shader.pencil";
    vendor : "Alan Ross";
    version : 1;
    description : "Pencil";
>
{
    parameter float n0
    <
        defaultValue :97.0;
        minValue : 0.0;
        maxValue : 100.0;
    >;
    parameter float n1
    <
        defaultValue : 15.0;
        minValue : 0.0;
        maxValue : 100.0;
    >;
    parameter float n2
    <
        defaultValue : 97.0;
        minValue : 0.0;
        maxValue : 100.0;
    >;
    parameter float n3
    <
        defaultValue : 9.7;
        minValue : 0.0;
        maxValue : 10.0;
    >;

    input image4 src;
    output pixel4 result;

    void evaluatePixel()
    {
        float2 p = outCoord();
        float2 offset;
        float dist, temp;
        float4 c, m, p0, p1, p2, p3, p4, p5, p6, p7, p8;

        dist = n3;
        offset.x = 0.0; offset.y = 0.0;
        p0 = sampleNearest( src, p + offset ); offset.x = -dist; offset.y = -dist;
        p1 = sampleNearest( src, p + offset ); offset.x =  dist; offset.y = -dist;
        p2 = sampleNearest( src, p + offset ); offset.x =  dist; offset.y =  dist;
        p3 = sampleNearest( src, p + offset ); offset.x = -dist; offset.y =  dist; dist = n3 * 2.0;
        p4 = sampleNearest( src, p + offset ); offset.x = -dist; offset.y = -dist;
        p5 = sampleNearest( src, p + offset ); offset.x =  dist; offset.y = -dist;
        p6 = sampleNearest( src, p + offset ); offset.x =  dist; offset.y =  dist;
        p7 = sampleNearest( src, p + offset ); offset.x = -dist; offset.y =  dist;
        p8 = sampleNearest( src, p + offset );

        m = ( ( p0 * n2 ) + ( p1 * n0 ) + ( p2 * n0 ) + ( p3 * n0 ) + ( p4 * n0 )
        + ( p5 * n1 ) + ( p6 * n1 ) + ( p7 * n1 ) + ( p8 * n1 ) ) / ( n2 + ( 4.0 * n0 ) + ( 4.0 * n1 ) );

        //----------------------- convert to b/w
        temp = ( p0.r + p0.g + p0.b ) / 3.0;
        p0.r = p0.g = p0.b = temp;

        temp = ( m.r + m.g + m.b ) / 3.0;
        m.r =  m.g = m.b = temp;

        //----------------------- invert
        m.r = 1.0 - m.r;
        m.g = 1.0 - m.g;
        m.b = 1.0 - m.b;

        //----------------------- color dodge blend mode
        if( m.r >= .9995 )
            c.r = 1.0;
        else
            c.r = min( p0.r * 1.0 / ( 1.0 - m.r ), 1.0 );

        if( m.g >= 0.9995 )
            c.g = 1.0;
        else
            c.g = min( p0.g * 1.0 / ( 1.0 - m.g ), 1.0 );

        if( m.b >= 0.9995 )
            c.b = 1.0;
        else
            c.b = min( p0.b * 1.0 / ( 1.0 - m.b ), 1.0 );

        c.a = 1.0;

        result = c;
    }
}

2 Comments. Leave a comment too

David L.
March 26, 2009

Fun stuff. Thanks for sharing.


Hi Alan,

thanks for sharing… I haven’t been into this artistik stuff before, just doing some experiments with it. I’d be interesting how real world scenarious would benefit from this. Maybe also adding some augmented reality as well? :-)

thanks, JH


Trackbacks. Ping Adjazent now.

Popular

Subscribe

Meta