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.
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 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/src/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:
// THIS FILE IS GENERATED BY generate_prototypes.dart FROM shaders/my_shader.frag.
// DO NOT EDIT OR CHECK THIS INTO SOURCE CONTROL
import 'dart:ui';
import 'package:shader_prototypes/shader_prototypes.dart';
class MyShader {
MyShader() {
shader = _program!.fragmentShader();
_uColor = UniformVec4(shader, 0);
}
late final FragmentShader shader;
UniformVec4 get uColor => _uColor;
set uScale(double value) => shader.setFloat(4, value);
late final UniformVec4 _uColor;
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.
(defaults to "lib/src/gen/shader_prototypes")
-h, --[no-]helpThis project is currently in a proof of concept stage and uses very simple text parsing
of the shaders to determine the offsets of the shader uniforms. Eventually it should use
the impellerc program to produce the uniform offsets in a more reliable way that would
also involve syntax checking the shader and be more resilient to syntax and line endings.