【计算机图形学/实时渲染】 阴影(GAMES202)

2023-05-16

阴影

对于静态的物体,可以使用Lightmap烘焙的方法来获取物体的影子(静态阴影),而对于动态的物体,一般采用的是Shadowmap的技术。

光照贴图(Lightmap)

(1)原理:从光源的方向去烘培(离线渲染)一个物体,把结果存一张贴图里,因为离线渲染的时候,如果光线和物体之间有东西被遮挡,那么物体上该点处就会存在阴影,那么在Lightmap上就是一个阴影的值(较暗的像素)**,**然后渲染的时候直接对该物体从光照贴图里面采样即可

(2)缺点:Lightmap只能存diffuse分量(漫反射),不能存specular分量(镜面反射),且没办法做动态阴影,只适用于固定在场景中的静态物体。

优点:使用lightmap的物体不参与实时光照计算,减少了大量的开销。

阴影贴图(Shadowmap)

基本原理:该技术其实是一种渲染到纹理的技术,我们得到的这张贴图一般称作阴影贴图。Shadowmap的原理非常简单,首先是从光源的位置(视角)渲染一遍场景,将得到的深度信息写入到贴图中,然后再一次正常的渲染场景,利用我们得到的shadowmap来判断哪些着色点落在了阴影中(确定visibility)。当场景发生变化时,每一帧都需要生成一遍ShadowMap

a. Self occlusion(自遮挡):

在这里插入图片描述

一个像素对应的实际场景中的点可能有多个,只会记录最近的深度值,而其他点并未被遮挡,只是因为共用一个像素变成了阴影。shadowmap记录的深度值是离散的不是连续的。

光源与地面的夹角越小,越接近grazing angle(掠射角)的时候此问题越严重

可以通过偏移技术来解决,增加一个bias来比较片段深度,在bias之内的不判定遮挡。

使用这种方法可能会导致出现detached shadow(不接触阴影),本来应该遮挡的物体没有被计算

还有更好的一种方式是使用一种自适应偏移的方案,基于斜率去计算当前深度要加的bias;

Second-depth shadow mapping

同时记录最小的第二小的深度

SM中记录两个深度的平均值

b. Aliasing 阴影锯齿

原因是阴影贴图的分辨率低,在对阴影贴图采样时,多个不同的顶点对同一个像素采样,导致生成锯齿。

1.百分比渐进过滤(Percentage Closer Filter,PCF)技术

:从深度贴图中多次采样,每次采样坐标都稍有些不同,比如上下左右各取9个点进行采样(即一个九宫格),最后加权平均处理,就可以得到柔和的阴影。标准PCF算法采样点的位置比较规则,最后呈现的阴影还是会看出一块一块的Pattern(图块),可以采用一些随机的样本位置,比如Poisson Disk来改善PCF的效果。后面会详细阐述该方法的过程

2.级联阴影贴图(CSM):

使用多张阴影贴图,离相机近的地方使用精细的阴影贴图,离相机远的地方使用粗糙的阴影贴图,这样不仅优化了阴影效果,还保证了渲染效率

使用 Parallel-Split Shadow Maps(PSSM) 平行分片阴影贴图法,

将视锥体切割成不同和投影平面平行的深度层,并为每个深度层都生成阴影贴图,如下图所示。原理是物体距离不同,阴影贴图的采样密度也不同。生成不同的阴影贴图可以提高采样频率从而减少走样问题

c. 采样Shadowmap的时候,需要将标准设备坐标系的坐标范围由[-1,1]修正到[0,1],否则贴图的坐标范围是[0,1],会采样错误。

Percentage Closer Soft Shadows (PCSS)

先详细介绍
Percentage Closer Filter(PCF)

本身是为了抗锯齿用的,后来发现PCF还可以用来生成软阴影。

在记录深度的时候进行。not filtering the shadow map

一个着色点对应了SM上的一个像素(在该像素的内部),现在我们取

取SM上周围的NxN个像素获得深度,进行NxN次深度比较(用该着色点的深度和这NxN个SM上记录的深度值比较,如果可见就为1,不可见就为0),获得比较结果NxN的矩阵(9个非0即1的值),最后做平均得到该像素的visibility,比如0.667,再代入到实时渲染的渲染方程中进行计算。

渲染方程如下:
在这里插入图片描述

当Filtering Size越大,阴影就会越软。

PCSS的做法是,在不同位置使用不同大小的Filter,因为阴影接受物距离阴影投射物越近,阴影就越硬,距离越远就越软(因为存在半影区),见下图:
在这里插入图片描述
在这里插入图片描述

而深度图记录的就是d(Blocker),光源到投射物的距离.

此时深度图正是用点光源代替实际的面光源生成的shadow map

一个着色点连向点光源(面光源中心),取得一定区域内多个blocker的平均距离,即该着色点对应的shadow map上的像素周围的若干像素(NxN)矩阵的平均值

