1

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

蓝天中间出现黑色或缺失多边形

故障示例:渲染显然没有在屏幕上放置片段的黑色形状

  • 黑色是设备在每帧开始时被清除的颜色。
  • 黑色区域的形状每次都不一样,有时可以看到很多多边形。它们总是以一个公共点为中心,通常靠近屏幕中心
  • 在不改变导航(眼睛位置和外观)的情况下重新绘制不会使故障消失,即它似乎确实取决于特定的导航
  • 导航改变的那一刻,即使是微乎其微的改变,它也会消失,天空会变得坚实。绝大多数的绘画是正确的。最终,当您四处走动时,您会发现另一个故障。
  • 改变球体的半径(例如,近/远平面距离的 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);

相同的图像,带有纯色像素着色器

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

4

1 回答 1

1

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

确保您正确初始化g_vecEyePos常量(也许您在 DirectX SetShaderConstant 函数之一中拼错了它?)。

此外,如果您在 的世界矩阵中包含了对眼睛位置的平移,则g_mWorldViewProj不应posL += g_vecEyePos;在 VS 中执行此操作,因为它会导致顶点移动眼睛位置的两倍。

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

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

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

于 2012-08-21T22:22:40.493 回答