OpenGL3.3_C++_Windows(36)

news2024/9/26 5:16:56

PBR_IBL镜面部分

  • 镜面部分并不能像漫反射部分一样将BRDF部分像常量一样提取出来,因为它整个积分上不是常数,因为它受到wi和w0的影响,就比如一个x的等式,不能把x部分提取出来一样,他是随着等式变化的
  • 如果试图解算所有入射光方向加所有可能的视角方向的积分,二者组合数会极其庞大,实时计算太昂贵。
  • 我们把镜面部分再次拆分为两个部分:镜面部分再次分解(近似):积分ab = 积分a * 积分b
  • 分割求和近似法(split sum approximation):预滤波环境贴图(辐照度) + BRDF积分贴图
  • 镜面部分(分解后:Cook-Torrance 积分的BRDF,积分的镜面辐照度(考虑粗糙度和重要性采样)
预滤波环境贴图(镜面部分):
  • 这次会考虑粗糙度,因为对于不同粗糙度的表明会使用不同的mip图采样
  • 粗糙度越高,采样越分散,贴图越模糊,将保存到不同的mipmap级别的贴图中,
  • 为了确保为其 mip 级别分配足够的内存,一个简单方法是调用 glGenerateMipmap(GL_TEXTURE_CUBE_MAP)。
  • GL_LINEAR_MIPMAP_LINEAR 启用三线性过滤
  • mip 级别每增加一级,尺寸缩小为一半。
重要性采样:
  • 如果使用均匀的半球采样,计算镜面部分的辐照度,效果会很差,镜面反射依赖于表面的粗糙度,形成镜面波瓣,如果以类似方式选取采样向量将是有意义的,因此需要重要性采样
  • 如果要预计算,我们并不知道视角方向,如果我们假设视角方向==输出采样方向w0,这个部分中就不用考虑视角方向,从而预计算,虽然效果不是很好
  • 对于视线wo方向:N法线 = R反射向量 = V视线方向
  • //
  • 重要性采样:具有更快收敛速度的采样
  • 蒙特卡洛积分(完全随机 | 伪随机):

  • 蒙特卡洛积分:离散的解决问题,不必考虑所有

    • 在 a 到 b 上采样 N 个随机样本的子集,求和并求平均数,pdf 代表概率密度函数         

    • 随着样本数量的不断增加,我们最终将收敛到积分的精确

    • 估算是有偏的,集中于特定的值或方向,具有更快的收敛速度,但是可能永远不会收敛到精确解

  • //

  • 低差异序列(均匀 | 半随机):

  • 该序列生成的仍然是随机样本,但样本分布更均匀:具有更快的收敛速度,它们会以更快的速度收敛到精确解,这使得它对于性能繁重的应用很有用。

  •  Hammersley 序列(XI):该序列是把十进制数字的二进制表示镜像翻转到小数点右边而得

float RadicalInverse_VdC(uint bits) //生成随机数
{
     bits = (bits << 16u) | (bits >> 16u);
     bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
     bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
     bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
     bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
     return float(bits) * 2.3283064365386963e-10; // / 0x100000000
}
// ----------------------------------------------------------------------------
vec2 Hammersley(uint i, uint N)//(i在n个样本中的第i个样本,N个子样本)生成低差异序列
{
	return vec2(float(i)/float(N), RadicalInverse_VdC(i));
}
  • //

  • GGX几何函数 重要性采样:

vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness)//生成大体围绕镜面波瓣的采样方向
{
	float a = roughness*roughness;
	
	float phi = 2.0 * PI * Xi.x;
	float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a*a - 1.0) * Xi.y));
	float sinTheta = sqrt(1.0 - cosTheta*cosTheta);
	
	// from spherical coordinates to cartesian coordinates - halfway vector
	vec3 H;
	H.x = cos(phi) * sinTheta;
	H.y = sin(phi) * sinTheta;
	H.z = cosTheta;
	
	// from tangent-space H vector to world-space sample vector计算TBN
	vec3 up          = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
	vec3 tangent   = normalize(cross(up, N));
	vec3 bitangent = cross(N, tangent);
	
	vec3 sampleVec = tangent * H.x + bitangent * H.y + N * H.z;//变换到世界空间
	return normalize(sampleVec);
}
  • 有别于均匀或纯随机地,采样会根据粗糙度a,偏向微表面的半向量h的宏观反射方向,将 GGX 和 NDF应用到采样中。使用低差异序列值 Xi作为输入来生成采样向量:

  • 我们需要一些方法定向和偏移采样向量,以使其朝向特定粗糙度的镜面波瓣方向:

