图形学 总结 - 老是忘

渲染流水线:

1、首先相机摆放到场景一个位置和角度,场景的各个物体也已经被摆放好

2、拿到场景物体的顶点信息,根据顶点信息构成图元

3、经过透视投影,将图元转化为2*2的正方形,再把2*2的正方形扩展到屏幕大小

4、对图元进行采样,仅采样会导致抗锯齿,所以这里做MSAA

对图片进行模糊再采样,然后将一个像素也模拟成n*n个虚拟像素,观察图元内包含的虚拟像素来决定颜色的深度,然后再做平均(卷积)

5、经过Z-Buffer,进行深度测试,处理Z通道中的遮挡关系

6、对最后的图元中的像素信息进行着色,shader着色(考虑环境光、漫反射光、强光影响),将RGB颜色画在各个像素上完成渲染管线生成最后的屏幕图片

在Games101中,提到过的抗锯齿方法在UE5里面是都有的:


Ray Traced:

简单来说就是屏幕中各个像素的位置射出一条射线进行反向追踪,计算各种因素的光照信息

如图,经过反射光,折射光从而把这些光线亮度累加在一起,就是这个像素最终亮度的值

但是只是做每个像素的反射和折射计算累加会消耗很多性能,这里采用了包围盒的概念来提速,如果射线连包围盒都没有进入,那么他是不会和包围盒内的物体有反射或者折射效果的,如果光线进入了包围盒,再来计算其是否与包围盒内的物体有进行反射或者折射

再进行优化,就是对场景空间分成很多个立方体的包围盒,一个包围盒又可以细化为多个子集的包围盒,以此类推变成树状结构,光线先射进大的包围盒中,看是否包围盒内有物体,若有,则对大包围盒细化为小的包围盒,看小的包围盒内是否也有光线射中的物体,以此去判断,具体的方法就是Oct-Tree KD-Tree BSP-Tree


Shadow:

在光源位置生成一张深度图,再从相机视角出发,观察到的位置深度比光源处生成的深度图深度大,则该位置存在阴影,反之则没有阴影
上面实现的事硬阴影,如何实现软阴影?(Soft Shadow)

PCSS(Percentage Closer Soft Shadow)

在摄像机看到的像素对周围做N * N的卷积,在最外侧的阴影则会和没有阴影的一起做平均,则产生了软阴影,N值越大,性能消耗越高,软阴影效果越明显

VSSM(Variance Soft Shadow Mapping)

对最开始的阴影生成一张深度图,再对这个深度图做平方再存放起来,然后做以下公式

用二维前缀和计算出大概的期望,用这个期望值来代表该像素的阴影数值,X为Depth数值

这个方法以显存换性能

由于PCSS的第一步和第三步都是n平方的操作,所以性能不达标,所以就有VSSM的操作

1、计算灯光位置对场景的一个深度采样

2、计算一个深度的平均值的平方,和深度平方的平均值来计算方差

3、通过概率论可以计算出任意一个深度值在第一部的深度采样图的概率排名,通过这个排名就可以直接计算出O(1)大概多少是在阴影内的,根据概率就可以算出对应阴影卷积后的平均值

DFSM(Distance Field Shadow Mapping)

已知o是光源,P1是o最近的物体位置,P2是P1最近物体位置,P3是P2最近物体位置,通过距离场:oP1是已知的,P1P2   P2P3是已知的

通过近似的算法直接算出来对应的数值SDF(p)就是P1P2或者P2P3,p-o就是oP1 oP2 oP3这样的值,这样的比例去做近似表达角度大小的数值,角度越大,值越大,阴影越柔软,K值是为了让更多位置大于1,更多位置为硬阴影,k值越大,阴影外轮廓柔度越低,1为最黑的阴影,0~1根据值的大小,线性决定阴影强弱

每个像素,根据求出来的球谐函数的值进行计算

Wavelet对光照的计算

通过Wavelet的各个形状来替换图片上的各个形状

Wavelet不能处理快速旋转的场景,没有Wavelet的图可以快速进行替换,而SH可以对当前这一层的图片进行旋转计算匹配,支持快速旋转的场景

Wavelet不动的时候效果好很多,但是快速旋转不行

所以前向渲染都是通过一个主要光源计算像素

四个次要光源计算顶点

其余光源用球谐函数来计算,依然能达到一个很好的效果

VSM:虚幻用的Virtual Shadow Map

对阴影贴图进行分区

进行分区显示,也做了类似MipMaps的操作,越近,分的区越细腻,阴影贴图展现的精度也越高,如果视口上没有显示的分区,不进行整体渲染,只渲染视口上显示的分区

RSM(Reflective Shadow Map):这个其实不是做阴影的,只是利用贴图计算反射光对场景的贡献

将阴影贴图中,所有的像素都是间接光源,再以间接光源去做阴影贴图,从来达到反射光做出阴影效果

优化:将阴影贴图,离中心位置越近,间接光源越小,离中心位置越远,间接光源越大,并不是取所有的点,而是随机一部分点,从而达到性能优化的效果

