码迷,mamicode.com
首页 > 其他好文 > 详细

Shadow Acne问题

时间:2020-05-20 21:41:57      阅读:93      评论:0      收藏:0      [点我收藏+]

标签:场景   现象   渲染   黄色   读取   阴影   问题解决   采样   normal   

ShadowMap是实时渲染中实现阴影效果一种常用的方法,它的基本思路是创建一个光源视角下的深度图;然后在渲染时,将渲染frag的深度和深度图对应的深度进行比较,若frag的深度比深度图的深度值大,则说明它是在阴影下的(有一个物体在它前面遮挡了光线),否则不需要渲染阴影。
但是在实际的实现中,会有一个问题,如下图所示:
技术图片
仔细看上图的地板和方体,可以看到条纹装的阴影,拉近镜头的话如下所示:
技术图片
该现象被称作Shadow Acne。其实原因也是不难理解。因为我们创建的深度图终究是离散的数值,对深度图采样只能得到该像素下某一个点的深度值,但实际上同一个像素不同位置的深度值也是有很大差别的,如下图所示:
技术图片
图中黄色的一个像素,在渲染时只能将中间的深度值作为该像素的深度值。但在实际渲染场景的时候,像素其他位置的深度值可能会高于或低于深度图存储的值,就会出现这种一部分在阴影中,一部分没有阴影的效果。
那么该如何解决这类问题呢?最简单的做法是为深度图中读取出的深度图加上一个bias,保证该像素内所包含的frag的深度均位于其下,这样就将该问题解决了。
我们还可以设置bias的值根据光线和物体本身的normal动态变化:

float bias = max(0.05 * (1.0 - dot(normal, lightDir)), 0.005);

但是利用该方法也有一个缺点,那就是利用bias有可能会导致阴影的偏移,如下图所示:
技术图片
尤其是在bias的值选的过大时,该现象更加明显。
其实,想彻底解决该问题只需要一个小小的改动就可以:在渲染深度图时只渲染背面。这样一来,假设该物体实际上被某物体遮挡,那么它的深度值必然高于遮挡物体背面的深度值。反之,假设该物体没有被遮挡,那么它的深度值必然小于它背面的深度值:
技术图片
这种方法被称作Peter panning。
当然,该方法也是有自己的问题的:就是它只能处理闭合的模型(比如长方体),对于只有一个面的模型(比如长方形)就无法渲染它的背面了。这就要求在制作模型的时候就要制作闭合的模型。
当然,实际上大部分还是用的bias值来处理该问题。只要比较小心得设置它的值,就可以得到皆大欢喜的结果。

Shadow Acne问题

标签:场景   现象   渲染   黄色   读取   阴影   问题解决   采样   normal   

原文地址:https://www.cnblogs.com/wickedpriest/p/12926299.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!