预过滤 mipmap 级别
roughness==0.2
  • 帧缓冲区缩放到适当的 mipmap 尺寸, mip 级别每增加一级,尺寸缩小为一半。

  • 访问该贴图时指定的 mip 等级越高,获得的反射就越模糊。

  • 基于积分的 PDF 和粗糙度采样环境贴图的 mipmap 

预过滤卷积的伪像:接缝和亮点:
可以看到亮点
  • 较低的 mip 级别具有更低的分辨率,并且预过滤贴图代表了与更大的采样波瓣卷积,因此缺乏立方体的面和面之间的滤波的问题就更明显:

  • 可以启用 GL_TEXTURE_CUBE_MAP_SEAMLESS,以为我们提供在立方体贴图的面之间进行正确过滤的选项:

  • //

  • 对镜面反射进行卷积需要大量采样,才能正确反映 HDR 环境反射的混乱变化。

  • 我们可以在预过滤卷积时,开启三线性过滤,不直接采样环境贴图,而是采样mapmap

 BRDF积分贴图:
LUT
  • 假设每个方向的入射辐射度L都是白色的,在给定粗糙度、光线 ωi 法线 n 夹角 n⋅ωi 的情况下,可以预计算结果,
  • 使用RGB通道的纹理,R为菲涅耳响应的系数,G为偏差值,
    n⋅ωi为横坐标,粗糙度作为纵坐标
  • 需要生成一张 512 × 512 分辨率的 2D 纹理
  • 对于brdf部分,我们可以再次移项变换和近似,将得到这个公式
合成最终颜色:
PBR
PBR带贴图
  • 根据菲涅尔fresnelSchlick(法线n视线v的点乘,f0,粗糙度)返回ks计算镜面部分占比,1-ks = kd计算漫反射部分占比
vec3 F = FresnelSchlickRoughness(max(dot(N, V), 0.0), F0, roughness);

vec3 kS = F;//漫反射部分权重
vec3 kD = 1.0 - kS;//镜面部分权重
kD *= 1.0 - metallic;     

vec3 irradiance = texture(irradianceMap, N).rgb;//漫反射LBL
vec3 diffuse    = irradiance * albedo;//漫反射部分

const float MAX_REFLECTION_LOD = 4.0;
vec3 prefilteredColor = textureLod(prefilterMap, R,  roughness * MAX_REFLECTION_LOD).rgb;//镜面LBL   
vec2 envBRDF  = texture(brdfLUT, vec2(max(dot(N, V), 0.0), roughness)).rg;//BRDF
vec3 specular = prefilteredColor * (F * envBRDF.x + envBRDF.y);//镜面部分

vec3 ambient = (kD * diffuse + specular) * ao; //计算顶点的环境光

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

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

相关文章

uni-app开发日志:将schema2code生成的新增页和修改页整合成一页

有没有想过&#xff0c;add和edit页面其实没多大差别&#xff1f; 我之前自研的系统add和edit都是一个页面&#xff0c;只要判断一下当前有没有id传递来&#xff0c;为空来就是新增。 这样如果页面修改时&#xff0c;才能尽量少改动代码&#xff0c;少出错。 对比add.vue和edit…

企业海外新闻稿发布的转型之路:从纸媒到数字化

