Shadow Maps 中 Back-face Culling的解决办法

法一:

对paulsprojects教程有效

http://emreburhan.com/blog/?p=9


Back-face Culling and Shadow Maps


Shadows has remained as a big challenge for years in computer graphics. There are many ways to achieve “shadows”, some methods require special data structures and coding, and some has quality and speed falloffs.
Shadow mapping is one of methods been used by now, presenting relatively easy implementation and reasonable speed, at cost of aliasing effect for shadows far from the camera, a shadow texture to hold information for each point light (more for soft shadows) and big sized shadow map texture memory space requirement.
For more information:
http://en.wikipedia.org/wiki/Shadow_mapping
http://www.paulsprojects.net/tutorials/smt/smt.html

Back-face Culling
Back-face culling is the process of discarding polygons that are not facing towards the camera where the image is taken from. So often used in 3D video games, the process allows rendering of scene much faster by eliminating the calculation of back-facing polygons-those eventually will be covered by another front-facing polygons. To get a better understanding, one can imagine a box, having all the 6 faces facing outer from the cube, that means the top face will orient towards above the cube, and bottom face will orient below. So, any camera that is in the outer space of the cube will see the all 6 faces, but a camera in the cube will not see any.

Back-face Culling and Shadow Maps
In general purpose 3D drawing software and CAD applications, it is often impossible to determine the correct orientation of faces. Any single face in 3D space may be clock-wise or counter clock-wise, constructing a outer face of an entity or should be just a plane with both sides visible, depending on the whole drawing. So, all faces in CAD applications are simply rendered without back-face culling, remaining both sides visible.
On the other hand, shadowing with shadow map method requires back-face culling turned on, makes it impossible to use with CAD applications. After searching everywhere to find a way to make shadow mapping work while back-face culling is off, I haven’t came to any solution. Then I have decided to play a bit and finally made it! So here it is.

The Sample
I will be using a very good, yet simple to understand sample project, developed by Paul Baker. You can find his tutorial at http://www.paulsprojects.net/tutorials/smt/smt.html.
Load the project into Microsoft Visual Studio and run. Then open the file main.cpp and locate glEnable(GL_CULL_FACE); in function bool Init(void) on line 70 and replace it with glEnable(GL_CULL_FACE); and run again. When back-face culling disabled, you will see there is disturbing Z-fight effect, due to multi pass rendering required for shadow maps (Three passes actually, in this example).

The fix
This time, comment out glEnable(GL_CULL_FACE); and after that, insert:

//注释掉glEnable(GL_CULL_FACE);使用以下代替


glDisable(GL_CULL_FACE);
glPolygonOffset(1.0, 1.0);
glEnable(GL_POLYGON_OFFSET_FILL);

Polygon Offset
Polygon offset is useful when you face coplanar faces, ie: faces on the same exact location and depth to the camera. If such coplanar faces are fed to OpenGL pipeline for drawing, you will see the disturbing z-fight effect, random colors from both faces, as in the image at the top line of this post. The reason of the z-fight effect in the previous example is that the lit and dark areas both are the same distance to the camera, having the same depth values causing the trouble. Polygon offset comes for help:
Polygon offset does not only correct z-fight effects but can also be used for highlighting the edges of a solid object and create some other effects. For more information on polygon offset, refer to:http://www.opengl.org/resources/faq/technical/polygonoffset.htm

法二:

网上摘抄的,貌似无效

在paulsprojects的Shadow Mapping原程序上的改动:    

把glEnable (GL_CULL_FACE)换成glEnable (GL_POLYGON_FILL),

glCullFace(GL_FRONT)换成glPolygonOffset(1.0,1.0),

glCullFace(GL_BACK)换成glPolygonOffset(0.0,0.0),           目的是为了在绘制立方体的时候避免某些免被CULL掉)。

Shadows should be rendering correct again.

法三:

从cookbook上摘抄的方法,有效

第一遍绘制时:

    glEnable(GL_CULL_FACE);
    glCullFace(GL_FRONT);
    glEnable(GL_POLYGON_OFFSET_FILL);
    glPolygonOffset(2.5f,10.0f);
 
    drawScene();


    glCullFace(GL_BACK);
    glDisable(GL_POLYGON_OFFSET_FILL);

第二遍绘制时:

    glDisable(GL_CULL_FACE);

    drawScene();

不用再在对CULL_FACE做其他操作,以上包括了所有CULL_FACE相关的操作
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值