Games104——渲染中光和材质的数学魔法
原文链接
渲染方程及挑战
挑战
对于任一给定方向如何获得radiance–阴影
对于光源和表面shading的积分运算(蒙特卡洛积分)
对于反射光多Bounce的无限递归计算
基础光照解决方案
Blinn-Phong模型:
简化阴影
最常见的处理方式就是Shadow Map:先在光源处放置相机,以z-buffer的方式储存一张深度缓冲,第二次将相机放置在view位置,并将视锥内的点的深度和深度缓冲中的对应点(矩阵变换)的深度进行对比,若前者大于后者,则认为视锥中的点处于阴影中
缺点:
光源处的采样率和观察处的采样率不一样,有分辨率限制,同时光源角度大时会出现自阴影锯齿的问题
简化光源
用平行光、聚光灯、点光源作为MainLight 来简化各种光源,用Ambient Light替代光源外的环境光
用可采样的环境贴图代替反射光线,环境贴图的mipmap代替粗糙度表现
最终结果 = MainLight + Ambient Light+Environment Map
简化材质(Blinn-Phong模型)
基于光可叠加原理(渲染方程中用体现),Blinn-Phong模型通过Ambient + Diffuse + Specular来简单粗暴的着色。
布林冯模型存在的问题
能量不保守,使用Blinn-Phong模型的出射光照能量可能大于入射光照的能量,这在计算光线追踪时会带来很大的问题:这一过程在光线追踪中经过无限次反弹后,会使得本该暗的地方变得过于明亮。
难以表现真实的质感,Blinn-Phong模型虽然比较经典,但它却很难表现出物体在真实世界中的模样,总是有一种”塑料“感。
简化阴影
阴影:当光线被不透明物体阻挡时形成的空间
最常见的处理方式就是Shadow Map:先在光源处放置相机,以z-buffer的方式储存一张深度缓冲,第二次将相机放置在view位置,并将视锥内的点的深度和深度缓冲中的对应点(矩阵变换)的深度进行对比,若前者大于后者,则认为视锥中的点处于阴影中
缺点:
光源处的采样率和观察处的采样率不一样,有分辨率限制,同时光源角度大时会出现自阴影锯齿的问题
基于预计算的全局光照
挑战和计算思路
空间换时间
挑战
indirect Light 要想去采样(整个球面)数据量非常大,需要有合适的方式压缩
并且还得便于在渲染方程中进行积分
傅里叶变换
可以把空间域信号转变为频域信号,截取频域的一小段就可以实现对频率整体的一个粗糙的表达,还可以反傅里叶计算还原会空间域。(高效压缩)
卷积定理是傅立叶变换满足的一个重要性质。卷积定理指出,函数 卷积的 傅立叶变换是函数傅立叶变换的乘积。具体分为时域卷积定理和频域卷积定理,时域卷积定理即时域内的卷积对应频域内的乘积;频域卷积定理即频域内的卷积对应时域内的乘积,两者具有对偶关系。
球谐函数(Spherical Harmonics)
SH是拉普拉斯方程的一组限制在球上的解,可以理解为一组sin\cos组成的正交基,数量越多,可以表达的精度越高;并且相互之间正交(卷积为0–简化计算的核心)且二阶导数为0(拟合表面光滑)
一般实时渲染只取前3阶就够了(9个),因为一般只需要低频信息(因此也无法表达更高频);有时只需要知道光从哪里来,就只需0和1阶就够了(4个),如下图。「在这种情况下,压缩后只用32bits(4Bytes)就可以存储一个像素的颜色。卷积时先投影到SH正交基上再系数相乘即可」
SH Lightmap:预计算 GI
有了SH,我们就可以将场景参数化到一张巨大的lightmap贴图上(通常被称为地图集atlas):对所有表面点的irradiance进行离线计算并压缩为SH系数、保存进atlas
计算过程:
对世界物体进行几何简化(因为要把三维空间复杂集合投影到二维空间),如下图,并且参数分配时需要尽可能在同样的面积或体积内分配的texel精度近似
lighting:将lightmap映射到各级LOD上,应用模型细节,用HBAO(水平基准环境光遮蔽Horizon based ambient occlusion,升级版SSAO)加上短程(short-range)增加高频的灯光细节,再加上直接光照和材质的效果
lightmap的光照效果,可以看到已经有很多细节和软阴影效果了,下图是最终应用效果
Lightmap优缺点和可借鉴思想:
优点:
1.实时运行效率很高;
2.可以表现出环境中全局光照的许多细节
缺点:
1.预计算时间非常长(因此老师自己的引擎宁死不用);
2.只能处理静态场景物体和静态光照(动态物体会有类似人物走到一小块阴影里整个人变黑的bug);
3.空间换时间,占用内存较大(几十到几百MB)
可借鉴优秀思想:
空间换时间
把整个场景参数化到二维的tex上(或三维vol上也一样),方便计算
探针 Probe:Light Probe + Refection Probe
优点:运行效率高,静动态物体都可用,可以处理漫反射和镜面反射
缺点:大量的光探测SH需要预计算,没办法做到像lightmap那样那么好的细节(采样太稀疏)
Light Probe
在空间中放置很多采样点,每个采样点采集对应光场信息,物体经过时寻找附近的采样点并插值计算
自动探测点生成:空间内均匀的产生采样点,再根据玩家的可到达区域和建筑物的几何结构进行延拓,相对均匀的分布采样点
Refection Probe
类似的反射probe,数量少,但采样精度很高,应用在镜面等场景
基于物理的材质
微平面理论
BRDF==Material
BRDF(广义)最常用在实时渲染管线中的是Cook-Torrance 模型,其中兼顾了漫反射和镜面反射2个部分
Lambertian漫反射部分
我们知道理想漫反射的反射光线是均匀散布在各个方向的(半球),因此漫反射的BRDF值一定是个常数。假设入射光均匀且布满整个半球,可以得到如下推导:「半球对cos积分结果为π」
cook-torrance镜面反射部分
微表面模型细看有很多凹凸细节,这些细节可看作微小的镜面,远看就像是完全的平面,只能感受到微小平面对整体的作用。现实生活中就算是纯金属表面也有划痕、磨砂等,因此微表面模型能表示非常多实际物体。
菲涅尔方程(Fresnel Rquation)
现实中在不同的角度看物体,明显看到反射率不同(看玻璃也是)
微平面理论
基于图像的光照(Image-Based Lighting,IBL)
主要思路还是预计算,把复杂的积分都先预计算过,以减少光照中的计算时间。我们会分别预计算漫反射项和镜面项,最终在实时渲染中只需通过简单的纹理采样即可得到结果
- diffuse:提前将cubemap与反射光卷积的结果计算并储存在Irradiance Map中,使用时只需要取位置上的结果就可以了,见下图左
- specular:近似为Lighting Term和BRDF Term的乘积
- Lighting Term:由于不同粗糙度造成的高光结果不一样,用cubemap的minmap存储多个粗糙度的结果,用minmap的精度刚好对应不同粗糙度下的不同精度,图右
- BRDF Term:直接预计算保存到了一张LUT图里,使用F和粗糙度加载即可
阴影(Shadow)
Cascade Shadow级联阴影
对视锥体进行分层,远处的精度降低,近处提高。
需要优化点:blend between Cascade Laters:在层级之间边界的地方做插值以避免出现视觉断层。
优点:解决透视混叠(perspective aliasing)问题;快速生成深度图,深度写入时可提升3倍;效果不错
缺点:存储空间大(空间换时间);绘制时成本昂贵;几乎不可能生成高质量的区域阴影;没有彩色阴影,半透明投射出不透明阴影
软阴影
PCF
「该技术起初是用于抗锯齿\反走样,后来发现软阴影也可以用。」
「为什么不对shadow map做滤波?因为把shadow map模糊后,在深度判定完还是硬阴影(相当于二值化)。」
原理是在阴影判定时做一个filtering----不仅计算当前着色点对应shadow map上的深度,还计算该点在shadow map上周围一圈(比如7x7)的深度判定结果(非0即1)并取平均,将平均值作为Visibility项。「如果滤波核比较大,可以在范围内随机采样固定个数」
PCSS
很多引擎的标配
投影平面上的阴影到物体的距离越远,阴影越软、滤波核越大。
投影平面离物体越近,阴影越硬、滤波核越小。「即下图W越大,阴影越软」
VSSM
技术展望
GPU显卡快速升级
real-time Ray-Tracing on GPU
Real-Time Global Illumination:SSGI、SDF based GI、Voxel-based GI(SVOG/VXGI)、RSM/RTX GI
更复杂的材质模型:BSSRDF、BSDF(Strand-based hair)
过量shader
艺术家搞出大量shadergraph
程序员给shader的各种变化都写了单独的shader(??不就是我们公司)
不同平台编译语言不同
Uber Shader:每一种变化组合都写入同一个shader,通过宏定义控制分支(会产生大量变体)
优点:某个算法改进时需要更新所有相关shader,容易出错,用Uber shader就不会有这个问题
Virtual Shadow Maps
原理:类似Tiled Virtual Texture
现代引擎可以关注这个方向
UE5中VirtualShadowMap的简易实现原理(一)
总结
5-10年前流行的3A配置:
Lightmap+LightProbe
PBR+IBL
Cascade shadow + VSSM
相关文章:

