Плоский шрифт WebGL2 заставляет цвета мигать

Я пытаюсь сделать простую сцену WebGL2 с низкополигональной местностью. Все работает, как и ожидалось, когда я позволяю шейдеру интерполировать между тремя цветами вершин. Но как только я добавляю тип flat, все ломается и каждый треугольник начинает "мигать".

Вершинный шейдер

#version 300 es
precision mediump float;

in vec3 in_vertexPosition;
in vec3 in_color;

uniform mat4 u_projectionMatrix;
uniform mat4 u_viewMatrix;

flat out vec3 pass_fragColor;

void main() {
    gl_Position = u_projectionMatrix * u_viewMatrix * vec4(in_vertexPosition, 1.0);

    pass_fragColor = in_color;
}

Фрагментный шейдер

#version 300 es
precision mediump float;

flat in vec3 pass_fragColor;

out vec4 out_fragColor;

void main() {
     out_fragColor = vec4(pass_fragColor, 1.0);
}

Вершины, индексы и цвета:

 const vertices = [
      0, 0, 0, // bottom left
      1, 0, 0, // bottom right
      1, 1, 0, // top right
      0, 1, 0 // top left
 ];

 const colors = [
      0.3, 0.3, 0.8, // bottom left
      0.3, 0.3, 0.6, // bottom right
      0.3, 0.3, 0.4, // top right
      0.3, 0.3, 0.2 // top left
 ];

 const indices = [
      0, 1, 3, // bl, br, tl
      3, 1, 2 // tl, br, tr
 ];

Я пробовал разные способы, используя индексы и другие типы вершин, но ничего не работает. Использование VBO для лучшей структуры.

Я заметил, что когда все три вершины треугольника имеют одинаковый цвет, мигание, очевидно, прекращается. Я читал, что тип flat заставляет все три вершины в треугольнике использовать цвет провоцирующей вершины (по умолчанию последняя вершина в треугольнике). К сожалению, это заставляет треугольники «мигать», и я не понимаю, почему.

Используя мою видеокарту NVIDIA GTX 1060.

GIF, показывающий "мигание": https://gyazo.com/7d3ba42afe1ba1458cd2820729490e47


person Gustav G    schedule 05.08.2018    source источник


Ответы (1)


Может у тебя глюк драйвера? Или, может быть, что-то еще не так с вашим кодом? Выложить рабочий код? У меня не мерцает.

const vs = `
#version 300 es
precision mediump float;

in vec3 in_vertexPosition;
in vec3 in_color;

uniform mat4 u_projectionMatrix;
uniform mat4 u_viewMatrix;

flat out vec3 pass_fragColor;

void main() {
    gl_Position = u_projectionMatrix * u_viewMatrix * vec4(in_vertexPosition, 1.0);

    pass_fragColor = in_color;
}
`
const fs = `
#version 300 es
precision mediump float;

flat in vec3 pass_fragColor;

out vec4 out_fragColor;

void main() {
     out_fragColor = vec4(pass_fragColor, 1.0);
}
`;

const m4 = twgl.m4;
const gl = document.querySelector('canvas').getContext('webgl2');

const vertices = [
     0, 0, 0, // bottom left
     1, 0, 0, // bottom right
     1, 1, 0, // top right
     0, 1, 0 // top left
];

const colors = [
     0.3, 0.3, 0.8, // bottom left
     0.3, 0.3, 0.6, // bottom right
     0.3, 0.3, 0.4, // top right
     0.3, 0.3, 0.2 // top left
];

const indices = [
     0, 1, 3, // bl, br, tl
     3, 1, 2 // tl, br, tr
];
 
const bufferInfo = twgl.createBufferInfoFromArrays(gl, {
   in_vertexPosition: vertices,
   in_color: {
     numComponents: 3,
     data: colors,
   },
   indices,
});

const programInfo = twgl.createProgramInfo(gl, [vs, fs]);

function render(time) {
  time *= 0.001;
  twgl.resizeCanvasToDisplaySize(gl.canvas);
  gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
  
  gl.clearColor(0, 0, 0, 1);
  gl.clear(gl.COLOR_BUFFER_BIT);
  
  gl.useProgram(programInfo.program);
  twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);
  const fov = Math.PI * .25;
  const aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;
  twgl.setUniforms(programInfo, {
    u_projectionMatrix: m4.perspective(fov, aspect, 0.1, 50),
    u_viewMatrix: m4.inverse(m4.lookAt(
      [ // eye,
        Math.sin(time * 1.2) * 2, 
        Math.cos(time * 1.1) * 2, 
        Math.sin( time * 1.3) * -3
      ], 
      [0, 0, 0], // target,
      [Math.cos(time), Math.sin(time), 0], // up
    )),
  });
  gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
  requestAnimationFrame(render);
}
requestAnimationFrame(render);
body { margin: 0; }
canvas { width: 100vw; height: 100vh; display: block; }
<script src="https://twgljs.org/dist/4.x/twgl-full.min.js"></script>
<canvas></canvas>

person gman    schedule 06.08.2018
comment
Я испытываю тот же тип мерцания с примером, который вы опубликовали. Может проблема с моими драйверами, сейчас проверю! - person Gustav G; 06.08.2018
comment
Другие браузеры тоже попробовать? - person gman; 06.08.2018
comment
Я установил последние версии драйверов GeForce для своей 1060, но мерцание все еще происходит. Я также пытался использовать FireFox, но с тем же результатом. Какую видеокарту и браузер используете? - person Gustav G; 06.08.2018
comment
Поэтому я только что попробовал это на своем Razer Blade с двумя графическими процессорами, интегрированной графикой Intel 630 и NVidia 1060. Если я заставлю систему использовать NVidia, она мерцает. Если я использую встроенную графику, это не так. Я бы посоветовал вам сообщить об ошибке в NVidia и на github.com/KhronosGroup/WebGL/issues - person gman; 06.08.2018
comment
Да, без аппаратного ускорения мерцания нет. - person Gustav G; 06.08.2018