LPV(Light Propagation Volumes)

在RSM中,我们通过shadow map找到并定义了一系列虚拟点光源,LPV的第一步仍是如此,在找到虚拟点光源后,考虑整个场景分成的一个个小格子,在对应的小格子中,可以找到其中的虚拟点光源

分成了体素,注入光源,将体素进行前后左右上下进行传播,最后实现了光照的反射的计算

当然LPV也是有缺点的,当体素大小不合理时,我光照明明遮住了,光线并不会传播过去,但是由于LPV不对可视性考虑,所以依然能传到被遮挡的体素上去,变得十分不合理

VXGI(Voxel Global IIIumination)

做成Oct-Tree类似的形式,将被照到的位置的法线信息,和面向光源的方向信息给存储起来

基于追踪出的圆锥面的大小,对格子的层级进行查询,就是对场景中的所有体素都要判断是不是与这个锥形相交,如果相交的话就要把对于这个点的间接光照的贡献算出来


AO(环境光遮蔽)【Ambient Occlusion】:

SSAO(Screen Space Ambient Occlusion)

先在屏幕表面的球形范围内随机生成一系列点,根据深度图,判断这些点深度是否小于深度图深度,再按照比例若小于深度图的点大于一半,则这部分不做AO,若小于一半,则做AO,取其中有绿色点的一半,若四个红色,一个绿色,则该点的暗面程度为1\5,值越小,颜色越黑

SSAO也有一个明显的缺陷,就是凹形的时候可能它没在物体内部,但是仍被认为深度大于深度图,从而造成计算不精准

另外,还有桌子明明没有和地面贴合,但是计算的时候不考虑是否贴合,只考虑球形范围内的点,是否深度小于深度图,来计算该点暗值,AO是贴近的缝之间存在暗面的效果,但SSAO明显这一点没做到

SSDO(Screen Space Directional Occlusion)

SSDO的检测采样做法和SSAO完全一样,如上图所示,在法线方向半球,(这里我们就假设已经知道法线了),撒点,然后根据深度图和投影到Camera的深度的对比来判断是否能对P点产生遮挡。

如果被遮挡,如上图第二幅图所示,根据法线计算它们对P点的贡献之和。其次图1的C点没有被挡到,于是我们可以直接采样环境光的直接光照,也就是说SSDO还提供了一种做环境光照的方法

当然Screen Space都存在一个严重的问题,就是屏幕外的没法渲染,因为只拿到屏幕上有限的内容去做操作,那么假如一个镜子,它朝向一个远方(屏幕上没有的地方),那么远方的内容不会被反射到镜子里面,这是个很严重的问题

以及屏幕上的内容,无法反射出三维信息的内容,从而三维反射不真实的情况,时常发生

SSR(Screen Space Reflection)

用MipMap取2*2深度的最小值,若深度最小值都没达到,则光线不可能会接触到物体表面

若光线到达这个最小值,则找到上一层的MipMap(更精细信息的MipMap),再去观察是否有到达物体表面,打到物体表面就将这一块渲染到反射面上,就达到反射的效果了

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

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

相关文章

修复 error Delete `␍` prettier/prettier 错误

修复 error Delete ␍ prettier/prettier 错误 问题背景报错信息报错原因解决办法修改CRLF----针对单个文件yarn run lint --fix 一键修复(官方提供) 问题背景 今天在使用 openapi 自动生成前端接口代码的时候,爆了一个类似 eslint 规范的错…

机器人路径规划:基于流场寻路算法(Flow Field Pathfinding)的机器人路径规划(提供Python代码)

流场寻路算法(Flow Field Pathfinding)是一种基于流体动力学理论的路径规划算法,它模拟了流体在空间中的流动,并利用流体的运动特性来指导路径的选择。下面是流场寻路算法的基本介绍及算法描述: 1. 基本介绍 流场寻路算法通过将环境划分为网…

算法导论第十二章练习参考答案(22) - 12.1-12.4

Exercise 12.1-1 任何时候,如果一个节点有一个子节点,就把它当作右子节点,左子节点为NIL。 Exercise 12.1-2 二叉搜索树的属性保证了左子树的所有节点都更小,右子树的所有节点都更大。最小堆属性只保证一般的子节点大于父节点的关…

你在测试金字塔的哪一层(上)

​在准备将软件上线到生产环境之前需要进行测试。随着软件测试方式日趋成熟,软件开发团队的测试也在取代大量手动测试,逐渐实现自动化测试。 通过自动化测试,开发团队可以在短短几分钟内就了解到软件是否存在问题,而不需要等待几天…

航空公司遭遇Play恶意家族攻击,亚信安全发布《勒索家族和勒索事件监控报告》

本周态势快速感知 本周全球共监测到勒索事件95起,与上周相比数量持平。 本周Play是影响最严重的勒索家族,Blacksuit和Ransomhub恶意家族紧随其后,从整体上看lockbit3.0依旧是影响最严重的勒索家族,需要注意防范。 本周大陆航空技…

【鸿蒙HarmonyOS开发笔记】常用组件介绍篇 —— 弹窗组件

