Вопрос или проблема
Насколько я знаю, я правильно настроил тестирование глубины, однако объекты отрисовываются с первого по последний. Я посмотрел в графическом отладчике, и кажется, что когда меш отрисовывается, он устанавливает буфер глубины в 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.