Почему пиксельный шейдер возвращает float4, когда задний буфер имеет формат DXGI B8G8R8A8 UNORM?



Хорошо, так что это меня уже некоторое время беспокоит, и я не могу найти ничего на MSDN, что входит в специфику, которая мне нужна.



Это скорее вопрос из 3 частей, так что вот он:



1-) при создании swapchain приложения указывают форматы пикселей backbuffer, и чаще всего это либо B8G8R8A8, либо R8G8B8A8. Это дает 8 бит на цветовой канал, в сумме 4 байт на пиксель....так почему пиксельный шейдер должен вернуть цвет как float4, когда float4 это на самом деле 16 байт?



2-) при привязке текстур к пиксельному шейдеру мои текстуры имеют формат DXGI_FORMAT_B8G8R8A8_UNORM, но почему для работы сэмплера требуется float4 на пиксель?



3-) я что-то упустил? я что, слишком много об этом думаю?



Пожалуйста, предоставьте ссылки, чтобы подтвердить вашу претензию. Желательно из MSDN!!!!

681   1  

1 ответ:

Графические процессоры предназначены для выполнения вычислений на 32-битных данных с плавающей запятой, по крайней мере, если они хотят поддерживать D3D11. Начиная с D3D10, вы также можете выполнять 32-битные операции со знаком и без знака. В HLSL нет требований или языковой поддержки для типов меньше 4 байт, поэтому нет "byte/char "или" short " для целых чисел 1 и 2 байта или более низкой точности с плавающей запятой.

Любые форматы DXGI, использующие суффикс" FLOAT"," UNORM "или" SNORM", являются нецелочисленными форматами, в то время как "UINT" и "SINT" - это целое число без знака и со знаком. Любые операции чтения, выполняемые шейдером на первых трех типах, будут предоставляться шейдеру как 32-битные с плавающей запятой, независимо от того, был ли исходный формат 8-битным UNORM/SNORM или 10/11/16/32-битным с плавающей запятой. Данные в вершинах обычно хранятся с меньшей точностью, чем полные 32-битные с плавающей запятой, чтобы сэкономить память, но к тому времени, когда они достигают шейдера, они уже преобразованы в 32-битную плавающую точку.

На выходе (для БПЛА или рендеринга целей) графический процессор сжимает данные " float "или" uint " в любом формате, в котором был создан целевой объект. Если вы попытаетесь вывести float4(4.4, 5.5, 6.6, 10.1) в целевой объект, который является 8-битным нормализованным, то он будет просто усечен до (1.0, 1.0, 1.0, 1.0) и будет потреблять только 4 байта на пиксель.

Итак, чтобы ответить на ваши вопросы:

1) потому что шейдеры работают только на 32-битных типах, но GPU будет сжимать / усекать ваши выходные данные по мере необходимости для хранения в ресурсе, который вы в данный момент привязали в соответствии с его типом. Это было бы так безумие иметь специальные ключевые слова и типы для каждого формата, поддерживаемого графическим процессором.

2)" сэмплер "не"нуждается в float4 на пиксель для работы". Мне кажется, вы путаете терминологию. Объявление, что текстура является Texture2D<float4>, на самом деле просто констатирует, что эта текстура имеет четыре компонента и имеет формат, который не является целочисленным форматом. "float" не обязательно означает, что исходные данные являются 32-битными float (или фактически даже с плавающей точкой), но просто что данные имеют дробный размер. компонент к нему (например 0.54, 1.32). Равным образом, объявление текстуры как Texture2D<uint4> не означает, что исходные данные являются 32-битными беззнаковыми обязательно, но более того, что она содержит четыре компонента беззнаковых целочисленных данных. Однако данные будут возвращены вам и преобразованы в 32-битный float или 32-битное целое число для использования внутри шейдера.

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

Comments

    Ничего не найдено.