Как заставить zbuffer работать правильно в DirectX 9?
Вопрос
Мне не удалось добиться правильного отображения простой геометрии куба с включенной заливкой.
Это код C#, но значения передаются через SlimDX непосредственно в код C++.
pParams.BackBufferWidth = 0;
pParams.BackBufferHeight = 0;
pParams.BackBufferCount = 1;
pParams.BackBufferFormat = Format::X8R8G8B8;
pParams.Multisample = MultisampleType::None;
pParams.MultisampleQuality = 0;
pParams.DeviceWindowHandle = this.Handle;
pParams.Windowed = true;
pParams.AutoDepthStencilFormat = Format.D24X8;
pParams.EnableAutoDepthStencil = true;
pParams.PresentFlags = PresentFlags.None;
pParams.FullScreenRefreshRateInHertz = 0;
pParams.PresentationInterval = PresentInterval.Immediate;
pParams.SwapEffect = SwapEffect.Discard;
...— это значения в структуре PresentParameter, используемые для настройки моего объекта Direct3D9Device.
Во время рендеринга SetRenderState вызывается следующим образом:
this.D3DDevice.Clear(ClearFlags.Target | ClearFlags.ZBuffer, this.BackColor, 10000.0f, 0);
this.D3DDevice.SetRenderState(RenderState.Ambient, false);
this.D3DDevice.SetRenderState(RenderState.ZEnable, ZBufferType.UseZBuffer);
this.D3DDevice.SetRenderState(RenderState.ZWriteEnable, true);
this.D3DDevice.SetRenderState(RenderState.ZFunc, Compare.LessEqual);
this.D3DDevice.BeginScene();
Опять же, это передается в код C++, который маршализует значения для вызовов, которых не боится программист C++.
Примитивы представляют собой вершины диффузного цвета (D3DFVF_XYZ | D3DFVF_DIFFUSE).Каркасный вид выглядит так:каркасный вид http://gallery.me.com/robert.perkins/100045/z-fightingwireframe/web.jpg
Ближайшая пара больших треугольников — это ближняя грань куба.
Заполненное представление выглядит так:полный вид 1 http://gallery.me.com/robert.perkins/100045/Z-fighting/web.jpg
Или это при последующем вызове рендеринга:полный вид 2 http://gallery.me.com/robert.perkins/100045/zfight2/web.jpg
Я не уверен, как это исправить.С чего мне начать поиск?
Редактировать:Матрица проекции камеры для одного из кадров выглядит примерно так:
{[[M11:0.6281456 M12:0.7659309 M13:0.1370506 M14:0]
[M21:0.7705086 M22:-0.5877584 M23:-0.2466911 M24:0]
[M31:-0.1083957 M32:0.2605566 M33:-0.9593542 M34:0]
[M41:-3.225646 M42:-1.096823 M43:20.91392 M44:1]]}
И матрица представления выглядит так:
camera.ViewMatrix = {[[M11:0.6281456 M12:0.7659309 M13:0.1370506 M14:0]
[M21:0.7705086 M22:-0.5877584 M23:-0.2466911 M24:0]
[M31:-0.1083957 M32:0.2605566 M33:-0.9593542 M34:0]
[M41:-3.225646 M42:-1.096823 M43:20.91392 M44:1]]}
Решение
Очистите Z-буфер до 1.0f, а не до 10000.0f.
Из Clear docs в SDK:
[in] Clear the depth buffer to this new z value which ranges from 0 to 1..
Также может быть полезно посмотреть настройки вашей матрицы проекции и области просмотра...
Редактировать:Как построить эту матрицу проекции?Вы установили zNear на 0 и zFar на 1.Попробуйте установить zNear на 0,001f и zFar на 1000,0f и посмотрите, поможет ли это вам вообще...
Другие советы
Предчувствие:Попробуйте включить Z-буфер перед очисткой.