2015-09-21 11 views
1

Я готовлю все в небольшом проекте DirectX 11.0 для отложенного конвейера рендеринга. Тем не менее, у меня было довольно много проблем с выборкой буфера глубины из пиксельного шейдера.Проблемы с выборкой D3D11 буфера глубины

Сначала я определить текстуру глубины и его вид ресурса шейдера:

D3D11_TEXTURE2D_DESC depthTexDesc; 
    ZeroMemory(&depthTexDesc, sizeof(depthTexDesc)); 
    depthTexDesc.Width = nWidth; 
    depthTexDesc.Height = nHeight; 
    depthTexDesc.Format = DXGI_FORMAT_R32_TYPELESS; 
    depthTexDesc.Usage = D3D11_USAGE_DEFAULT; 
    depthTexDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL | D3D11_BIND_SHADER_RESOURCE; 
    depthTexDesc.MipLevels = 1; 
    depthTexDesc.ArraySize = 1; 
    depthTexDesc.SampleDesc.Count = 1; 
    depthTexDesc.SampleDesc.Quality = 0; 
    depthTexDesc.CPUAccessFlags = 0; 
    depthTexDesc.MiscFlags = 0; 

    hresult = d3dDevice_->CreateTexture2D(&depthTexDesc, nullptr, &depthTexture_); 

    D3D11_DEPTH_STENCIL_VIEW_DESC DSVDesc; 
    ZeroMemory(&DSVDesc, sizeof(DSVDesc)); 
    DSVDesc.Format = DXGI_FORMAT_D32_FLOAT; 
    DSVDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; 
    DSVDesc.Texture2D.MipSlice = 0; 

    hresult = d3dDevice_->CreateDepthStencilView(depthTexture_, &DSVDesc, &depthView_); 

    D3D11_SHADER_RESOURCE_VIEW_DESC gbDepthTexDesc; 
    ZeroMemory(&gbDepthTexDesc, sizeof(gbDepthTexDesc)); 
    gbDepthTexDesc.Format = DXGI_FORMAT_R32_FLOAT; 
    gbDepthTexDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; 
    gbDepthTexDesc.Texture2D.MipLevels = 1; 
    gbDepthTexDesc.Texture2D.MostDetailedMip = -1; 

    d3dDevice_->CreateShaderResourceView(depthTexture_, &gbDepthTexDesc, &gbDepthView_); 

Вот соответствующая часть моей функции рендеринга:

float clearColor[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; 
    d3dContext_->ClearRenderTargetView(backBufferTarget_, clearColor); 
    d3dContext_->ClearDepthStencilView(depthView_, D3D11_CLEAR_DEPTH, 1.0f, 0); 

    // GBuffer packing pass (in the future): ///////////////////////////////////////// 

    d3dContext_->OMSetRenderTargets(1, &backBufferTarget_, depthView_); 

    unsigned int nStride = sizeof(Vertex); 
    unsigned int nOffset = 0; 

    d3dContext_->IASetInputLayout(inputLayout_); 
    d3dContext_->IASetVertexBuffers(0, 1, &vertexBuffer_, &nStride, &nOffset); 
    d3dContext_->IASetIndexBuffer(indexBuffer_, DXGI_FORMAT_R32_UINT, 0); 
    d3dContext_->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); 

    d3dContext_->VSSetShader(firstVS_, 0, 0); 
    d3dContext_->PSSetShader(firstPS_, 0, 0); 

    d3dContext_->DrawIndexed(nIndexCount_, 0, 0); 

    d3dContext_->OMSetRenderTargets(1, &backBufferTarget_, nullptr); 

    d3dContext_->VSSetShader(secondVS_, 0, 0); 
    d3dContext_->PSSetShader(secondPS_, 0, 0); 
    d3dContext_->PSGetShaderResources(0, 1, &gbDepthView_); 
    d3dContext_->PSSetSamplers(0, 1, &colorMapSampler_); 

    d3dContext_->DrawIndexed(nIndexCount_, 0, 0); 

    swapChain_->Present(0, 0); 

