Лучшее, что я могу понять, это то, что вы не хотите сортировать, а хотите сделать черно-белую гистограмму (все каналы r, g, b вместе).
Для этого вам нужно простоодин проход, который суммирует все каналы, а не 4 прохода, как это делается в настоящее время.
Вам необходимо внести изменения в следующие шейдеры и заменить некоторые вызовы рендеринга в javascript.
Изменить "hist-vs"to
attribute float pixelId;
uniform vec2 u_resolution;
uniform sampler2D u_texture;
void main() {
vec2 pixel = vec2(mod(pixelId, u_resolution.x), floor(pixelId / u_resolution.x));
vec2 uv = (pixel + 0.5) / u_resolution;
vec4 color = texture2D(u_texture, uv);
float colorSum = (color.r + color.g + color.b) / 3.0 ;
gl_Position = vec4((colorSum * 255.0 + 0.5) / 256.0 * 2.0 - 1.0, 0.5, 0, 1);
gl_PointSize = 1.0;
}
Измените" max-vs "на
precision mediump float;
uniform sampler2D u_texture;
void main() {
vec4 maxColor = vec4(0);
for (int i = 0; i < 256; i++) {
vec2 uv = vec2((float(i) + 0.5) / 256.0, 0.5);
maxColor = max(maxColor, vec4(texture2D(u_texture, uv).rgb, 1));
}
gl_FragColor = maxColor;
}
Измените" show-fs "на
precision mediump float;
uniform sampler2D u_histTexture;
uniform vec2 u_resolution;
uniform sampler2D u_maxTexture;
void main() {
vec3 maxColor = texture2D(u_maxTexture, vec2(0)).rgb;
vec2 uv = gl_FragCoord.xy / u_resolution;
vec3 hist = texture2D(u_histTexture, uv).rgb;
gl_FragColor = vec4(step(uv.yyy, hist / maxColor) * uv.x, 1);
}
Изменения в javascript
Тогда в Javascript вместо того, чтобы вызывать первый шейдер 4 раза, нужно вызывать его только один раз.Кроме того, поскольку униформа маски не требуется, вам не нужно передавать ее в шейдер.
Цикл for, который первоначально выглядел как
for (var channel = 0; channel < 4; ++channel) {
gl.colorMask(channel === 0, channel === 1, channel === 2, channel === 3);
twgl.setUniforms(histProgramInfo, {
u_texture: tex,
u_colorMult: [
channel === 0 ? 1 : 0,
channel === 1 ? 1 : 0,
channel === 2 ? 1 : 0,
channel === 3 ? 1 : 0,
],
u_resolution: [img.width, img.height],
});
twgl.drawBufferInfo(gl, gl.POINTS, pixelIdBufferInfo);
}
, заменит все эти строки на
* 1024.*