Games104——渲染中光和材质的数学魔法
原文链接 渲染方程及挑战 挑战 对于任一给定方向如何获得radiance–阴影 对于光源和表面shading的积分运算(蒙特卡洛积分) 对于反射光多Bounce的无限递归计算 基础光照解决方案 Blinn-Phong模型: 简化阴影 最常见的处理方式就是Shadow M…...

impala增加字段,hsql查不到数据
impala增加字段,插入数据后直接查看文件有值,impala查询是有值的,但是hsq查出来就没有值! Parquet格式的表,在重命名表的列名,或新增列名后,查询重名的列数据时显示当前列所有值为NULL。 原因&a…...

SpringBoot项目中的异常处理
定义错误页面 SpringBoot 默认的处理异常的机制:SpringBoot 默认的已经提供了一套处理异常的机制。一旦程序中出现了异常 SpringBoot 会像/error 的 url 发送请求。在 springBoot 中提供了一个叫 BasicExceptionController 来处理/error 请求,然后跳转到…...

ComfyUI实现老照片修复——AI修复老照片(ComfyUI-ReActor / ReSwapper)尚待完善
AI修复老照片,试试吧,不一定好~~哈哈 2023年4月曾用过ComfyUI,当时就感慨这个工具和虚幻的蓝图很像,以后肯定是专业人玩的。 2024年我写代码去了,AI做图没太关注,没想到,现在ComfyUI真的变成了工…...

