This package can help keep your Dart code up to date with the potential changes
in uniform slot indices that can happen when you edit a .frag file associated
with one or more of your FragmentProgram objects.
Eventually this package will be converted to a build_runner style package to enable automatic running, but for now this is just a prototype to help evaluate this concept of automatically generating prototype Dart classes to enable easy access to programs, their shader instances, and the uniforms on those shaders.
For now there is a manual step involved when you edit your .frag files,
which is to run the generate command below to update your Dart language shader
prototype files.
This package creates Dart classes to directly set the uniforms on your FragmentShader objects when you run a generator command that allow you to set the uniforms as fields, such as:
myShader.uColor.color = Colors.red;
myShader.uMix = 3.0;
myShader.uPos.xy = Offset(10, 15);
where uColor, uMix and uPos are the names used in the .frag file
for uniforms of types vec4, float, vec2 correspondingly.
To install this package in your Flutter project, add the following lines to the
dependencies section in your pubspec.yaml:
shader_prototypes:
git: https://github.com/flar/shader_prototypes.gitOnce you have your shaders created, invoke the prototype generator script from the package using:
dart pub global activate shader_prototypes
dart run shader_prototypes:generate_prototypesThat command will scan your pubspec.yaml file for the list of shaders you've
declared and create class prototypes for your shaders within your project
in the lib/gen/shader-prototypes subdirectory, or you can override this
location using the --output-dir option.
Once this script has done its work, you need to run it manually every time
you adjust the naming, ordering, or number of uniforms in your .frag
files. You can run it every time you make any change to these files, but the
only changes that affect the script's output are changes to the uniforms.
As an example, if your shader looks like this:
#include <flutter/runtime_effect.glsl>
uniform vec4 uColor;
uniform float uScale;
out vec4 fragColor;
void main() {
vec2 pos = FlutterFragCoord();
fragColor = vec4(
mod(uColor.r - pos.x * uScale, 1.0),
mod(uColor.g - pos.y * uScale, 1.0),
mod(uColor.b - (pos.x + pos.y) * uScale, 1.0),
uColor.a
);
}
the script will generate a class file that looks like this:
// GENERATED CODE - DO NOT MODIFY BY HAND
// THIS FILE IS GENERATED BY generate_prototypes.dart FROM shaders/my_shader.frag.
import 'dart:ui';
import 'package:shader_prototypes/shader_prototypes.dart';
class MyShader {
MyShader() : shader = _program!.fragmentShader();
final FragmentShader shader;
late final Vec4 uColor = UniformVec4(shader, 0);
double _uScale = 0.0;
set uScale(double value) {
_uScale = value;
shader.setFloat(4, value);
}
double get uScale => _uScale;
static FragmentProgram? _program;
static Future<void> init() async {
_program = await FragmentProgram.fromAsset('shaders/my_shader.frag');
}
}Which you can use in, for instance, a CustomPainter.paint method like this:
@override
void paint(Canvas canvas, Size size) {
final MyShader myShader = MyShader()
..uColor.color = color
..uScale = scale;
Paint p = Paint()
..shader = myShader.shader;
canvas.drawRect(Offset.zero & size, p);
}A utility to generate Dart language class definitions from fragment shader source files.
Usage: dart run shader_prototypes:generate_prototypes [arguments]
Global options:
--output-dir Directory to write the shader class source files.
-f, --[no-]force Rewrite shader prototype files without checking previous contents
-h, --[no-]help This project is currently in a proof of concept stage. It uses a recently added feature of
impellerc to parse the fragment program and output a JSON that contains descriptions of
the uniforms, which should be fairly robust. If it is run on a version of Flutter that does
not support that feature then it will back off to a simple text parser to read the fragment
program files directly and do a simple search for the uniforms. That technique will work on
all versions of Flutter that include support for custom fragment programs, but it is a
fairly simple parser that does not support the full syntax of the shader language.
A more fleshed out version of the gpu vecN and mat4 Dart objects in this package lives in
the shader_uniforms package (see https://github.com/flar/shader_uniforms). This package
will eventually just use that package for its implementation as it develops into a true
builder style package.