• Shadow Acne问题


    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值来处理该问题。只要比较小心得设置它的值,就可以得到皆大欢喜的结果。

  • 相关阅读:
    将vue文件script代码抽取到单独的js文件
    git pull 提示错误:Your local changes to the following files would be overwritten by merge
    vue和uniapp 配置项目基础路径
    XAMPP Access forbidden! Access to the requested directory is only available from the local network.
    postman与newman集成
    postman生成代码段
    Curl命令
    POST方法的Content-type类型
    Selenium Grid 并行的Web测试
    pytorch转ONNX以及TnesorRT的坑
  • 原文地址:https://www.cnblogs.com/wickedpriest/p/12926299.html
Copyright © 2020-2023  润新知