NLTK命名实体识别(NER)
命名实体识别(Named Entity Recognition, NER)是自然语言处理(NLP)中的一项核心技术,旨在从文本中识别出具有特定意义的实体,如人名、地名、组织名等。通过对文本的自动化处理,NER能够帮助计算机理解和组织大量的非结构化数据,为信息抽取、搜索引擎优化、数据分析等领域…...

【游戏设计原理】78 - 持续注意力
这个原理指出,人类的注意力通常只能维持7至10分钟,因此游戏设计需要根据这一规律进行优化。具体建议包括: 短时间段设计:将游戏体验分解成7到10分钟的任务或场景,以符合玩家的注意力节奏。引入新刺激:在注…...

Android设备:Linux远程lldb调试
更多内容:XiaoJ的知识星球 目录 一、环境准备1.1 安装llvm/NDK1.2 开启lldb-server服务1.3 lldb连接lldb-server 二、使用lldb调试Android native源码2.1 运行调试2.2 .lldbinit文件 下面介绍Android设备(Android手机为例),在Linu…...

多层 RNN原理以及实现
数学原理 多层 RNN 的核心思想是堆叠多个 RNN 层,每一层的输出作为下一层的输入,从而逐层提取更高层次的抽象特征。 1. 单层 RNN 的数学表示 首先,单层 RNN 的计算过程如下。对于一个时间步 t t t,单层 RNN 的隐藏状态 h t h_t…...

