z-fighting在unity中的解決方式


如果在畫面中,發現有畫面閃爍的問題。那么大多數情況下是z-fighting引起的,


解決方案:


1, 在每個場景中,找到那個MainCamera,然后在Inspector上,找到MainCamera的屬性,Clipping Planes,需要做的是盡量放大near的值,盡量減小far的值。根據我的實驗結果,同樣改動Near值的幅度比Far值的幅度相對來說效果會更好。如Near從1到20可能修正了某個z-fighting,但是Far從1000改到500也還是沒有用。這個在實踐中可以注意。

 

2, 如果場景沒有辦法改動上述的值,那么還有的方式就是找到產生z-fighting的模型,讓模型產生這個現象的兩個面盡量離開一些距離,究竟多少距離只有通過實驗才知道。

 

3, 如果可能,程序上就可以用Polygon Offset,這個是OpenGL的接口,

 

 

[cpp]  view plain  copy
 
  1. drawOnePlane();  
  2.   
  3. //Draw other plane in the almost same position, before use offset, it will fighting with the one we has drawn.  
  4. glEnable( GL_POLYGON_OFFSET_FILL );  
  5. glPolygonOffset( g_OffsetFactor, g_OffsetUnit );  
  6.   
  7. drawOtherPlane();  
  8.   
  9. glPolygonOffset( 0.0f, 0.0f );  
  10. glDisable( GL_POLYGON_OFFSET_FILL );  

 


4、如果是D3D,那么這篇文章提到3中方式,最后一種方式是跟上面的OpenGL思路一樣的。

 

http://software.intel.com/zh-cn/articles/alternatives-to-using-z-bias-to-fix-z-fighting-issues/

 

a, project matrix

 

 

[cpp]  view plain  copy
 
  1. // ZFighting Solution #1 - Projection Matrix  
  2. D3DXMATRIX mProjectionMat;   // Holds default projection matrix  
  3. D3DXMATRIX mZBiasedProjectionMat;   // Holds ZBiased projection matrix  
  4. // Globals used for Projection matrix   
  5. float g_fBaseNearClip   =   1.0f;  
  6. float g_fBaseFarClip    = 100.0f;  
  7. // Code indicates no change. ie states 'near and far clipping planes pushed out' but only far appears pushed  
  8. float g_fNearClipBias   =   0.0f;   
  9. float g_fFarClipBias    =   0.5f;  
  10.   
  11. // Projection Matrix work around  
  12. // Best if calculation are done outside of render function.  
  13.   
  14. // The "zbiased" projection has it near and far clipping   
  15. // planes pushed out...  
  16. D3DXMatrixPerspectiveFovLH( &mZBiasedProjectionMat, D3DX_PI/4,(mProjectionMat._22/mProjectionMat._11),    
  17. g_fBaseNearClip + g_fNearClipBias,   
  18. g_fBaseFarClip + g_fFarClipBias  );  
  19. . . .  
  20.   
  21. // Original projection is loaded  
  22. m_pd3dDevice ->SetTransform( D3DTS_PROJECTION, & mProjectionMat);  
  23.   
  24. // Billboards are rendered...  
  25.   
  26. // The "zbiased" projection is loaded ...  
  27. m_pd3dDevice->SetTransform(D3DTS_PROJECTION, &mZBiasedProjectionMat);  
  28.   
  29. // Posters are rendered...  
  30.   
  31. // Original projection is reloaded...  
  32. g_pd3dDevice->SetTransform( D3DTS_PROJECTION, & mProjectionMat);  
  33.   
  34. . . .  


 

 

b, view port matrix

 

