Понимание программирования шейдеров

Я пытаюсь понять программирование шейдеров, но на данный момент документация мне не поможет.

1] Есть ли тип данных & размер буферов должен совпадать?

В руководстве по DX 4 из DX SDK они имеют структуру:

struct SimpleVertex{
XMFLOAT3 Pos;
XMFLOAT4 Color;
};

Находясь в своем файле шейдера, они определяют:

struct VS_OUTPUT{
float4 Pos : SV_POSITION;
float4 Color : COLOR0;
};

Они определяют Pos как вектор из 3 в одном файле, а 4 в другом. Как это правильно? Я думал, что размер данных должен совпадать.

2] Чтобы создать еще один постоянный буфер, это шаги, которые мне нужно сделать?

// Make in shader file
cbuffer LightBuffer : register(b0){
float3 lDir;
float4 lColor;
}

// Make in C++ file
struct LightBuffer{
XMFLOAT3 Direction;
XMFLOAT4 Color;
};

...

LightBuffer lb;
lb.Direction=XMFLOAT3(-1.0f, -10.0f, 4.0f); // Make an instance of it
lb.Color=XMFLOAT4(0.35f, 0.5f, 1.0f, 1.0f);

...

ID3D11Buffer* lightBuffer=NULL; // Declare in global scope

D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(bd));
bd.Usage=D3D11_USAGE_DEFAULT;
bd.ByteWidth=sizeof(LightBuffer);
bd.BindFlags=D3D11_BIND_CONSTANT_BUFFER;

hr=graphics->deviceInterface->CreateBuffer(&bd, NULL, &lightBuffer);

graphics->deviceContext->UpdateSubresource(lightBuffer, 0, NULL, &lb, 0, 0);

graphics->deviceContext->PSSetConstantBuffers(0, 1, &lightBuffer);

Вот шаги, которые я сделал, что было похоже на постоянный буфер в учебнике. В итоге ничего не получается.

Я случайно обнаружил, что если я изменю тип LightBuffer :: XMFLOAT3 Направление до XMFLOAT4, это работает. Что я не понимаю? Почему я не могу выбрать желаемый тип?

Спасибо за прочтение.

2

Решение

1-Как видно из названия структуры, это не вход, а выход вершинного шейдера. Вершинный шейдер должен выводить переменную положения как 4 числа с плавающей запятой (координаты гомогена). Поэтому где-то в файле шейдера должна быть операция, которая расширяет вектор до переменной float4 (что-то вроде «float4 (inputPos, 1.0);»).

2-Это, вероятно, проблема выравнивания. Графические процессоры предназначены для работы с 4D векторами. Используя постоянные буферы, попробуйте создать свои структуры с матрицами сначала, 4D переменными во вторую, 3D переменными третьими и так далее. Или вы можете добавить дополнительные неиспользуемые байты заполнения, как вы и сказали. Если у вас слишком много не 4D векторов, вы можете упаковать их в один слот с ключевым словом «packoffset», чтобы не тратить впустую регистры GPU. Подробное объяснение здесь:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb509581(v=vs.85).aspx

1

Другие решения

  1. SimpleVertex — это боковая структура C ++, определяющая вход макет вершины. VS_OUTPUT — боковая структура hlsl, определяющая вершинный шейдер выход / пиксельный шейдер вход. Компоновка SimpleVertex соответствует вершинному шейдеру вход который является аргументами для функции вершинного шейдера VS (float4 Pos: POSITION, float4 Color: COLOR). В D3D11 вы используете объект ID3D11InputLayout (на стороне C ++), чтобы описать, как макет входной вершины (структура SimpleVertex) должен быть связан со входами вершинного шейдера. Если вы ищете в исходном коде C ++ учебник для InputLayout, вы увидите, где он создан.
  2. Вам необходимо учитывать выравнивание с постоянными буферами. Члены константного буфера выровнены по границам float4, но структуры C ++ не таковы, когда вы используете XMFLOAT3 для направления, ваш цвет XMFLOAT4 не совпадает с макетом, который ваш постоянный буфер определяет в hlsl.
1

По вопросам рекламы [email protected]