shadow acne(阴影失真)和peter panning(阴影悬浮)

原文链接:https://blog.csdn.net/lawest/article/details/106364935

 

总结下来就是:

因为深度贴图的分辨率有限,导致多个像素点采样1个深度,导致阴影失真(acne)

1个解决方法是添加bias,也就是给像素的z加上偏移,这个方法会导致阴影悬浮(peter panning)

最好的解决阴影失真的方法是cull font,只渲背面的深度

可参考:https://zhuanlan.zhihu.com/p/45653702

---------------------

在之前学习阴影映射时看的是这篇文章https://learnopengl-cn.github.io/05 Advanced Lighting/03 Shadows/01 Shadow Mapping/。

但是里面有两个点当时是云里雾里,现在重新学习如何实现柔和边缘阴影时有又遇到些问题,就是在阴影映射是出现的shadow acne(阴影失真)和peter panning(阴影悬浮),

阴影失真如图:

出现这个问题的原因原文根本就没讲清楚,给出的图和解释也十分误导人,而且给出的解决方法也十分含糊,当时看的的怀疑人生,怀疑自己的智商,在终于搞懂之后我那个气啊,当时就把桌子给掀了。

会出现阴影失真的根本原因是所生成的深度贴图的分辨率是有限的,就会造成在fragment位置处取深度图中的值发生采样就会出现问题,这里我引用知乎用户王十一的回答用的图(懒得自己画)。如图:以四个格子为四个fragment为例,由于深度图分辨率有限四个格子会采样同一个深度值(由于纹理参数设置的是临近GL_NEAREST,设置线性也会有这个问题)。

preview

如图假设采样这个四方格的正中心,假设这个深度值为10。

preview

这四个fragment分别取名a,b,c,d,由于光源的位置会导致求得的四个距离会不一样,先求a到光源的距离假设为9.8<10,b到光源的距离是11.6 >10,c到光源的距离12.1>10,c到光源的距离9.5<10,。就会导致a和d亮,b和c暗,他们本来应该都是亮的才对。然后整个光源视椎体下各个片段都会出现这个问题,就会出现上面的明暗交错的条纹。

preview

 

原文说的解决方法是将fragment到光源的距离适当的缩小bias,就会避免这个问题,但是这种解决方法会带来另外一个问题,那就是peter panning(阴影悬浮),bias越大悬浮的越厉害。

如果解决一个问题的方法会带来另外一个问题我们为什么要用呢?

   glCullFace(GL_FRONT);
使用正面剔除来生成深度贴图可以解决正面的阴影失真,也就是说只有物体背面才会产生深度信息,向地板这种只有一个面的物体不会产生深度信息,这也是合理的,但是这也只能在封闭的物体上这么做,但是即使这样物体的背面还是会出现阴影失真,这时候可以用glPolygonOffset来解决这个问题,将深度图中的值稍微减小一点而不是片段到光源的距离,两者结合就可以解决这个问题。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章