Вычислительные шейдеры: зачем возвращать float4? - PullRequest
0 голосов
/ 05 мая 2020

Отредактированный вопрос:

У меня есть ID3D11Texture2D и ID3D11UnorderedAccessView с форматом DXGI_FORMAT_R8G8B8A8_UNORM и шейдером

RWTexture2d<float4> tex: register(u0);

[numthreads(32, 32, 1)]
void main(uint3 dtid : sv_dispatchthreadid)
{
    float r;
    ...
    tex[dtid.xy] = float4(r, 0.0f, 0.0f, 0.0f);
}

Я предполагаю, что мы должны писать 8-битные unorm float.

Будет ли это означать преобразование типов из 32-битных чисел с плавающей запятой в 8-битные unorms?

Исходный вопрос:

Я изначально пробовал шейдер

RWTexture2D<uint> tex: register(u0);

[numthreads(32, 32, 1)]
void main(uint3 DTid : SV_DispatchThreadID)
{
    tex[DTid.xy] = 0xFF0000FF;// I actually tried and got white with 0xFF << 24 + 0xFF but I realized they are not the same.
}

, но когда я понял, что получаю ошибку:

Тип возвращаемого ресурса для компонента 0, объявленный в коде шейдера (UINT), несовместим с типом ресурса, привязанным к слоту Unordered Access View. 0 модуля вычислительного шейдера (UNORM).

, хотя unorm несовместим с uint и изменил мой вопрос. Но ответ Чака заставил меня понять, что я был неправ.

Как мне написать шейдер, который устанавливает биты в памяти без каких-либо преобразований типов?

Ответы [ 2 ]

1 голос
/ 06 мая 2020

Поскольку вы указали формат _UNORM, результирующие значения с плавающей запятой от 0,0 до 1,0 будут сопоставлены с 0 до 255.

Точное сопоставление будет другим, если вы используете _SNORM, _UINT по сравнению с _SINT.

0 голосов
/ 26 июля 2020

A DXGI_FORMAT_R8G8B8A8_UNORM шейдер должен возвращать float4.

Я действительно этого не ожидал. Однако, если учесть, что графический процессор предназначен для 32-битных вычислений, а дисплей имеет только 32 бита, поддерживающий каждый пиксель, это означает наличие встроенного преобразователя из float4 в DXGI_FORMAT_R8G8B8A8.

Это также сбили с толку других:

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

...