Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Directx 偶尔缺少绘制天空球体的多边形(在远平面)_Directx_Hlsl_Visual Glitch - Fatal编程技术网

Directx 偶尔缺少绘制天空球体的多边形(在远平面)

Directx 偶尔缺少绘制天空球体的多边形(在远平面),directx,hlsl,visual-glitch,Directx,Hlsl,Visual Glitch,我正在绘制一个天空球体作为三维视图的背景。有时,在视图周围导航时,会突然出现视觉故障: 这个小故障的例子:一个黑色的形状,渲染时显然并没有在屏幕上放置碎片 黑色是设备在每帧开始时清除的颜色 黑色区域的形状每次都不同,有时可以看到许多多边形。它们总是以一个公共点为中心,通常靠近屏幕中心 在不改变导航(眼睛位置和外观)的情况下重新绘制不会使故障消失,也就是说,它似乎取决于特定的导航 一旦导航发生变化,即使是极小的变化,它也会消失,天空也会变得坚实。大多数绘画是正确的。最终,当你四处走动时,你会发

我正在绘制一个天空球体作为三维视图的背景。有时,在视图周围导航时,会突然出现视觉故障:

这个小故障的例子:一个黑色的形状,渲染时显然并没有在屏幕上放置碎片

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

顶点着色器

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
像素着色器

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不是问题的原因

技术

const float fRadius = GetScene().GetFarPlane() - GetScene().GetNearPlane()*2;
D3DXCreateSphere(GetScene().GetDevicePtr(), fRadius, 64, 64, &m_poSphere, 0);
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
。没有任何区别。

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

确保您正确初始化了
g_vecEyePos
常量(可能是您在DirectX SetShaderConstant函数中错放了它?)

此外,如果您已将眼睛位置的转换包含在
g_mWorldViewProj
的世界矩阵中,则不应执行
posL+=g_veceypos在VS中,因为它会导致顶点移动到眼睛位置的两倍

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

  • g_mworldwiewproj=mCamView*mCamProj
    posL+=g_vecEyePos

  • g_mWorldViewProj=矩阵翻译(g_veceypos)*mCamView*mCamProj


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

    确保您正确初始化了
    g_vecEyePos
    常量(可能是您在DirectX SetShaderConstant函数中错放了它?)

    此外,如果您已将眼睛位置的转换包含在
    g_mWorldViewProj
    的世界矩阵中,则不应执行
    posL+=g_veceypos在VS中,因为它会导致顶点移动到眼睛位置的两倍

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

  • g_mworldwiewproj=mCamView*mCamProj
    posL+=g_vecEyePos

  • g_mWorldViewProj=矩阵翻译(g_veceypos)*mCamView*mCamProj


  • 好像是你的远剪裁平面造成的。它的当前值是多少?更改它并查看。近/远平面的当前值为1-5000。如果我稍微更改far计划(例如5050),则不会产生任何影响。很多(20000,但保持球体半径5000)是这样的:但我不想让它保持这样,因为对可见对象来说,这将极大地浪费精度。无论如何,球体的半径肯定小于剪辑距离。。。那么它为什么会影响它呢?所以它是远剪裁平面,我们现在知道了很多。:)现在,您是否使天空球体与摄影机保持恒定的距离?这个距离是多少?“outVS.posH=mul(float4(posL,1.0f),g_mWorldViewProj).xyzw;//始终在远平面上”这条线有什么可疑之处?距离是它被转换成围绕相机的中心,并且它有一个固定的半径。似乎是你的远剪裁平面造成的。它的当前值是多少?更改它并查看。近/远平面的当前值为1-5000。如果我稍微更改far计划(例如5050),则不会产生任何影响。很多(20000,但保持球体半径5000)是这样的:但我不想让它保持这样,因为对可见对象来说,这将极大地浪费精度。无论如何,球体的半径肯定小于剪辑距离。。。那么它为什么会影响它呢?所以它是远剪裁平面,我们现在知道了很多。:)现在,您是否使天空球体与摄影机保持恒定的距离?这个距离是多少?“outVS.posH=mul(float4(posL,1.0f),g_mWorldViewProj).xyzw;//始终在远平面上”这条线有什么可疑之处?距离是它被转换成围绕相机的中心,并且它有一个固定的半径。顺便说一句,我认为球体的半径应该是
    const float fRadius=GetScene().GetFarPlane(),这是从眼睛到远平面的距离。这两种方法都不起作用——也就是说,两者都产生了黑色背景,没有任何可见的多边形。我通过添加一行
    outVS.posH.w*=1.01来“解决”它-对我来说似乎很可疑,但它有效。顺便说一句