偶尔丢失的多边形绘制天空球体(在远处的平面)

时间:2012-08-16 16:56:30

标签: directx hlsl visual-glitch

我正在绘制一个天空球体作为3D视图的背景。偶尔,当在视图中导航时,会出现一个视觉故障:

Black or missing polygon in the middle of blue sky

毛刺的示例:黑色形状,渲染显然没有在屏幕上放置碎片

  • 黑色是设备在每帧开始时被清除的颜色。
  • 黑色区域的形状每次都不同,有时可见多个多边形。它们始终以公共点为中心,通常靠近屏幕中心
  • 重新绘制而不改变导航(眼睛位置和外观)不会使故障消失,即它似乎依赖于特定的导航
  • 瞬间导航改变,即使是无限小的数量,它也会消失,天空也会稳固地吸引。绝大多数的绘画是正确的。最后,当你四处走动时,你会发现另一个小故障。
  • 更改球​​体的半径(例如,近/远平面距离的0.9)似乎不会消除毛刺
  • 在效果技术中更改Z缓冲区写入或Z测试没有区别
  • 没有DX调试输出(运行时使用运行时的调试版本,最大验证和启用着色器调试。)

这些故障可能是什么原因?

我正在使用Direct3D9(2010年6月SDK),将着色器编译为SM3,并且在Windows 7和XP上的ATI卡和VMWare Fusion虚拟卡上观察到了故障。

示例代码

天空被绘制为一个球体(错误检查等删除了下面的代码):

创建

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);

Same image, with a solid-colour pixel shader

与纯色像素着色器相同的图像,确定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。没有任何区别。

1 个答案:

答案 0 :(得分:1)

问题肯定是由远平面剪裁引起的。如果改变球体的半径有点没有帮助,那么球体的位置可能是错误的......

确保您正确初始化g_vecEyePos常量(可能是您在其中一个DirectX SetShaderConstant函数中将其拼错了?)。

此外,如果您已将翻译包含在g_mWorldViewProj的世界矩阵中的眼睛位置,则不应在VS中执行posL += g_vecEyePos;,因为它会导致顶点移动两次眼睛的位置。

换句话说,您应该选择以下选项之一:

  1. g_mWorldViewProj = mCamView * mCamProj;posL += g_vecEyePos;

  2. g_mWorldViewProj = MatrixTranslation(g_vecEyePos) * mCamView * mCamProj;