Я пытаюсь сделать равномерное распределение по сетке: https://www.researchgate.net/figure/A-2D-uniform-grid-example-with-grid-cell-and-particle-ids_fig3_325579657
https://jsfiddle.net/mikoval/0147xwfq/12/ Работает на одном компьютере, но не на другом.Значения корзины будут напечатаны в консоли.
И все отлично работает на одном из моих компьютеров, но когда я тестирую на другом компьютере, я получаю ОЧЕНЬ другие результаты.Алгоритм, который я использую, работает следующим образом:
Создание двух целей рендеринга.Используйте один в качестве входа и один в качестве выхода.В начале каждого кадра очистите их оба.
Рендеринг всех частиц в буфер кадра на основе текстуры позиции.Вместо рендеринга цвета я отображаю индекс частицы.Я использую вывод этого процесса, чтобы перейти к следующему рендеру.Во время каждого рендеринга проверяется, была ли уже отрисована частица, и если это так, она игнорируется.Таким образом, у меня может быть до 4 разных частиц в одной ячейке сетки (каждая из них будет храниться в канале RGBA как один индекс).
Вот мои шейдеры:
this.bucketVertex = `#version 300 es
precision highp float;
in ivec2 position;
flat out ivec2 id;
out vec2 pv;
uniform vec2 res;
uniform sampler2D image;
uniform sampler2D current;
void main() {
gl_PointSize = 1.0;
id = position;
float aspect = res.y / res.x;
vec2 pos = texelFetch(image, position, 0).xy;
pos.x *= aspect;
float gSize = float(textureSize(image, 0).x);
float val = float(id.x + id.y * int(gSize) + 1);
vec2 b = floor(pos * gSize)/gSize + 0.5/gSize;
pv = (b + 1.0)/2.0;
vec4 c = texture(current, pv.xy);
for(int i = 0; i < 4; i++){
if(c[i] == val) {
b = vec2(1000.0, 1000.0);
}
}
gl_Position = vec4(b, 0, 1);
}
`;
this.bucketFragment = `#version 300 es
precision highp float;
flat in ivec2 id;
in vec2 pv;
out vec4 outColor;
uniform sampler2D current;
uniform sampler2D image;
void main() {
vec2 p = pv;
vec4 c = texture(current, p.xy);
int size = textureSize(image, 0).x;
int val = id.x + id.y * size + 1;
for(int i = 0; i < 4; i++){
if(c[i] == 0.0){
c[i] = float(val);
break;
}
}
outColor = c;
}
`;
и мой цикл рендеринга сегмента выглядит следующим образом:
/* clear previous run */
gl.bindFramebuffer(gl.FRAMEBUFFER, this.bucketTarget2.fb);
gl.clearColor(0.0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.disable(gl.BLEND);
gl.bindFramebuffer(gl.FRAMEBUFFER, this.bucketTarget.fb);
gl.viewport(0, 0, this.bucketTarget.fb.width, this.bucketTarget.fb.height);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.useProgram(this.bucketObj.program);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, state.texture);
gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, this.bucketTarget2.texture);
gl.uniform1i(this.bucketObj.uniformImage, 0);
gl.uniform1i(this.bucketObj.uniformImage2, 1);
gl.bindVertexArray(this.bucketVao);
gl.uniform2f(this.bucketObj.uniformRes, gl.canvas.width, gl.canvas.height);
for(var i = 0; i < 4; i++){
gl.drawArrays(gl.POINTS, 0, this.size * this.size);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, state.texture);
gl.uniform1i(this.bucketObj.uniformImage, 0);
gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, this.bucketTarget2.texture);
gl.uniform1i(this.bucketObj.uniformImage2, 1);
gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0, 0, this.bucketTarget2.fb.width, this.bucketTarget2.fb.height, 0);
}
Как уже упоминалось, это прекрасно работает на одном компьютере, где образец выходной текстуры может выглядеть следующим образом (да, это текстура с плавающей точкой):
[
5, 0, 0, 0,
3, 2, 0, 0,
4, 1, 6, 0,
7, 8, 0, 0
...
]
Однако на другом компьютере я получаю следующее:
[0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
1, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
1, 1, 1, 4,
1, 1, 1, 3,
0, 0, 0, 0,
1, 1, 1, 2,
0, 0, 0, 0,
0, 0, 0, 0]
По любой причине, каждый раз, когда появляется частица, которая не является 1, текстуразаполняется 1 с, а затем просто отображает одно значение в последнем канале.
Если я только сделаю (for i = 0; i < 2; i++)
, то текстура будет выглядеть как
[1, 4, 0, 0, 1, 0, 0, 0, 1, 3, 0, 0, ....]
Я понятия не имею, откуда эти 1 будут исходить из кода шейдера.Я могу попытаться сделать скрипку демонстрацией позже, если это будет полезно.
РЕДАКТИРОВАТЬ: Обновлено с комментарием gman.
ССЫЛКА НА ДЕМО: https://jsfiddle.net/mikoval/0147xwfq/12/