использование pointSize для запуска фрагмента шейдера для рисования пикселей - PullRequest
0 голосов
/ 31 января 2019

Я запрашиваю диапазон pointSize gl.getParameter (gl.ALIASED_POINT_SIZE_RANGE) и получаю [1,1024] это означает, что использование этой точки для покрытия текстуры (поэтому он запускает фрагментный шейдер, чтобы нарисовать все пиксельные интервалы с помощью pointSize

в лучшем случае, используя этот метод, я не могу рендерить изображения размером больше 1024x1024,?

Я думаю, мне нужно привязать 2 треугольника (6 точек) к фрагментному шейдеру, чтобы он покрыл все пространство клипаи затем gl.viewport (x, y, width, height); отобразит ли всю эту область на выходную текстуру (объект буфера кадра или холст)?

есть ли другой способ (может быть, что-то новое в webgl2)а затем использовать атрибут в фрагментном шейдере?

1 Ответ

0 голосов
/ 31 января 2019

Правильно, наибольшая область размера, которую вы можете визуализировать с одной точкой, это то, что возвращается gl.getParameter(gl.ALIASED_POINT_SIZE_RANGE)

Спецификация не требует какого-либо размера больше 1. Тот факт, что ваш графический процессор / драйвер / браузервозвращаемое значение 1024 не означает, что компьютеры ваших пользователей также будут возвращать 1024.

примечание: ответы на основе вашей истории вопросов

Обычная вещь, которую нужно сделать в WebGL для 99% от всех случаев, этопредставить вершины.Хотите нарисовать четырехугольник, отправьте 4 вершины и 6 индексов или 6 вершин.Хотите нарисовать треугольник, отправьте 3 вершины.Хочешь нарисовать круг, представь вершины для круга.Хотите нарисовать автомобиль, представить вершины для автомобиля или, более вероятно, представить вершины для колеса, нарисовать 4 колеса с этими вершинами, представить вершины для других частей автомобиля, нарисовать каждую часть автомобиля.

Вы умножаете эти вершины на некоторые матрицы , чтобы перемещать, масштабировать, вращать и проецировать их в 2D или 3D пространство.Все ваши любимые игры делают это.Canvas 2D API делает это через OpenGL ES внутри.Сам Chrome делает это для отображения всех частей этой веб-страницы.Это норма.Все остальное является исключением и, вероятно, приведет к ограничениям.

Для развлечения в WebGL2 есть и другие вещи, которые вы можете сделать.Это не обычная вещь, и они не рекомендуются для решения реальных проблем.Они могут быть забавными, хотя бы для решения проблемы.

В WebGL2 в вершинном шейдере есть глобальная переменная с именем gl_VertexID, которая является счетчиком обрабатываемой вершины.Вы можете использовать это с умной математикой для генерации вершин в вершинном шейдере без других данных.

Вот некоторый код, который рисует четырехугольник, покрывающий холст

function main() {
  const gl = document.querySelector('canvas').getContext('webgl2');
  
  const vs = `#version 300 es
  void main() {
    int x = gl_VertexID % 2;
    int y = (gl_VertexID / 2 + gl_VertexID / 3) % 2;    
    gl_Position = vec4(ivec2(x, y) * 2 - 1, 0, 1);
  }
  `;
  
  const fs = `#version 300 es
  precision mediump float;
  out vec4 outColor;
  void main() {
    outColor = vec4(1, 0, 0, 1);
  }
  `;
  
  // compile shaders, link program
  const prg = twgl.createProgram(gl, [vs, fs]);
  
  gl.useProgram(prg);
  const count = 6;
  gl.drawArrays(gl.TRIANGLES, 0, count);
}
main();
<canvas></canvas>
<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>

Пример: И тот, который рисует круг

function main() {
  const gl = document.querySelector('canvas').getContext('webgl2');
  
  const vs = `#version 300 es
  #define PI radians(180.0)
  void main() {
    const int TRIANGLES_AROUND_CIRCLE = 100;
    int triangleId = gl_VertexID / 3;
    int pointId = gl_VertexID % 3;
    int pointIdOffset = pointId % 2;
    
    float angle = float((triangleId + pointIdOffset) * 2) * PI /
                  float(TRIANGLES_AROUND_CIRCLE);
    float radius = 1. - step(1.5, float(pointId));
    float x = sin(angle) * radius;
    float y = cos(angle) * radius;
    
    gl_Position = vec4(x, y, 0, 1);
  }
  `;
  
  const fs = `#version 300 es
  precision mediump float;
  out vec4 outColor;
  void main() {
    outColor = vec4(1, 0, 0, 1);
  }
  `;
  
  // compile shaders, link program
  const prg = twgl.createProgram(gl, [vs, fs]);
  
  gl.useProgram(prg);
  const count = 300;  // 100 triangles, 3 points each
  gl.drawArrays(gl.TRIANGLES, 0, 300);
}
main();
<canvas></canvas>
<script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>

Существует целый сайт, основанный на этой идее .Сайт основан на загадке создания красивых картинок с указанием только идентификатора для каждой вершины.Это вершинный шейдерный эквивалент shadertoy.com .На Shadertoy.com головоломка в основном дается только gl_FragCoord в качестве входных данных для фрагментного шейдера и пишите функцию для рисования чего-то интересного.

Оба сайта - игрушки / головоломки.Делать такие вещи не рекомендуется для решения реальных задач, таких как рисование трехмерного мира в игре, обработка изображений, рендеринг содержимого окна браузера и т. Д. Они представляют собой милые головоломки с минимальными входными данными и рисуют что-то интересное.

Почему этот метод не рекомендуется?Наиболее очевидная причина в том, что она жестко запрограммирована и негибка, а стандартные методы очень гибкие.Например, выше для рисования полноэкранного четырехугольника требуется один шейдер.Для рисования круга требуется другой шейдер.Где стандартные атрибуты на основе буфера вершин, умноженные на матрицы, могут использоваться для любой предоставленной формы, 2d или 3d.Не только любую фигуру, с помощью простого простого умножения матрицы в шейдере, эти фигуры могут быть переведены, повернуты, масштабированы, спроецированы в 3D, там можно независимо устанавливать центры вращения и центры масштабирования и т. Д.

Примечание:Вы можете делать все, что хотите.Если вам нравятся эти техники, то обязательно используйте их.Причина, по которой я пытаюсь отвлечь вас от них, основана на ваших предыдущих вопросах, вы новичок в WebGL, и я чувствую, что в конечном итоге вы сами сделаете WebGL намного сложнее, если вместо этого будете использовать неясные и жестко закодированные методы, подобные этимиз традиционных более распространенных гибких методов, которые опытные разработчики используют для выполнения реальной работы.Но опять же, это зависит от вас, делайте что хотите.

...