Как реализовать нормализацию текстур в «автоматических уровнях» в вычислительных шейдерах HLSL - PullRequest
0 голосов
/ 19 марта 2020

Я только что обнаружил невероятную скорость вычислительных шейдеров и использую ее для генерации шума для процедурной системы текстур в DirectX12. Это работает фантастически, но потом стало очевидно, что для расширения этой системы мне понадобится возможность нормализовать значения высоты.

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

Способ, которым я понимаю это (и все еще неясный), единственный способ синхронизировать c потоков с XXXMemoryBarrierWithGroupSyn c и группами общих переменных. Тем не менее, они имеют дело только с указанной группой c, а не с внешними потоками.

Так что я быстро обнаружил, что мне нужно разделиться на два отдельных вычислительных шейдера, однако параллельная система все еще не позволяет мне делать то, что нужно. Я думал, что это было довольно просто.

1) Я не могу синхронизировать c все потоки, чтобы можно было гарантировать, что минимальные / максимальные значения всей текстуры были определены в одном вычислительном шейдере, чтобы затем нормализовать пиксели.

2) Я пытался получить 2-элементный структурированный буфер, чтобы получить информацию, но я получаю условия гонки ошибок компиляции, если я пытаюсь выполнить min / max для массива структурированного буфера, поэтому не могу выполнить вычисление 'find min / max' шейдер работает через все перекрестные группы изображений и обновляет любой вид вывода, который я могу передать в другой шейдер, чтобы применить эти минимальные / максимальные значения к текстуре.

3) если я использую переменную groupshared, то, как я понимаю, эти являются локальными только для этой группы и, таким образом, не смогут определить надлежащие минимальные / максимальные значения для всего изображения, и, поскольку они предназначены для использования на 4096 квадратных изображениях, они слишком медленные при использовании одной группы.

Я посмотрел на бесчисленные примеры CS из DX miniengine и везде, где я их нахожу, которые работают со средней яркостью и прочим, но во всех случаях Если они отправляют эти данные в виде текстур или являются контентом, работающим исключительно с пикселями в группе, и им не требуется дополнительная информация, то есть я не могу найти какую-либо параллель, чтобы просто получить минимальное / максимальное значение пикселя с плавающей запятой для всего изображения без необходимости чтобы экспортировать текстуру размера groupCountX * groupCountY, необходимо скопировать данные в ЦП для их минимального / максимального значения, что, похоже, мешает и лишает смысла всю эту работу в вычислительном шейдере. : (

Если кто-нибудь может дать мне какие-либо предложения, это было бы очень признательно, я нахожу систему настолько ограничительной и так мало информации. Я отказываюсь признать, что это невозможно, но я могу ' не найти ни малейшего понятия, как объединить эту информацию, без необходимости тратить тонны посторонних вещей между GPU и CPU.

Заранее спасибо!

...