Как вы генерируете случайное число в HLSL?
Я спрашиваю, потому что я хочу попробовать трассировку лучей GPU . Вам нужно генерировать случайные направления в пиксельном шейдере. Так что я хочу randFloat()
, где результатом является случайное число от -1 до +1.
Кроме того, как обстоят дела с инструкцией по шуму hlsl ? Документы говорят, что он был удален из HLSL 2.0 и выше. Почему ?
Я читал о подходе, где вы заполняете текстуру случайными значениями, а затем в каждой вершине, у которой есть индекс в этой текстуре, есть координата текстуры. Но это по каждой вершине , мне нужна инструкция, которую я могу вызвать в пиксельном шейдере. Кроме того, этот подход требует «повторного заполнения» текстовых координат для каждой вершины, если вы хотите разные значения для каждого кадра, а для этого требуется, чтобы буфер вершин обновлял каждый кадр (что может быть дорого!)
С подробностями, как вы можете дешево генерировать случайные числа на GPU?
Ответы:
Псевдослучайные числа в пиксельном шейдере получить нелегко. Генератор псевдослучайных чисел в ЦП будет иметь некоторое состояние, из которого он одновременно читает и записывает при каждом вызове функции. Вы не можете сделать это в пиксельном шейдере.
Вот несколько вариантов:
Используйте вычислительный шейдер вместо пиксельного шейдера - они поддерживают доступ для чтения и записи в буфер, так что вы можете реализовать любой стандартный PRNG.
Выборка из одной или нескольких текстур, содержащих случайные данные, на основе такого параметра, как положение на экране. Вы также можете выполнить некоторые математические операции с позицией, прежде чем использовать ее для поиска текстуры, что должно позволить вам повторно использовать текстуру, если математические операции включают в себя шейдерную константу random-per-draw-call.
Найдите некоторую математическую функцию положения на экране, которая дает «достаточно случайные» результаты.
Быстрый поиск в Google нашел эту страницу с этими функциями:
источник
Вот как я генерирую псевдослучайные числа для эффектов частиц с помощью вычислительного шейдера. Не уверен, насколько случайным является этот код, но он достаточно хорош для моих целей.
Ключом к тому, чтобы дать каждому ядру графического процессора свою собственную случайную последовательность, является подача на вычислительный шейдер начального случайного начального числа из ЦП. Затем каждое ядро использует это начальное число для циклического запуска генератора чисел, используя свой идентификатор потока в качестве счетчика. Оттуда каждый поток должен иметь свое собственное уникальное начальное число для генерации уникальных значений.
источник