I have an application that displays the northern lights on a map. I receive a lot of points that need to be rendered (2000+ points).
Here’s what the final result should look like:

Since this puts a heavy load on the CPU, the map starts to lag.
That’s why I decided to offload the rendering task to the GPU and create a shader.
I’m not very familiar with shaders—here’s what I’ve managed to do so far.
#version 460 core
#include <flutter/runtime_effect.glsl>
uniform float uProbability;
uniform vec2 uSize;
out vec4 fragColor;
float radius = 10.0;
vec4 color1 = vec4(226.0/255.0, 255.0/255.0, 227.0/255.0, 0.2);
vec4 color2 = vec4(138.0/255.0, 245.0/255.0, 111.0/255.0, 0.3);
vec4 color3 = vec4(255.0/255.0, 255.0/255.0, 29.0/255.0, 0.7);
vec4 color4 = vec4(250.0/255.0, 137.0/255.0, 24.0/255.0, 0.8);
vec4 color5 = vec4(255.0/255.0, 67.0/255.0, 67.0/255.0, 0.8);
vec4 getColorForProb(float value) {
if (value < 0.1) return color1;
else if (value < 0.2) return color2;
else if (value < 0.4) return color3;
else if (value < 0.6) return color4;
else return color5;
}
void main() {
vec2 pixelPos = FlutterFragCoord().xy;
vec2 center = uSize * .5;
float distance = length(pixelPos - center);
float gradient = 1.0 - smoothstep(0.0, radius, distance);
vec4 color = getColorForProb(uProbability);
fragColor = vec4(color.rgb, color.a * gradient);
}
class _IntensityPainter extends CustomPainter {
const _IntensityPainter(this.marker, this.zoom, this.shader);
final FragmentShader shader;
final AuroraMarker marker;
final int zoom;
double get baseBlurRadius => 5.0 / zoom;
@override
void paint(Canvas canvas, Size size) {
final paint = Paint();
shader
..setFloat(0, marker.auroraProbability)
..setFloat(1, size.width)
..setFloat(2, size.height);
canvas.drawCircle(
Offset.zero,
size.width / 2,
paint..shader = shader,
);
}
@override
bool shouldRepaint(covariant _IntensityPainter oldDelegate) {
return oldDelegate.marker != marker;
}
Here’s how it looks now:
The problem is that when I try to set alpha < 1, the color starts to turn white. And I don’t have a blur radius.
Could you please suggest how to fix this?
