[Stencyl 3.5] Image / Actor shaders

mdotedot

  • Posts: 1596
Taking a little break from the 3D Library. I wanted to do some image effects.
Stencyl does have a few image manipulation blocks: Brightness, Saturation, Sepia, Grayscale among others. As well as some Blur/Bloom effects.
And you can use fade tweening.

But I needed a Sharpen filter which I couldn't find.

So, I created another Engine-Extension: (For Stencyl 3.5 only!)

Tested:
  • HTML5
  • Android (in BlueStacks and native)
  • Flash does not support GLSL Shaders!
  • Mac OSX Native
  • iOS (Simulator)
  • Windows






Work In Progress!
Stencyl 3.5 Extension

Running Example:
HTML5 Demo

The .Stencyl file:
  Stencyl 3.5 file

« Last Edit: October 08, 2018, 12:32:07 am by mdotedot »
Hanging out in the Chat:  http://www.stencyl.com/chat/

Proud member of the League of Idiotic Stencylers! Doing things in Stencyl that probably shouldn't be done.

mdotedot

  • Posts: 1596
Development Log:

After some investigations on BitmapData manipulations I stumble upon Shaders. In Stencyl you can have fullscreen shaders, but I saw a comment on the Discord channel made by Justin that in 3.5 you can use image shaders.

Most of the code examples use a construction where you extend a shader class and add some Fragment Source Code.

Like this: (example from Justin)

Code: [Select]
class MyShader extends openfl.display.Shader {
   
    @:glFragmentSource(
       
        "varying float vAlpha;
        varying vec2 vTexCoord;
        uniform sampler2D uImage0;
       
        void main(void) {
           
            gl_FragColor  = texture2D (uImage0, vTexCoord);
           
        }"
       
    )
   
   
    public function new () {
       
        super ();
       
    }

}


This worked just fine! But creating a class for each effect didn't seem flexible to m.e.

So I investigated other ways to use dynamic code in the shader.


Some openfl examples indicated that you could set the variable like so:

Code: [Select]
var shader = new Shader ();
shader.glFragmentSource = "  ... GLSL Code ";

// And then:

// bitmap.filters = [ new ShaderFilter (shader) ];
// or
// bitmap.shader = shader;
Custom Shader reference

But that failed in Stencyl.

It took me a while and diving into the sources from openfl and Stencyl I did find a way where you need to create a shader and set both the Vertex and Fragment code:

Code: [Select]
shader.glFragmentSource=code;
shader.glVertexSource=_vert;


But that didn't made it effective as I needed to tell the engine that it was ' dirty '.

Apparently you need to set or get the shader.data to make it initialize again.

So this part of the code made it all happen:

Code: [Select]
var _vert="attribute vec4 openfl_Position; attribute vec2 openfl_TextureCoord; varying vec2 openfl_TextureCoordv; uniform mat4 openfl_Matrix; uniform vec2 openfl_TextureSize;void main(void){openfl_TextureCoordv = openfl_TextureCoord; gl_Position = openfl_Matrix * openfl_Position;}";

var bitmap=new Bitmap(image); // Make a Bitmap from the BitmapData

var shader=new Shader();

shader.glFragmentSource=code; // variable passed from extension
shader.glVertexSource=_vert;

var data=shader.data; // This makes the glfragmentSource and glVertexSource active

Next thing was to set the uniform variables using an engine-extension block.

My 3D Library knowledge came to the rescue and I use HaXe Reflection to set the data variables.
      

Currently I am porting some shader code found on the internet from this source:      
Some examples are ported from this resource: Wagner Fragment Shaders


And .. now is my vacation over and I have to work again tomorrow ...


Hanging out in the Chat:  http://www.stencyl.com/chat/

Proud member of the League of Idiotic Stencylers! Doing things in Stencyl that probably shouldn't be done.


mdotedot

  • Posts: 1596

Updated fist post with new .stencyl and Extension.

Now we can do timer / mouse effects:


Hanging out in the Chat:  http://www.stencyl.com/chat/

Proud member of the League of Idiotic Stencylers! Doing things in Stencyl that probably shouldn't be done.

HopFrog

  • *
  • Posts: 44
Wow this is seriously cool. Thanks!


mdotedot

  • Posts: 1596
There is an issue with preprocessor statements in the GLSL code.

If you come across this, here are some hints to rewrite the code:

Suppose this is the code you find online:
Code: [Select]

varying vec2 vTexCoord;
uniform sampler2D uImage0;
uniform float uTime;

void main() {
   
    vec2 texCoord = vTexCoord;
    vec2 iResolution = vec2(320.0, 240.0);
   
    float main_a=1.0;
float main_b=2.0;
float main_c=3.0;
   

#define   afunc( R, G, B) {
const vec3 tst = vec3(R, G, B);
main_a = R*G*B;
main_b = R/G/B;
main_c = (R*G)*B;
}
afunc(23./255.,171./255., 116./255.);
afunc(44./255.,230./255., 126./255.);
afunc(213./255.,140./255., 216./255.);
afunc(35./255.,46./255., 161./255.);
afunc(26./255.,41./255., 165./255.);

#undef afunc

    gl_FragColor = vec4(vec3(main_a,main_b,main_c), 1.0);

}


It will generate errors  like these :       invalid character: #define

*  remove all the comments
* varying vec2 vTextCoord   changing to :   varying vec2 openfl_TextureCoordv;
* uniform sampler2D uImage0; becomes    :   uniform sampler2D openfl_Texture;
*  vec2 texCoord = vTexCoord;   becomes   :   vec2 texCoord = openfl_TextureCoordv;

Do not inline the function in the main method.

So use public variables for the members that are changed inside the function.
   
   
Ported code:

Code: [Select]
varying vec2 openfl_TextureCoordv;
uniform sampler2D openfl_Texture;

float main_a = 0.1;
float main_b = 0.1;
float main_c = 0.1;


void afunc(float R, float G, float B){
vec3 tst = vec3(R, G, B);

main_a = R*G*B;
main_b = R/G/B;
main_c = (R*G)*B;

}

void main() {
   
    vec2 texCoord = openfl_TextureCoordv;
    vec2 iResolution = vec2(320.0, 240.0);
   
afunc(23./255.,171./255., 116./255.);
afunc(44./255.,230./255., 126./255.);
afunc(213./255.,140./255., 216./255.);
afunc(35./255.,46./255., 161./255.);
afunc(26./255.,41./255., 165./255.);

        gl_FragColor = vec4(vec3(main_a,main_b,main_c), 1.0);

}



(Example gives bright green image: just for demonstration purposes)


Hanging out in the Chat:  http://www.stencyl.com/chat/

Proud member of the League of Idiotic Stencylers! Doing things in Stencyl that probably shouldn't be done.