在全球化进程加速的今天&#xff0c;企业的传播渠道和方式也在经历着深刻的变革。曾经占据主导地位的纸质媒体&#xff0c;逐渐被灵活高效的海外媒体网站所取代。企业新闻稿发布形式的转变&#xff0c;不仅体现了技术进步和媒体环境的变化&#xff0c;也标志着企业全球传播战略…

日结兼职零工平台小程序系统开发制作方案

目前在大学生和自由职业者群体中&#xff0c;对短期兼职零工的需求日益增长。同时&#xff0c;企业与个人雇主也面临着季节性和临时性用工的需求。 日结兼职零工小程序系统为寻求日结工作的求职者和需要短期劳动力的企业提供一个快速匹配的平台。实现快速发布日结兼职工作信息…

5年经验社招后端面试经历分享

这是一位读者去年的面经&#xff0c;他在 2023 年在百度毕业&#xff0c;后面拿到了快手、滴滴和京东的 offer&#xff0c;最终选择了京东&#xff0c;薪资总包是 51w。 下面是正文。 背景介绍 大家好&#xff0c;本人 2018 年毕业于一所普通 211 学校&#xff0c;专业是软件…

【Redis】Redis 的消息队列 List、Streams—(六)

目录 一、消息队列二、List 方案三、Streams 方案 一、消息队列 我们一般把消息队列中发送消息的组件称为生产者&#xff0c;把接收消息的组件称为消费者&#xff0c;下图是一个通用的消息队列的架构模型&#xff1a; 消息队列在存取消息时&#xff0c;必须要满足三个需求&…

基于yolov10的PCB检测算法研究

内容&#xff1a;项目将YOLOV10创新后的PCB检测算法成功部署到GD32H757上&#xff0c;实现PCB缺陷的工业产线实时检测。 项目主要支持开源代码&#xff1a;HomiKetalys/gd32ai-modelzoo: Provide deployable deep learning models on gd32 (github.com) &#xff08;想了解将…

群晖7.2.1 半洗白后安装AME

1. 群晖打开SSH 2. Xshell登录群晖 用管理员账户登录&#xff0c;然后使用sudo -i 获取root权限&#xff0c;sudo -i是要再次验证管理员密码 sudo -iSA6400还需要运行这个命令 /usr/syno/etc/rc.sysv/apparmor.sh stop #DSM7.2 AME版本3.1.0-3005强制解锁激活命令 curl -sk…

最常用集合 - ArrayList详解

ArrayList介绍 ArrayList实现了List接口&#xff0c;是顺序容器&#xff0c;即元素存放的数据与放进去的顺序相同&#xff0c;允许放入null元素&#xff0c;底层通过数组实现。除该类未实现同步外&#xff0c;其余跟Vector大致相同。每个ArrayList都有一个容量(capacity)&…

MeshAnything V2来了!30秒生成建模师级Mesh!最大可生成面数提升至1600.

GitHub已揽星1.9k的MeshAnything项目上新了V2版本&#xff0c;由来自南洋理工大学、清华大学、帝国理工学院、西湖大学等研究人员完成。 MeshAnything V2相比V1&#xff0c;使用了最新提出的Adjacent Mesh Tokenization&#xff08;AMT&#xff09;算法&#xff0c;将最大可生…

mysql学习教程,从入门到精通,MySQL介绍(1)

1、MySQL 教程 本教程是为初学者准备的&#xff0c;以帮助他们理解与MySQL语言相关的基础知识和高级概念。 mysql MySQL 是最流行的关系型数据库管理系统&#xff0c;在 WEB 应用方面 MySQL 是最好的 RDBMS(Relational Database Management System&#xff1a;关系数据库管理系…

浏览器的高级搜索

