Skip to content

flar/shader_prototypes

Repository files navigation

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.

Features

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.

Getting started

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.git

Once 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_prototypes

That 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);
  }

Usage

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     

Additional information

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.

Other similar packages

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.

About

Tool to create Dart prototypes for shader uniforms for ease of use in Flutter programs

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages