Различия в качестве между HTML, Canvas и WebGL - PullRequest
0 голосов
/ 08 февраля 2020

Я хочу нарисовать изображение в WebGL, но уменьшено. Когда я не масштабирую его, тогда изображение имеет хорошее качество, но если я уменьшаю его, то оно имеет низкое качество.

Я читал об 'Обработка дисплеев с высоким разрешением (Retina) в WebGL' отсюда : http://www.khronos.org/webgl/wiki/HandlingHighDPI и я попытался сделать то же самое. Мой код в WebGL:

        Initializations:

        var devicePixelRatio = window.devicePixelRatio || 1;

        gl.canvas.style.width = "800px";
        gl.canvas.style.height = "600px";

        canvas.width = Math.round(800 * devicePixelRatio);
        canvas.height = Math.round(600 * devicePixelRatio);


        For drawing:

        gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
        matrix = m3.scale(matrix, 28/800, 35/600); // matrix for scaling texture

        Textures:

        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);

Но он не был такого же качества, как изображение HTML. Мой код в HTML:

        setTimeout(function() {

            var imagine = new Image();
            imagine.src = 'Tank.png';
            imagine.width = '28';
            imagine.height = '35';
            document.body.appendChild(imagine);

        }, 1000);

Мой код на холсте:

        var imagine = new Image();
        imagine.src = 'Tank.png';
        imagine.width = '28';
        imagine.height = '35';
        imagine.onload = function() {
            context.drawImage(imagine, 0, 0, 28, 35);
        }
        context = canvas.getContext('2d');

Разница между качеством изображения ниже (качество: WebGL

WebGL Canvas HTML

Я знаю, что это не очень большая разница, но я действительно хочу показывать фотографии в хорошем качестве. В HTML картинка более плавная. Я заметил, что если я увеличу масштаб в браузере Chrome, то качество изображения из HTML возрастет, но изображение WebGL останется с тем же разрешением, что ухудшит качество. И если я обновлю sh страницу, чтобы обновить devicePixelRatio для WebGL, то картинка получится лучше, но мой браузер работает медленнее при 500% увеличении, я думаю, потому что он делает холст больше и должен больше рисовать. Но в HTML, если я перемещаю изображение с увеличением 500%, проблем не возникает, изображение движется хорошо и имеет хорошее качество.

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

И по сравнению с этой ситуацией - холст drawImage качество - я ставлю значения как целые числа во всех трех программах.

Последний вопрос:

Как я могу рисовать изображения в webGL, как в HTML, с тем же качеством (без учета этих линий на этих дорожках) и хорошим качеством, даже при увеличении браузера ? Какие еще возможности у меня есть, чтобы их нарисовать? Какую технологию мне использовать? Я хотел использовать WebGL, потому что у него есть некоторые функции, которых нет у HTML, и я хотел рисовать некоторые вещи с нуля, например, линии или точки.

РЕДАКТ. 1: Это изображение с нормальным разрешением.

Tank Picture

На этом снимке кажется, что линии дорожек не прямые, но они пересекаются. Если вы можете посмотреть ближе к изображениям из Canvas и WebGL, первые строки дорожек, сначала слева, а затем справа, будут прямыми. Более того, картинка с Canvas имеет более прямые следы, даже последние. Последнее изображение HTML имеет все дорожки одинаковой формы.

Извините, потому что я выложил очень маленькие картинки. Это потому, что мне нужен этот масштаб, и мне нужны, чтобы картинки не были больше. Если бы я рисовал картинки большего размера, то devicePixelRatio заставил бы картинки выглядеть намного лучше, но я не использую картинки в нормальных размерах. Таким образом, проблема могла быть решена с помощью devicePixelRatio. Для меньших размеров этот метод с devicePixelRatio мне не помогает. Вот почему я ищу другое решение.

Ответы [ 2 ]

2 голосов
/ 08 февраля 2020

Случайный масштаб, положение и поворот

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

Сделать убедитесь, что холст (2D или WebGL) выровнен по пикселям устройства, и есть совпадение один к одному с пикселями физического устройства.

Не используйте devicePixelRatio, если это любое другое значение, кроме 1 или 2 ( 2 для HDPI, или сетчатки), поскольку другие значения означают, что страница была увеличена, и вы не можете получить соответствие пикселов устройствам от одного до одного. Попытка масштабирования холста (2D или WebGL) приведет только к снижению качества.

Исходное изображение

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

Самая важная часть рендеринга изображений хорошего качества (2d или webGL) - это соотношение между исходным размером изображения и отображаемым результатом.

Если вы уменьшите изображение до 28 на 35 пикселей, то исходное изображение ДОЛЖНО быть 2 * (68, 92) 4 * (136, 184) и т. Д. c ... в 2 раза размер окончательного результата. ПРИМЕЧАНИЕ необходимо учитывать стоимость ОЗУ графического процессора для больших изображений.

Исходные детали изображения, выровненные по визуализированным пикселям

Важные детали изображения, которые должны оставаться максимально четкими, должны выровняйте по отрисованным краям пикселей, или вы получите размытые детали.

Изображение ниже - 16 * окончательный размер. Он имеет шахматную доску (каждый квадрат 16 на 16 пикселей) поверх него, чтобы показать размер визуализированных пикселей.

Обратите внимание, как края дорожек, корпуса, бочки, револьвера все выровнены с конечными уменьшенными пикселями.

enter image description here

Рендеринг

На следующем изображении показаны результаты визуализации с выравниванием по пикселям (верхние строки буксировки WebGL имеют одинаковый результат в 2D)

Слева направо - размер исходного исходного изображения, в 2–16 раз превышающий окончательный размер.

В каждой строке используется поиск по разным пикселям

  • Ближайший , Самый быстрый рендеринг пикселя, ближайшего к верхнему левому углу каждого пикселя, - финальный рендеринг
  • Линейный. По умолчанию для 2d (сглаживание = true), webGL (gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR)). Цвет пикселя - это линейная интерполяция 4 пикселей около (под, справа, снизу, снизу справа) конечного пикселя.

  • Среднее значение. Только пользовательский WebGL. Фрагментный шейдер использует общее количество фотонов всех пикселей под визуализированным пикселем для вычисления окончательного цвета пикселя RGB. Для оригинального 2-кратного размера размер графического процессора примерно такой же, как для линейного, для 16-кратного - только для высокопроизводительных устройств или для низкого числа рендеринга изображений (в 64 раза медленнее линейного на пиксель)

  • Журнал Среднее +. Использует тот же фрагментный шейдер, что и Log Mean, для визуализации, но предварительно обрабатывает (как раз вовремя) оригинал, используя модифицированный сверточный сверточный фильтр, чтобы повысить резкость до 2/3 * invScale (Log calcs), чтобы увеличить визуальный контраст на границах низкой контрастности. Стоимость - единовременная начальная стоимость.