一、背景 通常我们在浏览器搜索内容都是直接在输入框输入我们想要查询的内容&#xff0c;但是这样搜索出来的内容关联性不是很高&#xff0c;很多内容都是与我们搜索内容无关&#xff0c;会浪费我们大量的时间去查找内容。比如&#xff1a;我想要搜索网页中包含《游戏科学》这4…

kafak集群搭建-基于kRaft方式

kafak集群搭建-基于kRaft方式 1、服务器规划2、kafka集群部署配置2.1、解压三个kafka2.2、配置/config/kraft/server.properties 3、启动kafka集群4、SpringBoot集成kafka的kRaft集群4.1、消费者4.2、生产者4.3、配置类4.4、实体类4.5、JSON工具类4.6、项目配置文件4.7、测试类…

【web开发】Spring Boot 快速搭建Web项目

Date: 2024.08.30 13:52:20 author: lijianzhan 简述&#xff1a;【Spring Boot 快速搭建Web项目应用】是一篇关于Java Web项目构建的文章&#xff0c;主要讲解了如何借助Maven工具来管理和构建Web应用程序。Maven是Java开发中广泛使用的自动化构建工具&#xff0c;能够帮助开…

顺序循环队列

顺序循环队列 队头插入元素&#xff0c;队尾删除元素 本来应该判空和判断是否存满的条件都是&#xff1a;队头 队尾&#xff0c;但这样就没办法区分了&#xff0c;所以&#xff0c;就牺牲一个空间&#xff08;比如长度为10&#xff0c;但只能存9个&#xff09;&#xff0c;这…

基层医疗云HIS系统源码:云计算、大数据等现代信息技术研发

云HIS源码&#xff0c;基层云HIS系统源码&#xff0c;基层医疗云HIS系统 利用云计算、大数据等现代信息技术研发的基层医疗云HIS系统实现了医院信息化从局域网向互联网转型&#xff0c;重新定义医疗卫生信息化建设的理念、构架、功能和运维体系。实现了医院信息化由局域网向互…

CAN协议通信 学习笔记

文章目录 1.CAN通信简介2.物理层2.1 CAN总线的电气特性2.2 CAN的位同步机制&#xff08;了解&#xff0c;用于理解CAN的初始化参数的配置原理&#xff09;硬同步方式重新同步方式 2.3 CAN对比其他常用协议的优势 3. 数据链路层3.1 CAN协议的数据帧3.2 仲裁机制3.3 访问控制3.4 …

python-FastApi框架

文章目录 FastApi一. 简介二. 特性三. 安装1. 安装fastapi模块2. 安装ASGI服务器( Uvicorn 或者 Hypercorn) 四. 实例1. 创建**main.py**文件(GET请求)2. 运行3. 测试4. 更新main_py(加入PUT请求) 五. 自动化API文档1. Swagger UI(交互式文档)2. ReDoc(可选式文档) FastApi 一…

华为云征文|Flexus云服务器X,云上性能新飞跃,开启业务增长新纪元

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;CSDN领军人物&#xff0c;全栈领域优质创作者✌&#xff0c;CSDN博客专家&#xff0c;阿里云社区专家博主&#xff0c;2023年6月CSDN上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;AWS/阿里云资深使用…

想告诉所有人,我找到脸书视频保存方法啦!

各位集美集帅们&#xff0c;我可算找到脸书视频的保存教学啦。作为社媒体人&#xff0c;在脸书看到有趣的素材却保存不了时真的要急的爆炸了。试了好多方式&#xff0c;这软件是最给力哒&#xff0c;我不管&#xff0c;下面的步骤介绍你一定要看完&#xff01; 打开脸书&#x…

JVM面试(一)什么是虚拟机?什么是class文件?

什么是java虚拟机&#xff1f; 如果通俗点来讲&#xff0c;我们在电脑上一行行敲出来的代码&#xff0c;电脑本身是不认识的&#xff0c;最终是要转成电脑可以运行的101001这种字节。 但是这些我们又不可能手动来转换&#xff0c;所以呢&#xff0c;就需要一个工具&#xff0…