flixel-addons icon indicating copy to clipboard operation
flixel-addons copied to clipboard

Added FlxRuntimeShader

Open EliteMasterEric opened this issue 1 year ago • 5 comments

FlxRuntimeShader is a class which allows for compiling, running, and utilizing GLSL shaders at runtime, rather than at compile time.

The constructor of FlxRuntimeShader takes three arguments:

  • fragmentSource is the text of the GLSL fragment shader as you would use. This is the same as what you would specify under @:glFragmentSource.
  • vertexSource is the text of the GLSL vertex shader as you would use. This is the same as what you would specify under @:glVertexSource.
  • glslVersion is the GLSL version to use for the shader. Currently defaults to 120, the minimum version needed to support uniforms.

Once constructed, you can assign the FlxRuntimeShader directly to the target sprite, like so:

var sprite:FlxSprite = new FlxSprite(0, 0);
var shader:FlxRuntimeShader = new FlxRuntimeShader(fragText);

sprite.shader = shader;

// The shader will now be called when rendering the sprite.

This class also supports retrieval and assignment of uniforms. To do this, use the provided functions:

  • getFloat(name:String):Null<Float> returns the value of a float uniform if available, null otherwise.
  • setFloat(name:String, value:Float) sets the value of a float uniform.
  • getFloatArray(name:String):Null<Float[]> returns the value of a float[] uniform if available, null otherwise.
  • setFloatArray(name:String, value:Float[]) sets the value of a float[] uniform.
  • getInt(name:String):Null<Int> returns the value of an int uniform if available, null otherwise.
  • setInt(name:String, value:Int) sets the value of an int uniform.
  • getIntArray(name:String):Null<Int[]> returns the value of an int[] uniform if available, null otherwise.
  • setIntArray(name:String, value:Int[]) sets the value of an int[] uniform.
  • getBool(name:String):Null<Bool> returns the value of a bool uniform if available, null otherwise.
  • setBool(name:String, value:Bool) sets the value of a bool uniform.
  • getBoolArray(name:String):Null<Bool[]> returns the value of a bool[] uniform if available, null otherwise.
  • setBoolArray(name:String, value:Bool[]) sets the value of a bool[] uniform.

Vectors are treated as arrays of the corresponding length for the corresponding type. For example, to assign a vec3 uniform, call setFloatArray and provide an array of three elements. Matrices are treated as arrays; to assign a mat4 uniform, call setFloatArray and provide an array of 16 elements.

EliteMasterEric avatar Jul 18 '22 05:07 EliteMasterEric

I've been meaning to do something like this. I've wanted to make a shadertoy-esque shader editor that allows people to create and share custom flixel shaders. I think this is fantastic!

Geokureli avatar Jul 18 '22 16:07 Geokureli

I didn't want to override __processGLData or __initGL, but I had to in order to add a check before Reflect.setField (to prevent a crash when attempting to set a custom uniform) and to add the #version directive (to prevent a shader compilation issue on some platforms) respectively.

EliteMasterEric avatar Jul 18 '22 18:07 EliteMasterEric

I see flash is failing.

Also: is this something that will need to change periodically, perhaps due to changes to lime/openfl shaders? I see a lot of shared/similar code in FlxGraphicsShader, should we use shared code to keep these 2 classes in line with any new changes? I'm expecting, otherwise, that we will need to make the same changes in 2 places every time.

Lastly, is there a unit test we could add that would let us know when thing DO need to be updated?

Geokureli avatar Jul 18 '22 19:07 Geokureli

The way FlxRuntimeShader is currently written has it share code with FlxGraphicsShader because I didn't want my class to depend on changes to FlxGraphicsShader. However, I think I should look into implementing the fixes I made such that the overrides can be removed (which will require additional PRs).

I will have to investigate the cause of Flash build failure further as well. I had not tested on that platform. I have also not gotten the unit test suite running yet so that's a further task.

EliteMasterEric avatar Jul 18 '22 19:07 EliteMasterEric

I just pushed some new changes, which add getBitmapData and setBitmapData functions for setting sampler2D uniforms. This is useful for shaders which depend on multiple textures, such as shaders which apply certain blend modes.

I have also integrated the shader fixes which FlxRuntimeShader was applying into openfl.display.Shader directly. These changes eliminate any concerns with maintainability, but make this pull request dependent on the approval of openfl/openfl#2577.

The issues on the Flash platform have not yet been investigated nor diagnosed.

EliteMasterEric avatar Jul 29 '22 23:07 EliteMasterEric

Quick check-in on this PR, this code is tested and working, but builds will fail because it depends on openfl/openfl#2577, so this PR is pending the implementation of those changes.

EliteMasterEric avatar Dec 30 '22 22:12 EliteMasterEric