这里取得范围可以根据着色点连接面光源在shadow map上的“投影”大小,具体可以看下面的图:
在这里插入图片描述
然后使用这个平均值来设置合适的Filtering Size进行PCF的操作

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【计算机图形学/实时渲染】 阴影(GAMES202) 的相关文章

  • AprilTag的使用、相关问题及解决方法

    使用棋盘格标定相机 安装标定功能包 span class token function sudo span span class token function apt get span span class token function i
  • 对接海康综合安防管理平台经验总结

    前言 xff1a 因业务需要对接海康威视的综合安防管理平台获得下属所管理的摄像头 xff0c 根据摄像头code获得监控视频流信息 1 详情可以浏览海康开放平台 xff0c 在官网上有对应的接入指南以及开放的API接口 前提是本地已部署了海
  • 【环境配置】Visual Studio opencv配置

    需求 在Visual Studio环境中编写C 43 43 代码 xff0c 同时可以调用OpenCV的相关代码 1 安装OpenCV 访问 opencv 官网下载对应平台的库文件 注意 xff1a Visual Studio和OpenCV
  • MySQL常见用法

    文章目录 一 时间类1 1 DATE SUB 函数1 2 NOW CURDATE CURTIME DATE 函数1 3 实战 二 统计类三 字符类3 1 LOCATE 函数3 2 concat 函数3 3 concat ws 函数3 4 g
  • 牢记公式,ardupilot EKF2就是纸老虎(四)!

    版权声明 xff1a 本文为博主原创文章 xff0c 转载请附上博文链接 xff01 四 一睹EKF2芳容 因为篇幅过长 xff0c 写的一些公式会乱码 xff0c 没办法只能把 牢记公式 xff0c ardupilot EKF2就是纸老虎
  • Java Optional使用

    文章目录 Optional一 Optional 简介二 创建 Optional 实例2 1 empty 方法2 2 of 方法2 3 ofNullable 方法 三 Optional的使用3 1 访问 Optional 对象的值3 1 1
  • 正则表达式:基础详解以及在Java中的使用

    文章目录 一 正则表达式1 1 正则表达式中的特殊字符1 2 正则表达式所支持的合法字符1 3 方括号表达式1 4 边界匹配符1 5 三种模式的数量表示符 二 应用2 1 String 类2 2 Pattern 类和 Matcher 类 一
  • Python学习:关键字global和nonlocal的用法说明

    一 global global关键字用来在函数或其他局部作用域中使用全局变量 1 1 如果局部要对全局变量修改 xff0c 而不使用global关键字 count 61 0 def global test count 43 61 1 pri
  • Python:flask框架下前后端的数据交互

    文章目录 前提 一 前端发送数据 xff0c 后端接受数据1 1 路由传参数 数据 1 2 表单提交 二 后端发送数据 xff0c 前端接受数据 前提 后端 xff1a python 的 flask 框架 前端 xff1a html css
  • Python关于None的报错:'NoneType' object is not iterable和cannot unpack non-iterable NoneType object

    文章目录 一 TypeError 39 NoneType 39 object is not iterable xff08 类型错误 xff1a 39 NoneType 39 对象不是可迭代的 xff09 二 TypeError cannot
  • Git:合并分支----git merge命令应用的三种情景

    文章目录 一 git merge 命令应用的三种情景1 1 快进 无冲突 1 2 非 快进 xff0c 修改不同文件 无冲突 1 3 非 快进 xff0c 修改相同文件 有冲突 一 git merge 命令应用的三种情景 1 1 快进 无冲
  • Git:远程分支----git fetch命令的使用

    git fetch 命令的使用 从远程主机克隆 Git 的 clone 命令会为你自动将远程主机命名为 origin xff0c 拉取它的所有数据 xff0c 创建一个指向它的 master 分支的指针 xff0c 并且在本地将其命名为 o
  • Git:移除文件----git rm命令的使用

    文章目录 一 git rm 命令使用1 1 rm 命令1 2 git rm 命令1 3 git rm f 命令1 4 git rm cached 命令 一 git rm 命令使用 Git 本地数据管理 xff0c 大概可以分为三个区 xff
  • 【OpenMv小车】OpenMv追小球的小车之pid调用

    pid py gt gt https github com wagnerc4 flight controller blob master pid py openmv 官网 xff1a http book openmv cc project
  • 【深入理解C++】函数模板作为成员函数

    文章目录 1 普通类的成员函数模板2 类模板的成员函数模板 1 普通类的成员函数模板 不管是普通类还是类模板 xff0c 它们的成员函数都可以是函数模板 xff0c 称为成员函数模板 xff0c 但不可以是虚函数 xff0c 否则编译器报错
  • QGroundControl开发之使用自定义mavlink

    工具 对QGC进行二次开发时 xff0c 常常会遇到想使用自定义mavlink的情况 xff0c 但不像APM那样编译命令会根据xml文件自动生成mavlink协议 QGC似乎不能自动生成mavlink协议 xff08 之前试过似乎不能自动
  • 字符串连接 (c语言)

    题目描述 将给定的字符串连接起来 书中的算法描述如下 xff1a 图 xff1a 字符串连接算法 输入描述 三对字符串 xff0c 每对字符串占一行 xff0c 用空格隔开 每个字符串只包含数字和英文字母大小写且长度不超过100 输出描述
  • STM32—UART中断收发 Day4

    软件 xff1a STM32CubeMX xff0c MDK ARM 硬件 xff1a 蓝桥杯物联网Lora开发板 xff0c 板载芯片STM32L071 一 STM32CubeMX配置 1 先在连接 xff08 Connectivity
  • 虚拟机出现command XXX is available in /bin/ls问题

    问题 xff1a 使用本地的shell命令时候 The command could not be located because 39 usr bin bin 39 is not included in the PATH environme
  • 全志lichee的pack命令

    全志lichee目录打包命令流程 pack 将打包命令传进去build sh脚本里面 查看buildsh里面的脚本命令 其实里面的脚本还是较为简单地的 xff0c 仅仅是作为一个过渡 xff0c 然后就跑进去buildroot script

随机推荐