enter image description here

Лично для проектов в реальном времени я использую второй столбец первого столбца 2 * линейный, и при рендеринге на HDPI или большом количестве рендеринга я использую простейшую 1 * линейную (не показана).

Большинство людей не могут различить разницу между 2-м, 3-м и последним рядами. Можете ли вы без увеличения масштаба изображения?

Поворот

На следующем изображении показан тот же метод от 2 до 16 раз слева направо, затем строки линейные, ближайшие и среднее значение в логах, + .

enter image description here

Примечания

  • Журнал Обработка изображений RGB имеет существенное улучшение только при использовании изображений с высокой насыщенностью и высокой цветовой контрастностью. Изображение резервуара имеет очень низкий цветовой контраст и, таким образом, не получает большой выгоды от Log Mean. Следующее изображение показывает слева направо ближайшее, линейное и логарифмическое значение версии с высокой контрастностью цвета.

enter image description here

  • Все изображения в этом ответе были созданы на ускоренном GPU Chrome 80 Win 10 x64. Исходное эталонное изображение резервуара от OP.

  • Я только что заметил, когда я заканчиваю sh, что все повернутые Nearest изображения имеют сглаживание на внешних краях. Это ошибка с моей стороны, так как я забыл придать изображению прозрачный отступ. Сглаживание происходит из-за края многоугольника и не является частью процесса поиска пикселей gl.TEXTURE_MIN_FILTER, gl.LINEAR. Чтобы много работы исправить, извините.

0 голосов
/ 08 февраля 2020

Если вы хотите, чтобы ваши картинки выглядели более плавно, вы можете использовать mipmaps! Постарайтесь сделать так, чтобы оба измерения имели мощность, равную 2, и после того, как вы сможете сгенерировать мип-карты, например:

gl.generateMipmap(gl.TEXTURE_2D);

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

gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);

Ниже приведены изображения с различиями (LINEAR vs LINEAR_MIPMAP_LINEAR):

LINEARLINEAR_MIPMAP_LINEAR

На первом изображении дорожки асимметричны c, но второе изображение нарисовано плавным. Я думаю, что второе изображение больше похоже на предоставленное вами изображение HTML.

Существует большое руководство по текстуре WebGL: https://webglfundamentals.org/webgl/lessons/webgl-3d-textures.html. Там написано, что этот тип фильтрации текстур самый медленный и занимает на 33% больше памяти, так что имейте это в виду!

...