Using alpha channel with blending for HeatMap

I’m trying to develop Heat Map.

My data are many points.

I’m creating a texture and drawing to it all the points, each one with an alpha of 1 / objectsCount. So the end result with blending will be less transparent places are more heated.

Than, for customizing the colors, i’m drawing the texture on the screen and in the fragment shader i’m checking the value of the alpha and changing accordingly.

When i’m drawing 100 objects it is working good. when 1000, not at all. I saw that when the opacity i send as a uniform is less then 0.00219… it considered as 0. Might be because of precision. I’ve put highp wherever I though but i don’t manage to find the correct place.

If my algorithm is not correct, i would be glad to hear new one. Tried to figure out how They did it but it far more complicated.

Drawing to texture shader

Vertex Shader


...
uniform float pointSize;
 
void main() {
   gl_Position = gl_ModelViewProjectionMatrix* gl_Vertex;
   gl_PointSize = pointSize;
}

Fragment Shader

...
uniform highp float opacity;
uniform highp vec4 color;
uniform sampler2D sampler;
void main() {
   highp vec4 usedColor = color;
   gl_FragColor = usedColor * texture2D(sampler, gl_PointCoord );
   gl_FragColor.a *= opacity;
}

Drawing the result on the screen - Shader

My vertices of the result texture for drawing on the screen are in clip space this is why i’m not multiplying with the matrices

Vertex Shader

...
attribute vec2 texCoords;
varying vec2 tex;
void main()
{
   gl_Position = gl_Vertex;
   tex = texCoords;
}

Fragment Shader

...
uniform sampler2D sampler;
varying vec2 tex;
uniform float objCount;
void main()
{
   highp vec4 f = texture2D(sampler, tex);

   if (f.a > 0.)
   {
      f = vec4(1,0,0,1); // for the test we make it red
   }
   gl_FragColor = f;
}

After banging my head on the keyboard, finally found the solution for my problem.

When creating texture in GL we specify the data type we want to save for each value - r/g/b/a. We can send there FLOAT and we get more precised data for each value.

My problem was that this type was unsigned byte.

In addition, if we want to draw this texture we must specify a webgl extension OES_texture_float and maybe also OES_texture_float_linear if we use linear filter.


// Creating the texture with FLOAT values
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.FLOAT, null);

// Loading the extensions
gl.getExtension('OES_texture_float');
gl.getExtension('OES_texture_float_linear');