[Computer Vision]实验三:图像拼接
目录 一、实验内容 二、实验过程及结果 2.1 单应性变换 2.2 RANSAC算法 三、实验小结 一、实验内容 理解单应性变换中各种变换的原理(自由度),并实现图像平移、旋转、仿射变换等操作,输出对应的单应性矩阵。利用RANSAC算法优…...

【Vim Masterclass 笔记22】S09L40 + L41:同步练习11:Vim 的配置与 vimrc 文件的相关操作(含点评课内容)
文章目录 S09L40 Exercise 11 - Vim Settings and the Vimrc File1 训练目标2 操作指令2.1. 打开 vimrc-sample 文件2.2. 尝试各种选项与设置2.3. 将更改内容保存到 vimrc-sample 文件2.4. 将文件 vimrc-sample 的内容复制到寄存器2.5. 创建专属 vimrc 文件2.6. 对于 Mac、Linu…...

5.9 洞察 OpenAI - Translator:日志(Logger)模块的 “时光记录仪”
洞察 OpenAI - Translator:日志(Logger)模块的 “时光记录仪” 在开发和生产环境中,日志记录是确保应用程序正常运行和快速调试的核心机制之一。日志模块(Logger)用于记录应用程序的运行信息,包括错误、警告、调试信息、信息性事件等。通过日志,开发者可以实时监控程序…...

客户案例:电商平台对帐-账单管理(亚马逊amazon)
账单管理: 功能定义: 账单管理用于上传亚马逊(amazon)平台下载的原始账单数据,美国站、日本站、墨西哥站等账单模板直接进行数据上传,做到0调整,下载下来的账单数据无缝上传至对账平台-账单管…...

IP协议特性
在网络层中,最重要的协议就是IP协议,IP协议也有两个特性,即地址管理和路由选择。 1、地址管理 由于IPv4地址为4个字节,所以最多可以支持42亿个地址,但在现在,42亿明显不够用了。这就衍生出下面几个机制。…...

Kubernetes入门学习
kubernetes技术架构模型 一、kubernetes的Label标签 1.标签是以keyvalue的格式通过用户自定义指定,目的是将其加入到各种资源对象上来实现多维度的资源分组管理使其更方便的进行资源分配、调度、配置和部署管理工作。 2.标签可以结合Label Selector(标签选择器)查询…...

支持向量机SVM的应用案例
支持向量机(Support Vector Machine,SVM)是一种强大的监督学习算法,广泛应用于分类和回归任务。 基本原理 SVM的主要目标是周到一个最优的超平面,该超平面能够将不同类别的数据点尽可能分开,并且使离该超平面最近的数…...

Chrome 132 版本新特性
Chrome 132 版本新特性 一、Chrome 132 版本浏览器更新 1. 在 iOS 上使用 Google Lens 搜索 在 Chrome 132 版本中,开始在所有平台上推出这一功能。 1.1. 更新版本: Chrome 126 在 ChromeOS、Linux、Mac、Windows 上:在 1% 的稳定版用户…...

(5)STM32 USB设备开发-USB键盘
讲解视频:2、USB键盘-下_哔哩哔哩_bilibili 例程:STM32USBdevice: 基于STM32的USB设备例子程序 - Gitee.com 本篇为使用使用STM32模拟USB键盘的例程,没有知识,全是实操,按照步骤就能获得一个STM32的USB键盘。本例子是…...

Linux 系统服务开机自启动指导手册
一、引言 在 Linux 系统中,设置服务开机自启动是常见的系统配置任务。本文档详细介绍了多种实现服务开机自启动的方法,包括 systemctl 方式、通用脚本方式、crontab 方案等,并提供了生产环境下的方案建议和开机启动脚本示例。 二、systemct…...

分布式多卡训练(DDP)踩坑
多卡训练最近在跑yolov10版本的RT-DETR,用来进行目标检测。 单卡训练语句(正常运行): python main.py多卡训练语句: 需要通过torch.distributed.launch来启动,一般是单节点,其中CUDA_VISIBLE…...