В этой временной реализации, firstVS_ и secondVS_ идентичны, и их единственная функция - делать все преобразования и передавать данные в PS.

И, наконец, вот firstPS_ и secondPS_:

// firstPS_ 
float4 main(PS_Input frag) : SV_TARGET 
{ 
    return float4(1.0f, 1.0f, 1.0f, 1.0f); 
} 

// secondPS_ 
Texture2D<float> depthMap_ : register(t0); 
SamplerState colorSampler_ : register(s0); 

float4 main(PS_Input frag) : SV_TARGET 
{ 
    float4 psOut; 
    psOut.xyz = depthMap_.Sample(colorSampler_, frag.tex0).xxx; 
    psOut.w = 1.0f; 
    return psOut; 
} 

Итак, мои актуальные вопросы:

1) Все это код компилируется без каких-либо проблем, но когда я попробовать буфер глубины, он просто оказывается черным. Я читал, что это может быть вызвано тем, что ваша глубина &: просмотр трафарета связан D3D11DeviceContext::OMSetRenderTargets() во время выбора буфера глубины. Я исправил это, но буфер все еще черный. Я проверил графический отладчик, без успеха. Итак, мой буфер глубины не получается правильно написанным, или я неправильно пробовал? firstPS_ отлично работает.

2) Говоря о выборке, книга, которую я использую, просто говорит: «Мы будем использовать точечный сэмплер», но я понятия не имею, что именно имеется в виду. Теперь я просто использую стандартный сэмплер текстурной карты, но есть ли что-то еще, что я должен попробовать?

3) Кроме того, книга использует функцию SamplerState.Gather() в secondPS_, но когда я попробовал, он пожаловался, что «выражение не может быть отображено в набор инструкций пиксельных шейдеров». Является ли Gather() ошибкой в ​​книге, или это мой графический процессор (D3D feature level 11.0), который не понимает, что это такое? Является ли Sample() достаточным для того, что я хочу делать? Первоначальное использование Gather() было в контексте создания силуэта вокруг объектов в буфере глубины.

4) Я попытался получить secondVS_, чтобы нарисовать ничего, кроме полноэкранного четырехъядерного процессора, но FXC жаловался на то, что мое использование SV_VertexID было «недействительным», заявив, что мой тип должен быть интегральным, даже если он уже был. Я где-то читал, что SV_VertexID может использоваться только первым VS в конвейере. Это проблема здесь? Как я могу решить это в этом конкретном случае? В моем текущем неэффективном решении проблема связана с УФ?

+0

Включили ли вы слой отладки? Такие ошибки, как установка ресурса как ввода, так и вывода, очень легко обнаружить с помощью отладочных сообщений. Всегда мой первый шаг, если что-то возвращает неожиданный черный цвет. – Gnietschow

+0

Уровень отладки включен, и все предупреждения создания состояния - # 0. Я до сих пор не знаю, что происходит. – PeanutsGrowUnderground

+0

Почему параметр MostDetailedMip установлен на -1 в SRV? –

ответ

1

1) Вы вызывали PSGetShaderResources вместо PSSetShaderResources. Кроме того, MostDetailedMip должен быть 0 не -1.

2) «Точечный пробоотборник» - это только образец текстуры с полем FILTER, установленным на что-то вроде D3D11_FILTER_MIN_MAG_MIP_POINT.

3) Соберите функцию на Texture2D, а не на SamplerState, как вы заявили.

4) Вы получаете эту ошибку, если компилируете с помощью vs_4_0, попробуйте vs_5_0.

+0

Благодарим вас за всех ваших ответчиков. Все они помогли, хотя, когда я просмотрел свой код, я обнаружил, что MostDetailedMip уже установлен в 0. И я не могу поверить, что пропустил эту опечатку. Пока все регистрируется правильно, мой буфер глубины, кажется, заполнен только значениями 1.0f. Я помету ваш ответ, как только это будет исправлено. – PeanutsGrowUnderground

 Смежные вопросы

  • Нет связанных вопросов^_^