[cpp]  view plain  copy
 
  1. // ZFighting Solution #2 - Viewport  
  2. D3DVIEWPORT9 mViewport;             // Holds viewport data  
  3. D3DVIEWPORT9 mNewViewport;          // Holds new viewport data  
  4.   
  5. // Global used for Viewport   
  6. // Hard coded for ZBIAS of 1 using this formula   
  7. //          MinZ - 256/(2^24-1) and   
  8. //          MaxZ - 256/(2^24-1)  
  9. // 2^24 comes from the amount of Zbits and the 256 works   
  10. // for Intel (R) Integrated Graphics, but can be any   
  11. // multiple of 16.  
  12. float g_fViewportBias   = 0.0000152588f;  
  13.   
  14. // Projection Matrix work around  
  15. // Viewport work around  
  16. m_pd3dDevice->GetViewport(&mViewport);  
  17.   
  18. // Copy old Viewport to new  
  19. mNewViewport = mViewport;  
  20.   
  21. // Change by the bias  
  22. mNewViewport.MinZ -= g_fViewportBias;   
  23. mNewViewport.MaxZ -= g_fViewportBias;   
  24. . . .  
  25.   
  26. // Original viewport is reloaded …  
  27. m_pd3dDevice->SetViewport(&mViewport);  
  28.   
  29. // Billboards are rendered …  
  30.   
  31. // The new viewport is loaded …  
  32. m_pd3dDevice->SetViewport(&mNewViewport);  
  33.   
  34. // Posters are rendered …  
  35.   
  36. // Original viewport is reloaded …  
  37. m_pd3dDevice->SetViewport(&mViewport);  
  38.   
  39. . . .  
  40.   
  41.               


 

c, depth - bias

 

[cpp]  view plain  copy
 
  1. BOOL                    m_bDepthBiasCap;        // TRUE, if device has DepthBias Caps  
  2.   
  3. // Globals used for Depth Bias   
  4. float g_fSlopeScaleDepthBias    = 1.0f;  
  5. float g_fDepthBias              = -0.0005f;  
  6. float g_fDefaultDepthBias       = 0.0f;  
  7.   
  8. // Check for devices which support the new depth bias caps  
  9. if ((pCaps->RasterCaps & D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS) &&   
  10.      (pCaps->RasterCaps & D3DPRASTERCAPS_DEPTHBIAS))  
  11. {  
  12.     m_bDepthBiasCap = true;        // TRUE, if DepthBias Caps  
  13. }  
  14.   
  15. // Billboards are rendered...  
  16.   
  17. // DepthBias work around  
  18. if ( m_bDepthBiasCap ) // TRUE, if DepthBias supported  
  19. {   
  20.     // Used to determine how much bias can be applied  
  21.     // to co-planar primitives to reduce z fighting  
  22.     // bias = (max * D3DRS_SLOPESCALEDEPTHBIAS) + D3DRS_DEPTHBIAS,  
  23.     // where max is the maximum depth slope of the triangle being rendered.  
  24.     m_pd3dDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, F2DW(g_fSlopeScaleDepthBias));  
  25.     m_pd3dDevice->SetRenderState(D3DRS_DEPTHBIAS, F2DW(g_fDepthBias));  
  26. }  
  27.   
  28. // Posters are rendered...  
  29.   
  30. if ( m_bDepthBiasCap ) // TRUE, if DepthBias supported  
  31. {   
  32.     // DepthBias work around  
  33.     // set it back to zero (default)  
  34.     m_pd3dDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, F2DW(g_fDefaultDepthBias));  
  35.     m_pd3dDevice->SetRenderState(D3DRS_DEPTHBIAS, F2DW(g_fDefaultDepthBias));  
  36. }  
  37.   
  38. . . .  
  39.   
  40.               


 

5,這里還有一篇文章教到怎么樣在面上畫出線的,相信你也會遇到同樣的問題。當然,核心還是用depth-bias,但是,人家把怎么做和做的時候要注意的問題都寫上了(主要就是用bias的時候值不要取的太大,否則線框是渲染出來了,但是也同時多出線來了,因為本來是該本剪切的,經過修正可能就不被剪切了)。值得一看。

 

http://www.catalinzima.com/samples/12-months-12-samples-2008/drawing-wireframes-without-z-fighting/

 

背景原理:


z-fighting的出現是的不同面上的像素在z-buffer中的值相近,導致前台取像素的時候一會去這個面的,一會取那個面的。改變照相機的near、far屬性會涉及到z-buffer中的值的精度。因為在各個平台上z-buffer位數不同,因此改變near和far能給z-buffer中的值的浮點數部分盡量留出空間,消除z-fighting。

 

這個是wiki上的z-fighting的例子,可以看到不同色彩的面,因為z-buffer的精度設置的小,然后兩個面放置的比較近,因此出現了相關的穿插顯示的問題。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM