4.3 实时阴影

news2024/11/15 8:54:34

一、基于图像的阴影技术(Shadow Map)

什么是阴影

当来自光源的至少一个点在空间中被遮挡时,就产生了阴影区域。

阴影的前提

  • 直接光照
  • 不透明物体

阴影的实现方式

阴影体(Shadow Volumes)——空间中黑暗部分的几何

阴影映射(Shadow Map)——在场景中没有背光源找到的地方

阴影映射(Shadow Map)

绿色的点没有阴影。

红色点在摄像机视角看是在阴影里,但在光源的视角看在盒子后面,不代表一定在阴影中(例如多光源情况)。

深度比较

相机视角渲染的深度图与光照视角渲染的深度图进行比较。

阴影映射-问题

  • 低分辨率的阴影映射会导致有锯齿的阴影。
  • 当比较深度时,为了避免表面自阴影,需要设置容错阈值(深度偏移)。

二、基于图像的阴影技术的优化

深度偏移(Depth Bias)

传统Shadow Map因为自阴影出现的问题——阴影失真(Shadow Acne)

红色斜着的区域对应了ShadowMap上每块片段(像素)的位置,因为阴影贴图受限于分辨率,在距离光源比较远的情况下,多个片段可能从ShadowMap的同一个值中去采样。图片每个斜坡代表ShadowMap一个单独的纹理像素。你可以看到,多个片段从同一个深度值进行采样。有些在地板上面,有些在地板下面;在和屏幕空间深度做比较的时候就会出现误差,这样我们所得到的阴影就有了差异。

我们可以用一个叫做阴影偏移(shadow bias)的技巧来解决这个问题,我们简单的对表面的深度(或深度贴图)应用一个偏移量,这样片段就不会被错误地认为在表面之下了。

举个栗子:

这四个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暗,他们本来应该都是亮的才对。然后整个光源视椎体下各个片段都会出现这个问题,就会出现上面的明暗交错的条纹。








 

如果Bias值过大也会导致一个问题——悬浮

Unity中的自阴影优化

与OpenGL优化原理差不多。

阴影映射的走样

人们期望,正常情况下Shadow Map上的像素可以对应上屏幕空间的像素,这种情况仅在目标Light垂直于目标物体(平面)时才会出现,但通常并不会满足上述条件。

因此人们开始针对此类问题进行优化,主要优化点如下:

  • 初始采样(渲染阴影映射)
  • 重采样:从摄像机视角对采样信号(阴影映射)重采样
  • 重建:使用滤波函数(例如PCF)

主要误差类型

解决方案:

  • 初始采样——透视走样
  • 光空间透视阴影映射 (LiSPSM)
  • Z分割(级联阴影映射)
  • 视口采样映射

小结

  • 只能使用一张阴影映射时,LiSPSM是最好的选择,尤其是户外顶部光照
  • 允许多张阴影映射时,最好的方案是Z分割(CSM等)
  • 自分割可以同时处理透视与投影走样,RMSM与现值虚拟纹理的方案很类似,支持虚拟纹理的引擎很容易实现
  • 无走样方案可以达到像素级别的精度,应该会是未来的趋势

硬阴影的滤波

  • 主要用于减少重采样的误差(使用阴影映射进行渲染时产生)
  • 滤波
    • 图像处理中可以通过滤波强调一些特征或者去除图像中一些不需要的部分
    • 滤波是一个邻域操作算子,利用给定像素周围的像素的值决定此像素的最终的输出值
    • 任何使用一部分阴影映射采样点来计算某个指定View采样点的最终阴影结果的方法
PCF(Pencentage close Filtering)滤波

  • 可以模糊来隐藏欠采样的瑕疵;
  • 得到类似软阴影的效果,不少游戏引擎称之为“软阴影”;
  • 一个重要缺陷是较大的滤波核会导致更多采样点的计算,性能消耗大;
  • 无法进行预计算,因为滤波依赖于
  • PCF 虽然能对阴影进行平滑模糊,但毕竟无法模拟基于物理的软阴影, PCSS(Percentage Closer Soft Shadows)能够设置变化的滤波核来改进这一点。

