Using Shaders with Flutter

Published on Thu Sep 28 2023Denny George - FACTS

As participants in the Factshala Innovation Lab, we are building an in-classroom game about media manipulation. This came with a unique set of requirements :

  1. Develop a cross platform app for smartphones.
  2. Support low level access to network sockets to function even in low network or bad connectivity regions.
  3. Support for image processing

We chose Flutter as the framework to implement this. One of the reasons for choosing Flutter was that flutter's APIs for working with shaders seemed very intuitive. Using the 1CustomPainter class you can use dart to control drawing operations on a canvas. And to this same class you can pass a fragment shader to control the painting.

We went from 0 to loading shaders, working with textures and implementing interactivity. This guide will serve as a retracing of steps to share what we learnt.

Get barebones code :

1git clone https://github.com/dennyabrain/flutter_shader_demo.git
2git checkout basic-setup

Try Running this project. It should launch an app : screenshot 1

Interacting with shaders

Loading Shaders

1var program = await FragmentProgram.fromAsset('shaders/shader_tex.frag');
2shader = program.fragmentShader();

Passing Variables from flutter to shaders (uniform)

1class ShaderPainter extends CustomPainter {
2  final FragmentShader shader;
3
4  ShaderPainter(FragmentShader fragmentShader) : shader = fragmentShader;
5
6  
7  void paint(Canvas canvas, Size size) {
8    shader.setFloat(0, size.width);
9    shader.setFloat(1, size.height);
10
11    final paint = Paint();
12
13    paint.shader = shader;
14    canvas.drawRect(Offset.zero & size, paint);
15  }
16
17  
18  bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
19}

Footguns :

  1. Be mindful of unused variables within a shader. You might be setting uniform variables in the CustomPainter but if those variables are not being used in the shader, you will get out of index errors that left me clueless for a long time.

Future Planned Lessons :

  1. Loading 1 texture
  2. Loading 2 textures
  3. Interactivity

Various milestones are pushed as tags here. You can always check out a particular tag to try out working stable code.

References

Contact

This is a work-in-progress post. Contact denny for feedback and clarifications.

Text and illustrations on the website is licensed under Creative Commons 4.0 License. The code is licensed under GPL. For data, please look at respective licenses.