Ускорить симплексный шум

Я хочу написать Java-программу, в которой движущееся небо создается из симплексного шума, но у меня проблемы с производительностью (слишком низкая частота кадров). Я использую https://github.com/KdotJPG/OpenSimplex2/blob/master/java/OpenSimplex2F.java класс шума.
Моя функция, которая генерирует небо, генерирует его полностью заново в каждом кадре:

private void generate() {
        float y = offset;
        for (int i = 0; i < frame.getHeight(); i++) {
            float x = offset;
            for (int j = 0; j < frame.getWidth(); j++) {
                double a = noise.noise2(x, y) + 0.25f * noise.noise2(2 * x, 2 * y) + 0.125f * noise.noise2(4 * x, 4 * y);
                a = a / (1 + 0.25 + 0.125);
                a = (a + 1) / 2;
                a *= 100;
                Color color = Color.getHSBColor(220f / 360f, a / 100f, 1f);
                background.setRGB(j, i, color.getRGB());
                x += noiseResolution;
            }
            y += noiseResolution;
        }
    }

Где background — это BufferedImage, на котором я рисую, а offset говорит, сколько шума перемещено. Я попытался сохранить массив пикселей из background каждого кадра и перевести его на количество пикселей, на которые он должен быть перемещен, а затем сгенерировал только новые пиксели. К сожалению, из-за того, что тогда он рендерился слишком быстро, количество пикселей, на которое его нужно было переместить, было, например. 0.2, поэтому я не мог переводить индексы массива на дробь.
Так что я думаю, что единственный способ - это каким-то образом сгенерировать его по-другому, но я совершенно не знаю, как это сделать.

Спасибо!


person Andrzej Sołtysik    schedule 12.03.2021    source источник
comment
Рассматривали ли вы возможность хранения нескольких массивов пикселей и смешивания между ними? Или это испортит эффект, которого вы добиваетесь?   -  person Ryan1729    schedule 13.03.2021
comment
Я не думал об этом, но это звучит как возможное решение. Я надеялся на что-то попроще, но если нет другого выхода, то попробую, спасибо!   -  person Andrzej Sołtysik    schedule 13.03.2021


Ответы (1)


Не уверен насчет Java, но в C++ с DirectX, OpenGL или любым подобным низкоуровневым интерфейсом это должно быть легко сделано на графическом процессоре либо в HLSL (DirectX), либо в GLSL (OpenGL). Я внедрил шум 5D Simplex и даже увеличил масштаб, чтобы он заполнил мой большой экран, и на моем 9-летнем компьютере с моей старой графической картой он все еще делает пару сотен кадров в секунду. Вот как это выглядит.

https://www.youtube.com/watch?v=oRO1IGcWIwg

Если вы можете запустить фрагментный шейдер из Java, я думаю, это будет правильный путь. Я думаю, что в Java есть какой-то интерфейс OpenGL, так что вы можете посмотреть на него.

person Community    schedule 13.03.2021
comment
Я думаю, что это решение. Я делал все это на базовых компонентах Java и забыл, что они используют только процессор по умолчанию. Попробую отрендерить на gpu. Спасибо!! - person Andrzej Sołtysik; 14.03.2021