三、基于图片的软阴影算法

流程:

1.查找遮挡体

2.半影宽度的计算

Wpenumbra=P sz- Zavg / Zavg * Wlight

Wlight为光源的大小

3.滤波

Wf = Znear / PSZ *Wpernumbra

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1243398.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【办公常识_1】写好的代码如何上传?使用svn commit

首先找到对应的目录 找到文件之后点击SVN Commit

1688API如何获取商品详情信息(关键词搜索商品列表),1688API接口开发系列

1688商品详情接口是指1688平台提供的API接口&#xff0c;用于获取商品详情信息。通过该接口&#xff0c;您可以获取到商品的详细信息&#xff0c;包括商品标题、价格、库存、描述、图片等。 要使用1688商品详情接口&#xff0c;您需要先申请1688的API权限&#xff0c;并获取ac…

Harmony Ble蓝牙App(二)连接与发现服务

Ble蓝牙App&#xff08;二&#xff09;连接与发现服务 前言正文一、BlePeripheral回调二、连接和断连三、连接状态回调四、发现服务五、服务提供者六、显示服务七、源码 前言 在上一篇中我们进行扫描设备的处理&#xff0c;本文中进行连接和发现服务的数据处理&#xff0c;运行…

多线程,线程池,线程的创建,线程池的参数

文章目录 多线程-1 高并发〇、使用多线程的场景1. 为什么使用多线程 1. 线程概述1.1 线程和进程1.2 并发和并行1.3 多线程的优势1.4 程序运行原理1.5 主线程 1.6 线程的 6 种状态2. 线程的创建和启动2.1 Thread类2.2创建线程有哪几种方法2.2.1 继承**Thread**类&#xff0c;重写…

一、用户管理

一、后端数据库初始化 1.1 因为版本问题&#xff0c;始终报错&#xff0c;按照报错信息去查询解决方案&#xff0c;无法解决 灵机一动&#xff1a; 网址&#xff1a; Spring Boot 3.0 升级 实战踩坑记录 - 掘金 (juejin.cn) &#xff11;.&#xff12; 个人配置【运行成功…

1、基础入门——操作系统文件下载反弹SHELL防火墙绕过

名词解释 POC&#xff1a;验证漏洞存在的代码&#xff1b; EXP&#xff1a;利用漏洞的代码&#xff1b; payload&#xff1a;漏洞利用载荷&#xff0c; shellcode&#xff1a;漏洞代码&#xff0c; webshell&#xff1a;特指网站后门&#xff1b; 木马&#xff1a;强调控制…

注意:怎么用JMeter操作MySQL数据库?看完秒懂!

近期用JMeter做接口测试&#xff0c;遇到了一个需要用到数据数据库的场景&#xff1a;一个关于数据报告的页面&#xff0c;需要将数据库里面的数据求和或者取均值之后&#xff0c;展示出来。 如果要断言的话&#xff0c;需要连接数据库&#xff0c;通过写sql语句&#xff0c;将…

OpenLayers实战,WebGL图层如何使用一张拼接合成图片根据坐标切片成单个图片进行渲染

专栏目录: OpenLayers实战进阶专栏目录 前言 本章主要讲解OpenLayers使用WebGL图层的情况下,如何使用一张拼接合成图片根据坐标切片成单个图片进行渲染不同图片到地图上的功能。 为方便讲解原理,本章使用的一张图片是按照横向4等分,纵向两等分规则拼接了6个图标的合成图片…

【分布式】分布式事务及其解决方案

目录 一、分布式事务二、分布式事务的解决方案1. 全局事务&#xff08;1&#xff09;DTP模型&#xff08;2&#xff09; 两阶段提交协议&#xff08;2PC&#xff09;原理二阶段提交的缺点 &#xff08;3&#xff09;三阶段提交协议&#xff08;3PC&#xff09;原理 2. 基于可靠…

Typescript 的 class 类

介绍 1. 类介绍 传统的JavaScript通过函数和基于原型的继承来创建可重用的组件&#xff0c;从ES6开始&#xff0c;JavaScript程序员也可以使用面向对象的方法来创建对象。例如&#xff0c;下列通过class关键词&#xff0c;来声明了一个类&#xff1a;Greeter class Greeter …

