Что я хочу:
Для тестирования стиля игрового искусства, о котором я думал, я хочу отобразить 3D-мир в пиксельной форме. Так, например, возьмите сцену, подобную этой (но визуализированную с определенным цветом/стилем, чтобы хорошо выглядеть после пикселизации):
И заставьте это выглядеть примерно так:
Играя разными способами стилизации 3D-источника, я думаю, что пикселированный вывод может выглядеть красиво. Конечно, чтобы получить этот эффект, он просто уменьшает изображение до ~ 80p и увеличивает его до 1080p с повторной выборкой ближайшего соседа. Но более эффективно выводить прямо на холст 80p, чтобы начать с него, и просто сделать масштабирование.
Обычно это не так, как использовать шейдер, чтобы изменить размер растрового изображения в формате ближайшего соседа, но производительность на нем лучше, чем любой другой способ, который я нашел для такого преобразования в реальном времени.
Мой код:
Мой буфер для растрового изображения хранится в строке major, как r1, g1, b1, a1, r2, g2, b2, a2...
и я использую gpu.js, который по существу преобразует эту функцию JS в шейдер. Моя цель - взять одно растровое изображение и вернуть его в более крупном масштабе с масштабированием ближайшего соседа, поэтому каждый пиксель становится квадратом 2x2 или 3x3 и так далее. Предположим, что inputBuffer
представляет собой масштабированную долю размера выхода, определяемую методом setOutput
.
var pixelateMatrix = gpu.createKernel(function(inputBuffer, width, height, scale) {
var y = Math.floor((this.thread.x / (width[0] * 4)) / scale[0]);
var x = Math.floor((this.thread.x % (width[0] * 4)) / scale[0]);
var remainder = this.thread.x % 4;
return inputBuffer[(x * y) + remainder];
}).setOutput([width * height * 4]);
Имейте в виду, что он перебирает новый буфер вывода полного размера, поэтому мне нужно найти правильные координаты, которые будут существовать в более
sourceBuffer
основываясь на текущем индексе вoutputBuffer
(индекс раскрывается lib какthis.thread.x
).
Что происходит вместо этого:
Это, вместо того, чтобы сделать ближайший соседский высококлассный, делает приятную маленькую радугу (выше - маленький нормальный рендер, ниже - результат шейдера), а справа вы можете увидеть отладочный журнал с статистикой о входных и выходных буферах ):
Что я делаю не так?
Примечание. Я задал связанный с этим вопрос: существует ли более простой (и все еще совершенный) способ масштабирования рендеринга холста с повторной выборкой ближайшего соседа?