我正在绘制一个天空球体作为3D视图的背景。偶尔,当在视图中导航时,会出现一个视觉故障:
毛刺的示例:黑色形状,渲染显然没有在屏幕上放置碎片
这些故障可能是什么原因?
我正在使用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
。没有任何区别。
答案 0 :(得分:1)
问题肯定是由远平面剪裁引起的。如果改变球体的半径有点没有帮助,那么球体的位置可能是错误的......
确保您正确初始化g_vecEyePos
常量(可能是您在其中一个DirectX SetShaderConstant函数中将其拼错了?)。
此外,如果您已将翻译包含在g_mWorldViewProj
的世界矩阵中的眼睛位置,则不应在VS中执行posL += g_vecEyePos;
,因为它会导致顶点移动两次眼睛的位置。
换句话说,您应该选择以下选项之一:
g_mWorldViewProj = mCamView * mCamProj;
和posL += g_vecEyePos;
g_mWorldViewProj = MatrixTranslation(g_vecEyePos) * mCamView * mCamProj;