简介 弹窗是移动应用中常见的一种用户界面元素,常用于显示一些重要的信息、提示用户进行操作或收集用户输入。ArkTS提供了多种内置的弹窗供开发者使用,除此之外还支持自定义弹窗,来满足各种不同的需求。 下面是所有涉及到的弹窗组件官方文档…

CSS 浮动

浮动 在标准流当中,元素或者标签在页面上摆放的时候会出现不如意的地方。要想解决这些问题可以采用脱离标准流的方式来进行解决这些问题,脱离标准流也称为脱离文档流。 脱离标准流的解决方式有三种,一种是浮动,另外一种是固定定位…

如何读懂磁滞回曲线(磁化曲线、退磁曲线、内禀曲线)

硬磁性材料,如钕铁硼磁钢,有两个显著特征,一是在外磁场作用下能被强烈磁化,另一个是磁滞,即撤走外磁场后硬磁材料仍保留磁化状态,下图为硬磁材料的磁感应强度B与磁化场强度H之间的关系曲线。 当磁场按Hs→H…

算法——贪心

「贪心的本质是选择每一阶段的局部最优,从而达到全局最优」 贪心无套路 1. 分发饼干 贪心策略: (1)局部最优就是大饼干喂给胃口大的,充分利用饼干尺寸喂饱一个,全局最优就是喂饱尽可能多的小孩 &#xff08…

Linux chapter1 常用命令 cp

note 1 : netstat、curl、ip、nmap、dig 这些都是常用的网络诊断工具,它们的全称如下: netstat:Network Statistics,网络统计,用于显示网络连接,路由表,网络接口统计等网络信息。curl&#xf…

Kali Linux 更换优质国内源

文章目录 环境说明1 Kali Linux 源简介2 Kali Linux 更换国内源 环境说明 操作系统:kali-linux-2024.1-installer-amd64 1 Kali Linux 源简介 所谓的 Kali Linux 源,你可以将它理解为软件仓库,系统通过它安装和更新软件;源的服务…

nodeJs 学习

常用快捷键 二、fs模块 回调函数为空,则表示写入成功! 练习 const fs require(fs); fs.readFile(../files/成绩.txt, utf-8, (err, dataStr) > {if (err) {console.log(读取失败);return err;}console.log(读取成功);const arr dataStr.split( )co…

RPC 和 序列化

RPC 1 RPC调用流程 1.1 clerk客户端调用远程服务 Clerk::PutAppend() raftServerRpcUtil::PutAppend() raftServerRpcUtil是client与kvserver通信的入口, 包含kvserver功能的一对一映射:Get/PutAppend,通过stub对象——raftKVRpcProctoc:…

web前端之实现复选功能、repeat

MENU 1、原生实现1.1、html部分1.2、JavaScript部分1.3、css部分1.4、效果图 2、uniApp实现2.1、html部分2.2、JavaScript部分2.3、css部分2.4、效果图 1、原生实现 1.1、html部分 暂时为null,后续会补充。1.2、JavaScript部分 暂时为null,后续会补充…

算法第二十九天-森林中的兔子

森林中的兔子 题目要求 解题思路 重点:某个兔子回答x的时候,那么数组中最多循序x1个同花色的兔子同时回答x 我们可以通过举例子得出一下的规律: 我们统计数组中所有回答x的兔子的数量n: 若n%(x1)0,说明我们此时只需…

Vector[C++]

文章目录 C中的std::vector简介std::vector的特点std::vector的重要接口用法介绍1. 初始化vector 2. 添加元素push_backemplace_back 3. 访问元素operator[]back 4. 修改元素operator 5. 遍历三种,下标,迭代器,范围for 6. 容量和大小sizeempt…

Induction or tail-recursion

选择排序 遍历整个待排序的数组,从第一个元素开始。在未排序的部分中,找到最小(或最大)的元素,并将其与第一个元素交换位置。接着从第二个元素开始,重复步骤2,直到所有元素都被排序 迭代版 递…

Qt实现简单的五子棋程序

Qt五子棋小程序 Qt五子棋演示及源码链接登陆界面单机模式联机模式联网模式参考 Qt五子棋 参考大佬中国象棋程序,使用Qt实现了一个简单的五子棋小程序,包含了单机、联机以及联网三种模式;单机模式下实现了简易的AI;联机模式为PtoP…

OPTIONS请求(跨域预检查)

目录 一、什么是OPTIONS请求?二、简单请求、复杂请求三、特定的请求头、响应头 一、什么是OPTIONS请求? OPTIONS 请求方式是 HTTP 协议中的一种,主要用于 从响应头中获取服务器支持的HTTP请求方式。 OPTIONS 请求方式是 浏览级行为&#xf…

Redis命名设计

可读性和管理性 以项目名为前缀(防止key冲突),用冒号分隔,比如项目名:表名:id zh(知乎):news_data(新闻数据):2(主键id) zh:news_data:2 精简性 key的命名,尽量精简,key的名字长度对内存的占用不可忽视,我们来实际…