Codeforces Round 1000 (Div. 2)-C题(树上两个节点不同边数最大值)
https://codeforces.com/contest/2063/problem/C 牢记一棵树上两个节点如果相邻,它们有一条边会重叠,两个节点延伸出去的所有不同边是两个节点入度之和-1而不是入度之和,那么如果这棵树上有三个节点它们的入度都相同,那么优先选择非相邻的两个节点才能使所有不同边的数量最大!!…...

C++17 新特性解析:Lambda 捕获 this
C17 引入了许多改进和新特性,其中之一是对 lambda 表达式的增强。在这篇文章中,我们将深入探讨 lambda 表达式中的一个特别有用的新特性:通过 *this 捕获当前对象的副本。这个特性不仅提高了代码的安全性,还极大地简化了某些场景下…...

Spring Boot 使用 Micrometer 集成 Prometheus 监控 Java 应用性能
在Spring Boot中使用Micrometer集成Prometheus来监控Java应用性能是一种常见的做法。 一、Micrometer简介 Micrometer是一个开源的Java项目,主要用于为JVM应用程序提供监控和度量功能。以下是对Micrometer的详细介绍: 定义与功能 Micrometer是一个针…...

Spring Boot 事件驱动:构建灵活可扩展的应用
在 Spring Boot 应用中,事件发布和监听机制是一种强大的工具,它允许不同的组件之间以松耦合的方式进行通信。这种机制不仅可以提高代码的可维护性和可扩展性,还能帮助我们构建更加灵活、响应式的应用。本文将深入探讨 Spring Boot 的事件发布…...

IM系统设计
读多写少,一般采用写扩散成timeline来做 写扩散模式 利用last message id作为这个作为最后一个消息体 timeline和批量未读和ack 利用ZSET来维护连接的定时心跳,来续约运营商的连接不断开...

华为EC6110T-海思Hi3798MV310_安卓9.0_通刷-强刷固件包
华为EC6110T-海思Hi3798MV310_安卓9.0_通刷-强刷固件包 刷机教程说明: 适用机型:华为EC6110-T、华为EC6110-U、华为EC6110-M 破解总分为两个部分:拆机短接破解(保留IPTV)和OTT卡刷(不保留IPTV)…...

ASP.NET Blazor托管模型有哪些?
今天我们来说说Blazor的三种部署方式,如果大家还不了解Blazor,那么我先简单介绍下Blazor Blazor 是一种 .NET 前端 Web 框架,在单个编程模型中同时支持服务器端呈现和客户端交互性: ● 使用 C# 创建丰富的交互式 UI。 ● 共享使用…...

PyTorch广告点击率预测(CTR)利用深度学习提升广告效果
目录 广告点击率预测问题数据集结构广告点击率预测模型的构建1. 数据集准备2. 构建数据加载器3. 构建深度学习模型4. 训练与评估 总结 广告点击率预测(CTR,Click-Through Rate Prediction)是在线广告领域中的重要任务,它帮助广告平…...

PAT甲级-1017 Queueing at Bank
题目 题目大意 银行有k个窗口,每个窗口只能服务1个人。如果3个窗口已满,就需要等待。给出n个人到达银行的时间和服务时间,要求计算每个人的平均等待时间。如果某个人的到达时间超过17:00:00,则不被服务,等待时间也不计…...

OneData体系架构详解
阿里巴巴的 OneData 体系架构方法论,主要分为三个阶段:业务板块、规范定义 和 模型设计。每个阶段的核心目标是确保数据的高效管理、共享与分析能力。 一. 业务板块(Business Segment) 业务板块是OneData体系架构中的第一步&…...

Gin 框架入门实战系列教程
一,Gin介绍 Gin是一个 Go (Golang) 编写的轻量级 http web 框架,运行速度非常快,如果你是性能和高效的追求者,我们推荐你使用Gin框架。 Gin最擅长的就是Api接口的高并发,如果项目的规模不大,业务相对简单…...