DirectX 11: каждая сетка рисуется в глубинный буфер как 0, что фактически исключает тестирование глубины.

Вопрос или проблема

Насколько я знаю, я правильно настроил тестирование глубины, однако объекты отрисовываются с первого по последний. Я посмотрел в графическом отладчике, и кажется, что когда меш отрисовывается, он устанавливает буфер глубины в 0, независимо от расстояния.

    D3D11_TEXTURE2D_DESC описаниеБуфераГлубины;
    d3d11FrameBuffer->GetDesc(&описаниеБуфераГлубины);

    d3d11FrameBuffer->Release();

    описаниеБуфераГлубины.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
    описаниеБуфераГлубины.BindFlags = D3D11_BIND_DEPTH_STENCIL;
    описаниеБуфераГлубины.Width = 1920;
    описаниеБуфераГлубины.Height = 1080;
    описаниеБуфераГлубины.MipLevels = 1;
    описаниеБуфераГлубины.ArraySize = 1;
    описаниеБуфераГлубины.SampleDesc.Count = 1;
    описаниеБуфераГлубины.SampleDesc.Quality = 0;
    описаниеБуфераГлубины.Usage = D3D11_USAGE_DEFAULT;
    описаниеБуфераГлубины.CPUAccessFlags = 0;
    описаниеБуфераГлубины.MiscFlags = 0;


    ID3D11Texture2D* буферГлубины;
    HRESULT результат = d3d11Device->CreateTexture2D(&описаниеБуфераГлубины, nullptr, &буферГлубины);
    
    D3D11_DEPTH_STENCIL_VIEW_DESC описаниеВидаГлубиныШтемпеля;
    ZeroMemory(&описаниеВидаГлубиныШтемпеля, sizeof(описаниеВидаГлубиныШтемпеля));
    описаниеВидаГлубиныШтемпеля.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
    описаниеВидаГлубиныШтемпеля.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
    описаниеВидаГлубиныШтемпеля.Texture2D.MipSlice = 0;

    результат = d3d11Device->CreateDepthStencilView(буферГлубины, nullptr, видБуфераГлубины);
    ID3D11DepthStencilState* состояниеГлубиныШтемпеля;
    {
        D3D11_DEPTH_STENCIL_DESC описаниеГлубиныШтемпеля = {};
        описаниеГлубиныШтемпеля.DepthEnable = true;
        описаниеГлубиныШтемпеля.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
        описаниеГлубиныШтемпеля.DepthFunc = D3D11_COMPARISON_LESS;
        описаниеГлубиныШтемпеля.StencilEnable = false;
        описаниеГлубиныШтемпеля.StencilReadMask = 0xFF;
        описаниеГлубиныШтемпеля.StencilWriteMask = 0xFF;
        описаниеГлубиныШтемпеля.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
        описаниеГлубиныШтемпеля.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
        описаниеГлубиныШтемпеля.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
        описаниеГлубиныШтемпеля.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
        описаниеГлубиныШтемпеля.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
        описаниеГлубиныШтемпеля.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
        описаниеГлубиныШтемпеля.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
        описаниеГлубиныШтемпеля.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;

        d3d11Device->CreateDepthStencilState(&описаниеГлубиныШтемпеля, &состояниеГлубиныШтемпеля);
    }
        d3d11DeviceContext->RSSetState(rasterizerState);
        d3d11DeviceContext->OMSetDepthStencilState(состояниеГлубиныШтемпеля, 1);

        d3d11DeviceContext->OMSetRenderTargets(1, &d3d11FrameBufferView, видБуфераГлубины);

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

Ответ или решение

Проблема, с которой вы столкнулись, может быть связана с несколькими аспектами конфигурации буфера глубины и состояния глубины порисовки в DirectX 11. Исходя из вашего кода, можно выделить ключевые моменты, которые стоит проверить и исправить.

1. Инициализация буфера глубины

Убедитесь, что буфер глубины действительно создается корректно. Возможно, нужно установить свойства текстуры глубины перед тем, как вызывать CreateTexture2D. Например, если d3d11FrameBuffer не освобождается корректно, это может повлиять на последующую инициализацию. Убедитесь, что d3d11FrameBuffer перед вызовом GetDesc правильно инициализирован.

2. Состояние глубины

В вашем коде вы создаете состояние глубины, но важно также установить это состояние перед рендерингом. Убедитесь, что вы установили состояние глубины перед каждым циклом рендеринга:

d3d11DeviceContext->OMSetDepthStencilState(depthStencilState, 1);

3. Установка целей рендеринга

Когда вы устанавливаете рендер-таргеты, убедитесь, что также правильно используете OMSetRenderTargets. Убедитесь, что порядок аргументов правильный; сначала идёт буфер цвета, потом буфер глубины.

4. Проверка параметров растеризатора

Если отключение отсечения по глубине (depth clipping) вызывает проблемы с рендерингом, возможно, вам следует пересмотреть настройки растеризатора. Попробуйте использовать стандартные настройки, прежде чем настраивать их индивидуально. Например, попробуйте включить отсечение по глубине и посмотрите, изменится ли поведение.

5. Убедитесь в правильности Z-координат

Проверьте, что Z-координаты ваших объектов находятся в диапазоне [0, 1] или [nearPlane, farPlane], в зависимости от того, как вы настроили масштабирование глубины. Если все ваши объекты имеют Z-координату 0, это объясняет, почему все они отображаются в порядке от первого к последнему.

Пример обновленного кода

Ниже приведен упрощенный пример, который может помочь вам определить, работает ли система глубины корректно:

// Настройка буфера глубины
D3D11_TEXTURE2D_DESC depthBufferDesc;
ZeroMemory(&depthBufferDesc, sizeof(depthBufferDesc));
depthBufferDesc.Width = 1920;
depthBufferDesc.Height = 1080;
depthBufferDesc.MipLevels = 1;
depthBufferDesc.ArraySize = 1;
depthBufferDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
depthBufferDesc.SampleDesc.Count = 1;
depthBufferDesc.Usage = D3D11_USAGE_DEFAULT;
depthBufferDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;

HRESULT hr = d3d11Device->CreateTexture2D(&depthBufferDesc, nullptr, &depthBuffer);

// Настройка глубинного представления
D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc;
ZeroMemory(&depthStencilViewDesc, sizeof(depthStencilViewDesc));
depthStencilViewDesc.Format = depthBufferDesc.Format;
depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
depthStencilViewDesc.Texture2D.MipSlice = 0;

hr = d3d11Device->CreateDepthStencilView(depthBuffer, nullptr, &depthBufferView);

// Настройка состояния глубины
D3D11_DEPTH_STENCIL_DESC depthStencilDesc = {};
depthStencilDesc.DepthEnable = TRUE;
depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS;

d3d11Device->CreateDepthStencilState(&depthStencilDesc, &depthStencilState);

// Цикл рендеринга
d3d11DeviceContext->OMSetRenderTargets(1, &d3d11FrameBufferView, depthBufferView);
d3d11DeviceContext->OMSetDepthStencilState(depthStencilState, 1);

Заключение

После внесения этих изменений, протестируйте вашу программу еще раз. Если проблема сохраняется, вам стоит рассмотреть другие аспекты вашего рендеринга, такие как корректность использования шейдеров и входных данных, передаваемых в вершинный шейдер. Надеюсь, это поможет вам выявить источник проблемы с буфером глубины в вашей реализации DirectX 11.

Оцените материал
Добавить комментарий

Капча загружается...