Я рисую небесную сферу в качестве фона для 3D-вида. Иногда при навигации по представлению возникает визуальный сбой, который появляется:
Пример сбоя: черная фигура, фрагменты которой при рендеринге явно не отображаются на экране
- Черный — это цвет, на который устройство очищается в начале каждого кадра.
- Форма черной области каждый раз разная, и иногда видно много полигонов. Они всегда сосредоточены вокруг общей точки, обычно близкой к центру экрана.
- Перерисовка без изменения навигации (положения глаз и взгляда) не устраняет глюк, т. е. похоже, что он зависит от конкретной навигации.
- В тот момент, когда навигация изменяется, пусть даже незначительно, она исчезает, и небо рисуется целиком. Подавляющее большинство рисунков правильно. В конце концов, когда вы будете двигаться, вы заметите еще один глюк.
- Изменение радиуса сферы (например, до 0,9 расстояния в ближней/дальней плоскости), похоже, не устраняет сбои.
- Изменение записи Z-буфера или теста Z в технике эффекта не имеет значения
- Выходные данные отладки DX отсутствуют (при работе с отладочной версией среды выполнения, максимальной проверкой и включенной отладкой шейдеров).
В чем может быть причина этих глюков?
Я использую Direct3D9 (июнь 2010 SDK), шейдеры, скомпилированные в SM3, и сбой наблюдался на картах ATI и виртуальных картах VMWare Fusion в Windows 7 и XP.
Пример кода
Небо рисуется как сфера (проверка ошибок и т. д. удалена из приведенного ниже кода):
Чтобы создать
const float fRadius = GetScene().GetFarPlane() - GetScene().GetNearPlane()*2;
D3DXCreateSphere(GetScene().GetDevicePtr(), fRadius, 64, 64, &m_poSphere, 0);
Изменение радиуса, похоже, не влияет на наличие глюков.
Вершинный шейдер
OutputVS ColorVS(float3 posL : POSITION0, float4 c : COLOR0) {
OutputVS outVS = (OutputVS)0;
// Center around the eye
posL += g_vecEyePos;
// Transform to homogeneous clip space.
outVS.posH = mul(float4(posL, 1.0f), g_mWorldViewProj).xyzw; // Always on the far plane
Пиксельный шейдер
Не имеет значения, даже тот, который выводит сплошной цвет, будет глючить:
float4 ColorPS(float altitude : COLOR0) : COLOR {
return float4(1.0, 0.0, 0.0, 1.0);
То же изображение со сплошным пиксельным шейдером, чтобы убедиться, что PS не является причиной проблемы
Техника
technique BackgroundTech {
pass P0 {
// Specify the vertex and pixel shader associated with this pass.
vertexShader = compile vs_3_0 ColorVS();
pixelShader = compile ps_3_0 ColorPS();
// sky is visible from inside - cull mode is inverted (clockwise)
CullMode = CW;
}
}
Я попытался добавить в настройки состояния, влияющие на глубину, такие как ZWriteEnabled = false
. Ничто не имело никакого значения.