direct x 11 интеллектуальное создание буферов вершин

У меня есть небольшая загадка, которая просто ставит меня в тупик. Допустим, у меня есть пара шейдеров с разными типами вершин, например:

// light shader
struct vertexInputType
{
    float4 position : POSITION;
    float2 tex : TEXCOORD0;
    float3 normal : NORMAL;
};

// color shader
struct vertexInputType
{
    float4 position : POSITION;
    float4 color : COLOR;
};

// bump mapping shader
struct vertexInputType
{
    float4 position : POSITION;
    float2 tex : TEXCOORD0;
    float3 normal : NORMAL;
    float3 binormal : BINORMAL;
    float3 tangent : TANGENT;
};

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

1) я мог бы иметь большой буфер в оперативной памяти, в котором хранятся все данные, а затем при каждом вызове отрисовки я беру из объекта шейдера тип вершины и создаю новый буфер вершин с правильной информацией. Это, как вы можете видеть, будет УЖАСНО медленным.

or...

2) я мог бы создать несколько буферов ID3D11Buffers при инициализации модели, где один буфер имеет положение и цвет, другой имеет положение, texcoord и нормаль, один имеет положение, texcoord, нормаль, бинормаль и касательную, а также столько необходимых буферов для любых других типов вершин, для которых модель имеет информацию. Для сравнения, это стирает ваш доступный vram, что также делает это nogo.

Я не вижу другого способа сделать это. Как вы, другие ребята из d3d, делаете это?


person FatalCatharsis    schedule 16.07.2012    source источник


Ответы (2)


Хорошо, что вы спрашиваете об этом в контексте DX11 — ID3D11InputLayout НАМНОГО упрощает эту концепцию по сравнению с предыдущими версиями. Вы можете использовать CreateInputLayout для создания нескольких макетов ваших данных вершин (по одному для каждой из структур, которые вы указали выше) и вызова IASetInputLayout с правильным макетом в точках, в которых вы хотите, чтобы один и тот же буфер вершин интерпретировался по-разному.

Изменить: посмотрите здесь для примера создания объекта Input-Layout.

Надеюсь это поможет!

person Ani    schedule 16.07.2012
comment
да, до сих пор я использовал учебные пособия при создании макета ввода для шейдера, но теперь мне любопытно, как настроить макет ввода. Вы говорите, что я могу иметь, например, ID3D11Buffer, который содержит все данные, такие как положение, цвет, нормали, текстуры и т. д., а затем можно настроить макет для выбора отдельных элементов для этого шейдера? Как бы я это сделал? прямо сейчас я просто определяю первый входной элемент desc с его членомalignbyteoffset как 0, а затем остальные с D3D11_INPUT_PER_VERTEX_DATA; . Каков способ сделать это так, как я хочу? - person FatalCatharsis; 16.07.2012
comment
woops означало, что остальные были установлены на D3D11_APPEND_ALIGNED_ELEMENT. скопируйте и вставьте тот, что чуть ниже: P - person FatalCatharsis; 16.07.2012
comment
вау, теперь, когда я знаю, что это связано с макетом ввода, мне удалось найти в Google ЭТА статья. Типа объясняет все, что мне нужно знать :\. Спасибо, что поставили меня на правильный путь! - person FatalCatharsis; 16.07.2012
comment
Просто сделал длинное редактирование, объясняющее все, но ваша ссылка работает намного лучше. Я добавлю это к своему ответу в качестве редактирования, чтобы людям, которые приходят позже, не приходилось копаться в комментариях. - person Ani; 16.07.2012
comment
упс, простите за потраченное время, наверное :\. Тем не менее, спасибо за вашу помощь. - person FatalCatharsis; 16.07.2012

Хитрость заключается в том, чтобы разделить ваши данные на потоки: P, T, A.

Поток P содержит позицию и нормаль. Эти данные необходимы для рендеринга вершин с освещением. Вы также можете включить данные о бинормалях и цвете вершин.

Поток T содержит информацию о текстуре, поэтому может содержать ДО 8 каналов TU. Следует соблюдать осторожность, чтобы сохранить количество каналов, закодированных в этом потоке, чтобы гарантировать, что пропускная способность памяти не будет потрачена впустую при копировании пустых каналов через шину графического процессора.

Поток A содержит информацию об анимации, весе костей и т. д.

У вас может быть больше или меньше каналов в зависимости от архитектуры вашего конвейера рендеринга. Хитрость здесь заключается в использовании FVF для динамического определения макета данных. Одним из преимуществ этой архитектуры является оптимальное использование пропускной способности памяти. Это имеет особое значение, когда требуется несколько проходов рендеринга, но не все данные требуются для каждого прохода.

person blockchaindev    schedule 16.07.2012
comment
гм, FVF и потоки d3d9 я думаю. вообще не понимаю о чем ты :\ - person FatalCatharsis; 16.07.2012