shell 脚本 批量 修改 文件名

shell 脚本 批量 修改 文件名 原始文件 你可以使用以下的shell脚本来批量修改文件名&#xff1a; #!/bin/bashinput_dir$1if [ -z "$input_dir" ]; thenecho "Usage: ./rename.sh input_directory"exit 1 ficd "$input_dir" || exitfor file in…

C百题--6.输出C

1.问题描述 输出“C”样式的字符 2.解决思路 1.用printf(&#xff09;逐行输出&#xff1b; 2用循环一部分一部分输出 3.代码实现 #include<stdio.h> int main(){for(int i0;i<5;i){printf("*"); }printf("\n");for(int i0;i<2;i){printf…

【保姆级教程】协同双注意力机制CDAM2与YOLOv7结合:构建高效工地头盔检测系统

1.研究的背景和意义 随着工业化和城市化的快速发展&#xff0c;建筑工地的安全问题日益凸显。在建筑工地中&#xff0c;工人的安全是至关重要的&#xff0c;而工地安全帽的佩戴是保障工人安全的重要措施之一。然而&#xff0c;由于工地环境复杂多变&#xff0c;工人的佩戴情况…

OpenStack云计算平台-启动一个实例

目录 一、创建虚拟网络 ​二、创建m1.nano规格的主机 三、生成一个键值对 四、增加安全组规则 ​五、启动一个实例 1、确定实例选项 2、创建实例 3、使用虚拟控制台访问实例 4、验证能否远程访问实例 一、创建虚拟网络 下面的说明和框图使用示例IP 地址范围。你必须依…

[Linux] shell脚本的函数和数组

一、函数 1.1 函数的定义 函数是脚本的别名 作用&#xff1a;函数可以避免代码重复&#xff0c;可读性强&#xff0c;可以简化脚本。 格式&#xff1a;函数名&#xff08;&#xff09;{脚本} 1.2 如何使用函数 1.定义 2.调用 函数一定要先定义再使用 例子&#xff1a…

Linux 的性能调优的思路

Linux操作系统是一个开源产品&#xff0c;也是一个开源软件的实践和应用平台&#xff0c;在这个平台下有无数的开源软件支撑&#xff0c;我们常见的apache、tomcat、mysql等。 开源软件的最大理念是自由、开放&#xff0c;那么Linux作为一个开源平台&#xff0c;最终要实现的是…

为企业解决设备全生命周期需求,凌雄科技凸显DaaS增长价值

企业成长离不开投资&#xff0c;但毫无疑问的是&#xff0c;投资最有价值的部分在业务。相比之下&#xff0c;诸如办公设备之类的固定资产投资&#xff0c;很容易变成企业现金流的吞噬者。从购买、运维到保养、折旧、回收&#xff0c;现代企业在越来越大的办公设备规模面前&…

通过Whisper模型将YouTube播放列表中的视频转换成高质量文字稿的项目

项目简介 一个通过Whisper模型将YouTube播放列表中的视频转换成高质量文字稿的项目。 这个基于 Python 的工具旨在将 YouTube 视频和播放列表转录为文本。它集成了多种技术&#xff0c;例如用于转录的 Fast-Whisper、用于自然语言处理的 SpaCy 以及用于 GPU 加速的 CUDA&…

机器学习实战-第5章 Logistic回归

Logistic 回归 概述 Logistic 回归 或者叫逻辑回归 虽然名字有回归,但是它是用来做分类的。其主要思想是: 根据现有数据对分类边界线(Decision Boundary)建立回归公式,以此进行分类。 须知概念 Sigmoid 函数 回归 概念 假设现在有一些数据点,我们用一条直线对这些点进行…

Redis深入理解-内核请求处理流程、数据传输协议

Redis 内核级请求处理流程 Redis Server 其实就是 Linux 服务器中的一个进程 主要还是下图的流程 应用先和 server 端建立 TCP 连接建立连接之后&#xff0c;server 端就会有一个与该客户端通信的 socket&#xff0c;客户端的读写请求发送到服务端的 socket那么通过 IO 多路…