zoukankan      html  css  js  c++  java
  • 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的精度设置的小,然后两个面放置的比较近,因此出现了相关的穿插显示的问题。

  • 相关阅读:
    window上部署Flask
    PIP超时
    覆盖内敛样式
    解决js导出csv中文乱码
    没有为请求的 URL 配置默认文档,并且没有在服务器上启用目录浏览。
    nuget加载本地包
    DataTable表头对不齐、添加参数等方法总结
    根据class判断
    element-ui的table动态生成表头和数据,且表中数据可编辑
    VScode快捷键、Chrome快捷键知识小总结和状态码
  • 原文地址:https://www.cnblogs.com/czaoth/p/5830725.html
Copyright © 2011-2022 走看看