Directx 偶尔缺少绘制天空球体的多边形(在远平面)
我正在绘制一个天空球体作为三维视图的背景。有时,在视图周围导航时,会突然出现视觉故障: 这个小故障的例子:一个黑色的形状,渲染时显然并没有在屏幕上放置碎片Directx 偶尔缺少绘制天空球体的多边形(在远平面),directx,hlsl,visual-glitch,Directx,Hlsl,Visual Glitch,我正在绘制一个天空球体作为三维视图的背景。有时,在视图周围导航时,会突然出现视觉故障: 这个小故障的例子:一个黑色的形状,渲染时显然并没有在屏幕上放置碎片 黑色是设备在每帧开始时清除的颜色 黑色区域的形状每次都不同,有时可以看到许多多边形。它们总是以一个公共点为中心,通常靠近屏幕中心 在不改变导航(眼睛位置和外观)的情况下重新绘制不会使故障消失,也就是说,它似乎取决于特定的导航 一旦导航发生变化,即使是极小的变化,它也会消失,天空也会变得坚实。大多数绘画是正确的。最终,当你四处走动时,你会发
- 黑色是设备在每帧开始时清除的颜色
- 黑色区域的形状每次都不同,有时可以看到许多多边形。它们总是以一个公共点为中心,通常靠近屏幕中心
- 在不改变导航(眼睛位置和外观)的情况下重新绘制不会使故障消失,也就是说,它似乎取决于特定的导航
- 一旦导航发生变化,即使是极小的变化,它也会消失,天空也会变得坚实。大多数绘画是正确的。最终,当你四处走动时,你会发现另一个小故障
- 更改球体的半径(例如,更改为近/远平面距离的0.9)似乎无法消除故障
- 在effect技术中更改Z缓冲区写入或Z测试没有任何区别
- 没有DX调试输出(在运行时启用调试版本、最大验证和着色器调试时)
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来“解决”它代码>-对我来说似乎很可疑,但它有效。顺便说一句