DirectX12(D3D12)基础教程(二十一)—— PBR:IBL 的数学原理(1/5)

这篇具有很好参考价值的文章主要介绍了DirectX12(D3D12)基础教程(二十一)—— PBR:IBL 的数学原理(1/5)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、前言

1.1、一些感慨

  2023年来了,令人闹心伤身的疫情也暂告一段落了。感慨之余,其实我也挺惆怅,这个系列教程还能继续下去吗?或者我自己还能坚持多久,我不知道。因为我也天天徘徊在失业的边缘,年纪大了被人嫌弃,学历低被人嫌弃,身体稍差也被人嫌弃,忽然发现我已不是当初那个少年了,却还始终怀揣着少年时的梦想,依旧挣扎在理想与现实之间,或者只是挣扎在温饱线上,已然是一身债,半条命了。当然幸运的是到现在我都还没有阳过,属于少数那部分,我身边的朋友们也很惊奇。然而我的家人也都阳过了,他们也很惊奇我居然一直没有阳过,算是一点小小的慰藉吧。

  年轻时走错的弯路,经受过的磨难,造成了今天的困境,索性的是我现在在尽一切努力纠错,只是错过的光阴却永远无法找回了。生活可能就是这样,当你经历了很多,看透了很多,甚至都觉得人生其实只是短暂的一瞬间,与整个世界其实也毫无意义,我们不断重复和追寻的不过就是在思考、探讨或实践所谓的人生意义而已,更多的其实只是为了生存。无论你是工作、学习、生活、休闲、旅游、陪伴家人等等,都不过如此,始终你所能影响的就是那么一部分人,能记住你的也就是那一部分人,其中可能还包括你所谓的敌人或者对手,或许也没什么人会记得你。其实归根结底我们改变不了什么,甚至连我们自己的某些卑劣的人性都无法克服,只是一个平凡的自己而已。当然这样的生死又会有什么意义呢?

  然而,当我在对自己感兴趣的自己的这个领域深耕下去时,并且一次次突破瓶颈,恍然大悟时,我才真正感觉到内啡肽带给我的那种“极乐”,我始终认为这或许才是我自己真正的人生的意义,钻研下去,分享出去,获得真正的“极乐”。

  将来,不论怎样,我想只要我还活着,我就将这个系列继续下去,直到生命的尽头,不为别的,只为自己内心的“极乐”!在此也非常感谢各位网友一路的陪伴与支持!

1.2、运行效果展示

  在对技术的执著与深深的情怀支撑下,经过了一段时间的编程和调试后,终于 IBL 的基础示例代码也编写上传 Github 完成了( GRSD3D12Sample/25-IBL-MultiInstance-Sphere )。当这个例子第一次运行起来后,画面直接将我自己也惊艳到了。瞬间感觉“内啡肽”分泌量达到峰值,感觉真的是太好了,瞬间觉得所有的努力与汗水都十分的值得。当然如果各位能够顺利的从该系列教程的开始看到这里时,并且当你自己调试运行所有示例并完全搞明白的时候,也同样会感受到我说的那种快乐。其实本章示例代码也是很早就上传到了GitHub上,只是最近才得一点宽裕的时间,把这一章的教程内容补齐。

  从本质上来说,我们现在学习和讨论的是关于 Shader 的话题,与完全的D3D12接口编程是有点区别的,当然使用 D3D12 接口编程的目的之一就是为了更好的进行 Shader 编程。最终本章的内容不但可以用于 D3D,还可以用于 OpenGL,Vulkan,甚至手机渲染上,只要你搞明白了基本的 PBR Shader 的数学原理和基本代码,就可以把它们用在你想要使用的任何地方,甚至包括光追渲染。

  因为 IBL 的话题有些复杂,涉及内容较多(有D3D12编程的,也有Shader编程方面的,还有自身PBR的,更牵扯到很多数学、物理方面的知识),所以这一块的知识,也将被分成几部分来介绍。本章核心是让大家对整个 IBL 先有个整体的认识,尤其是其数学原理,并且搞清楚 IBL 作为 PBR 的一部分核心解决了什么问题。这是继续后续很多高级话题的基础,比如 Probe(探针),Pathtracing(路径追踪),球谐函数、距离场等等。所以这一章和前两章的内容希望大家都能够牢固掌握和理解,当然我会尽力为各位梳理清楚,方便各位深入学习。

  按照惯例,在正式开始介绍之前,先来看几幅效果截图:
DirectX12(D3D12)基础教程(二十一)—— PBR:IBL 的数学原理(1/5)
DirectX12(D3D12)基础教程(二十一)—— PBR:IBL 的数学原理(1/5)
DirectX12(D3D12)基础教程(二十一)—— PBR:IBL 的数学原理(1/5)
DirectX12(D3D12)基础教程(二十一)—— PBR:IBL 的数学原理(1/5)DirectX12(D3D12)基础教程(二十一)—— PBR:IBL 的数学原理(1/5)
DirectX12(D3D12)基础教程(二十一)—— PBR:IBL 的数学原理(1/5)
DirectX12(D3D12)基础教程(二十一)—— PBR:IBL 的数学原理(1/5)
DirectX12(D3D12)基础教程(二十一)—— PBR:IBL 的数学原理(1/5)
DirectX12(D3D12)基础教程(二十一)—— PBR:IBL 的数学原理(1/5)
DirectX12(D3D12)基础教程(二十一)—— PBR:IBL 的数学原理(1/5)

  从示例中已经可以明显的看出明亮光滑的金属球表面倒映出了环境光的样子,并且每种材质反射率表现出了不同的材质的基础属性,比如黄金看上去已经很逼真,而且黄铜,紫铜也表现出不同的反射色差,这一切都是 PBR 本身要表达的令人惊艳的光照效果。而这些还只是通过多种“近似”方法模拟出来的。当然本章展示的也只是 PBR 的基础效果而已,后面看有时间的话,就继续展开讲讲其它的那些分支,比如大气散射、皮肤渲染、玻璃折射等等,当然这要看我时间和精力的情况。只是希望我还能撑下去吧。

1.3、示例简介

  本章的示例,是在前一章 DirectX12(D3D12)基础教程(十九)—— 多实例渲染_ 示例的基础上,更进一步多实例化,用到了“间接绘制(ExecuteIndirect)”方法,并且示例中的小球阵列按照几种主要的材质(涉及金、银、铜、铁、水、玻璃等等)不同的反射率形成多个平面,每个平面又按照从上到下粗糙度变大,从左到右金属度变小的顺序排列成密集的的材质球演示立方阵列。并且横向排列比较宽,主要是因为我的显示器是 HDR 的“带鱼屏”,所以就这样设置。大家可以通过调整程序开头的几个参数来自己手动设置材质球阵列的行列大小。

  同时一定要注意的是,因为 IBL 中就开始牵扯到了复杂的光照积分运算,所以最原始的基于简单数值积分的 Shader 文件 “GRS_IBL_Diffuse_Irradiance_Convolution_With_Integration_PS.hlsl” 仅供大家参考学习之用,请千万不要在代码中引用! 实际我们使用的是结合了蒙特卡洛积分和重要性采样的版本“GRS_IBL_Diffuse_Irradiance_Convolution_With_Monte_Carlo_PS.hlsl”。根本原因是因为最基本的数值积分版本在单像素上计算量过于庞大,在加载和计算积分的过程中如果分辨率过高会导致GPU过载,如果你的系统没有保护机制,那么可能造成显卡损伤。

  在此郑重声明,由于你误操作引用了原始积分版本而导致的一切后果自负!

1.4、示例操作说明

  因为示例中引用了几个纹理,并且使用的是 HDR 纹理,为了让大家方便的引用不同的环境光照映射,所以程序会弹出几个文件选择框。第一个文件选择框是选择 “Image Base Lights” 也就是 HDR版的环境光源图片(扩展名为hdr,并且文件名中会有3k的字样说明),目前我们使用的是“hdr”格式的“等距柱面环境映射”贴图,示例代码中附带了几个环境映射。更多的环境映射,大家可以去 “sIBL Archive (hdrlabs.com)” 这里免费下载。在此感谢 hdrlabs 的慷慨分享!

  第二个文件选择框是为了选择 “等距柱面映射”版本的 Skybox,在 sIBL 下载的时候会附带至少 8k 分辨率的高清 SkyBox 贴图,为了感受更加逼真的效果建议加载扩展名为“jpg”的高清版环境映射。需要注意的是,实际代码中使用的是和加载 HDR 环境映射一样的 stb 库来加载这个高清的 jpg 图片,而没有使用我们一直使用的 WIC 库。因为WIC库自身的限制,这么高分辨率的图片它已经不能加载了。而关于 stb 库的用法,将在后续的教程中详细的介绍,本章教程将还是集中在 IBL 数学原理的介绍上。

  需要注意的是,高分辨率的环境映射加载需要一定的时间,并且因为程序并没有做优化的缘故,所以也会占用一定的内存和显存,当你显卡的显存少于 2G 时运行可能会有问题,请考虑升级显卡,或加载 Preview 版本的低分辨率版本环境映射。

  程序运行中可以用按键来控制一些效果,统一在下表中说明:

按键 效果 说明
Tab键 打开/关闭 中间贴图显示框 所有的中间解算或计算的CubeMap贴图、预积分贴图(漫反射和镜面反射积分图)、LUT等,使用了HLSL中的动态上限纹理数组
+/- 切换不同反射率材质球的平面 当全部切换完一遍后,会将所有的材质球平面全部显示出来,形成一个密集的阵列,有密集恐惧症的请慎重运行示例!
w 向前移动镜头
s 向后移动镜头
a 向左移动镜头
d 向右移动镜头
PageUp 向上移动镜头
PageDown 向下移动镜头
Shift 启/停 小球阵列旋转 启动或停止小球阵列的旋转动画

  未在上表中出现的操作方式,请详见代码中的 WndProc 函数中关于键盘消息处理的部分,这里就不在赘述了。

  在编译和运行之后,并且能够操作的情况下,建议反复运行并轮流加载本章教程附带的4组精选的 HDR 环境映射,以感受不同的效果和氛围。并且对 PBR 的 IBL 渲染方式有一个最直接的感性认识。

  另外需要注意的是,示例中带的名为“UV-Testgrid” 纹理是用于验证和理解“等距柱面映射”的原理和解算结果的,请在全部学习完毕后再运行,以加深对整个IBL知识的理解。运行这个验证环境纹理时,两个纹理都选择 testgrid.jpg 文件即可。其本质就是特意设定的黑白方格纹理,加载计算后可以根据方格及文字标记识别解算后的纹理坐标变化情况(拓扑变换),以及计算过程中各种贴图都是经历了什么样的变化。

1.5、本章内容的简述

  在实际学习 IBL 的整个过程中,我深深的感受到,如果其数学原理不搞清楚的话,学习 IBL 就只会停留于皮毛,而根本无法触及其深刻的本质,尤其是其中一些极具创造力的数学技巧。不得不说,当我彻底搞懂了 IBL 的数学原理之后,就被他其中的那些非常有创意的数学技巧所深深吸引。当然触及到 IBL 自身的数学原理的资料,无论是书籍还是资料都是非常少的,或者就是分散在各处,其中有些还语焉不详,错漏百出。

  正因为这样的感触,所以我就专门整理一整套的 IBL 的基础数学原理成为此章教程。并且尽力将整个推算简化近似的过程都讲清楚,当然过于基础的内容限于篇幅就不多讲解了。数学基础较弱同学,请自行复习微积分、概率论、线性代数、向量运算即向量微积分等内容,尤其是概率论及微积分是彻底搞懂 IBL 原理的基础支撑性知识。在阅读本篇教程前,建议各位先阅读一下: 3D数学系列之——再谈特卡洛积分和重要性采样 对蒙特卡洛积分有个初步的了解。
DirectX12(D3D12)基础教程(二十一)—— PBR:IBL 的数学原理(1/5)

  最终如果你暂时看不懂这一章的内容也没有关系,先收藏,等你复习完必要的数学知识后再折回头好好消化下本章的内容,直到能够彻底掌握 IBL 的数学原理为止,因为这是通向PBR 渲染中的其他高级话题的第一座高峰。

2、什么是IBL

2.1、“Cook-Torrance” 模型解决的问题

  实际在 DirectX12(D3D12)基础教程(十八)—— PBR基础从物理到艺术(下) 中,我们只是解决反射方程中的 f r ( p ⃗ , ω i ⃗ , ω o ⃗ ) {f}_{r}( \vec{p} , \vec{\omega_i} , \vec{\omega_o}) fr(p ,ωi ,ωo ) 函数的近似形式问题。或者说我们找到了一个物理与艺术相结合的近似解析表达式(基于迪士尼原则),也就是基于微平面理论的“Cook-Torrance”模型的 BRDF 函数。整体上来说该模型使得的渲染方程更进一步的解析表达如下(忽略自发光项):
L o ( p ⃗ , ω o ⃗ ) = ∫ Ω ( k d c π + k s D F G 4 ( ω o ⃗ ⋅ n ⃗ ) ( ω i ⃗ ⋅ n ⃗ ) ) L i ( p ⃗ , ω i ⃗ ) n ⃗ ⋅ ω i ⃗ d ω i ⃗ L_o(\vec{p},\vec{\omega_o}) = \int\limits_{\Omega} (k_d \cfrac{c}{\pi} + k_s \cfrac{ D F G }{ 4 (\vec{\omega_o} \cdot \vec{n} )(\vec{\omega_i} \cdot \vec{n})}) L_i(\vec{p},\vec{\omega_i}) \vec{n} \cdot \vec{\omega_i} \mathrm{d} \vec{\omega_i} Lo(p ,ωo )=Ω(kdπc+ks4(ωo n )(ωi n )DFG)Li(p ,ωi )n ωi dωi
  上述方程是完整的积分方程形式,也被称为渲染方程,在之前的教程中都没有正式的提到过,现在正式将其列出,作为复习总结和本章开始的基础。

  之前之所以没有出现这个形式的总体方程,是因为前面的重点是放在 BRDF 函数的解析与应用上,也就是 DFG 部分的表达式的介绍与应用上。并且是基于点光源的简单原理性应用,并没有涉及到复杂的积分究竟如何计算和编程上。即还没有真正的考虑全部复杂的入射光源的问题。也就是说前面的教程实质上是简化了光源(其实只使用了几个点光源而已,从而就不必要考虑复杂的积分问题),而将重点放在了 BRDF 函数的讲解和说明上。那么在这一章中,我们就需要来思考复杂光源或复杂入射光情况下,如何来完整的做这个积分运算。

2.3、光源问题

  在之前示例的几个点光源模型下,上述的 “Cook-Torrance” 模型积分其实就退化为按每个点光源分别计算 BRDF,以及对应一条光线的反射效果,然后再根据光源的参数计算一个点引起的光照反射效果之后,最终求和并求平均值即可。这使的复杂的积分计算退化成了求和问题(与黎曼和有本质的区别不要搞混)。这样的简化,其目的是搞明白基于微平面理论的 “Cook-Torrance” 模型 BRDF 函数的解析形式及 Shader 代码如何编写的问题。

  在有限点光源的示例中,其实本质上来说,积分方程中的 L i ( p ⃗ , ω i ⃗ ) L_i(\vec{p},\vec{\omega_i}) Li(p ,ωi ) 函数其实就被简化为视点 p 、光源颜色、和入射方向向量(实际是从光源位置计算得到)等几个具体向量而已。这其实在实际应用中是不存在的情况。因为这就好像用简单的几道单光子激光照射一个物体表面上的情况一样,除了实验室中可能会有这种场景外,实在想不出还会有什么地方会有这样的情况。

  而在现实的情况中,基于对万事万物都处在普遍联系中这个朴素真理的认识,我们知道物体间的光照关系是异常复杂的。也就是说代表光源的 L i ( p ⃗ , ω i ⃗ ) L_i(\vec{p},\vec{\omega_i}) Li(p ,ωi ) 函数本身是异常复杂的。这就导致整个积分方程的计算也会异常复杂,从而无法使用解析积分的方法求解其原函数。实际计算中只能退回到黎曼和的方式来计算这个积分,而且是对每一个像素点使用所有的入射光进行复杂的数值积分计算。这样反射方程的整体计算量对于实时 PBR 来说依然是非常巨大而无法执行的。

  并且积分中的入射辐照度函数 L i ( p ⃗ , ω i ⃗ ) L_i(\vec{p},\vec{\omega_i}) Li(p ,ωi ) ,往往还无法简单的找到解析表达式,也就是说没法用一个解析式来表达它。这样实际上对于复杂光照场景来说 “Cook-Torrance” 模型积分虽然有了近似的 BRDF 函数支撑,但其计算依然是非常复杂的。
DirectX12(D3D12)基础教程(二十一)—— PBR:IBL 的数学原理(1/5)

2.4、IBL 模型

  在现实光照的场景中入射辐照度 L i ( p ⃗ , ω i ⃗ ) L_i(\vec{p},\vec{\omega_i}) Li(p ,ωi ) 函数的表达式一般是无法知道的,主要是因为对于具体的物体表面的一点 p ⃗ \vec{p} p 来说,其入射光不止来源于直接光源,还可能来源于其它物体的反光以及大气散射后的光源等等(想想阴天见不到太阳时的情景,这时基本没有直射光源)。

  但是可以换个角度思考这个问题,既然万事万物都处于普遍联系中,那么也就是说一事物上受到的光照一定是来自于其环境中所有的其它事物。这些其它事物就包括光源、反光体等等。这时聪明的图形程序员就想到,如果把包围物体的环境映射(通常是一个以被照射物体中心点为原点的 CubeMap 映射,这也是插入 DirectX12(D3D12)基础教程(二十)—— 纹理数组(Texture Array)非DDS初始化操作)这一章教程的本意。)然后将这个环境映射作为 L i ( p ⃗ , ω i ⃗ ) L_i(\vec{p},\vec{\omega_i}) Li(p ,ωi ) 函数的数值表示(图形即函数!)那么 L i ( p ⃗ , ω i ⃗ ) L_i(\vec{p},\vec{\omega_i}) Li(p ,ωi ) 函数的计算就成了一个针对 CubeMap 映射的 3D Sample 操作,而采样的方向就是入射光的反方向 − ω i ⃗ -\vec{\omega_i} ωi 。这就是 IBL (Image Based Lighting)的真实含义。

  也就是说我们用代表所有环境光,包括光源、反光体等的图片作为 L i ( p ⃗ , ω i ⃗ ) L_i(\vec{p},\vec{\omega_i}) Li(p ,ωi ) 函数并进行采样操作,就相当于进行了 L i ( p ⃗ , ω i ⃗ ) L_i(\vec{p},\vec{\omega_i}) Li(p ,ωi ) 函数计算。这样一来 “Cook-Torrance” 模型积分方程中最重要的 BRDF 计算问题 和入射辐照度 L i ( p ⃗ , ω i ⃗ ) L_i(\vec{p},\vec{\omega_i}) Li(p ,ωi ) 函数计算问题就都解决了,剩下的就是找到合适的 环境映射 CubeMap Image,加载并进行最终的数值积分计算即可。

  而在实际 IBL 应用中,一般使用的是将原本需要6个面来存储的环境映射CubeMap 贴图,投影压缩到一张被称为 “等距柱面”贴图的映射,通常像下面的样子:
DirectX12(D3D12)基础教程(二十一)—— PBR:IBL 的数学原理(1/5)

  这个图形看上去很扭曲,其实可以简单的将他理解为我们常见的世界地图,本质上就是将本应是一个球面的图形拓扑平铺到了一个平面上。只是等距柱面贴图是按照圆柱面映射球面,最后再把圆柱面展开平铺成平面图形。这样做的好处就是比起 6 个面的 cubemap 来说,存储上面占有较大优势。同时这也方便一些 360 度全景相机拍摄存储处理。当然图形细节及精度方面就有所损失,尤其是靠近图形的上下边界部分。但是它在中间水平线(地平线)附近几乎保留了全部细节,所以在重映射回球面时,因为通常场景中,视方向主要还是集中在中间线部分,所以实际中看上去效果还是令人满意的。在 “sIBL Archive (hdrlabs.com)” 网站上就有大量的精美的等距柱面环境映射贴图供大家免费下载。

  实际使用的时候,就需要先将这个 “等距柱面贴图” 解算为一个具有 6 个面的 CubeMap纹理上。具体解算的方法放在后续教程中再详细介绍。本章示例代码中那些小方块中的第1幅图片就是加载后的等距柱面原始图片,紧随其后的 第2-7幅图片就是结算后的CubeMap 6个面的图片:
DirectX12(D3D12)基础教程(二十一)—— PBR:IBL 的数学原理(1/5)
  从上图中可以看出,解算后的6个面的CubeMap的效果还是令人满意的,也就是说实际上等距柱面贴图的缺陷并不是那么明显,比起其优点来说几乎可以忽略不计,这也是等距柱面贴图比较流行的原因。在此复习下6个面的顺序以及位置关系(最好对照上面的顺序和下图自行脑补一下最终的CubeMap的样子):
DirectX12(D3D12)基础教程(二十一)—— PBR:IBL 的数学原理(1/5)
  在后续要介绍的漫反射项预积分和镜面反射预积分计算中,实际使用的都将是解算出的6个面的 CubeMap(本章教程中使用了 GS 一次性渲染到六个面的方法,后续教程会详细介绍,大家先理解原理即可)。

  同时在示例代码的开头处,用宏定义预设值定义了结算后的 CubeMap每个面的大小如下:

#define GRS_RTA_DEFAULT_SIZE_W          512
#define GRS_RTA_DEFAULT_SIZE_H          512

  对于设备比较好,尤其是显卡比较好的同学来说,可以尝试将这个预设值调高一点,但是一定要注意这两个值必须一样大小,因为实际上这6个面围成了一个正方体的6个面,可以直观的理解为是一个SkyBox,关于SkyBox 和 CubeMap操作的更多基础知识请参阅:DirectX12(D3D12)基础教程(二十)—— 纹理数组(Texture Array)非DDS初始化操作 。

  另外除了等距柱面贴图外,IBL 中还经常使用另一大类被称之为“双抛物面环境映射”的贴图。这里需要提醒大家注意的是,不论使用哪种环境映射来作为整体的环境光照的光源,包括后续可能会讲到的所谓全局光照中使用的探针(Probe),并实时生成的环境映射中,其格式都应该是 HDR 线性的。这是因为根据对 PBR 本质的了解,我们知道 PBR 核心的思想就是物理真实的,所以其包含的作为光源光线的信息也应当是物理真实的,而现实中的光源能量值范围是非常宽泛的,并且远超出一般 RGB 图形中所能表示的范围的。所以这样的光源能量信息就必须使用更宽范围的 HDR 图片格式来存储。有些情况下,甚至需要自定义格式的 HDR 格式图片来存储物理真实的光源能量信息。

  另外,如果环境映射使用的不是 HDR 格式时,或者严格的说是被衰减并压缩了范围的光源能量信息时,将会导致整个 IBL 效果失真,最终效果甚至看上去还不如传统光照时的效果。这是大多数时候被忽视的一个问题,即虽然渲染内核使用的是 PBR 的算法,但是使用的光源、光线信息却不是 “物理真实的” 从而导致实际效果大打折扣。这个问题是包括图形程序员和技美人员,都需要高度重视的一个问题。

  特别需要提醒的是,即使是使用所谓 HDR 功能的一些摄影摄像设备采集真实环境的映射时,依然要仔细查看它实际上所能表达和记录的光线的能量范围。因为有些 HDR 设备虽然称之为 HDR, 可能实际上只是比普通的RGB表达范围高一点点而已。而这时辐射度测量仪器是非常好的帮手。
DirectX12(D3D12)基础教程(二十一)—— PBR:IBL 的数学原理(1/5)
  关于 HDR 的进一步话题,将在后续的教程中详细介绍。这里大家先可以简单的理解为 HDR 就是每个颜色范围都可以远超过 [0.0f,1.0f] 范围的图片。基于这个理解,大家就会明白在之前的点光源 PBR 示例中,为每个光源设置的 RGB 范围是远远大于1.0的含义了,其实就是为了使用更高能量表达的光源,尽可能的照亮材质球。

  最后要提示大家的是,其实整个 IBL 属于被称为 PBL (Physically Based Lighting)的范畴,也就是基于物理的光照,即使用物理真实的光源光照信息来渲染整个场景的方法。文章来源地址https://www.toymoban.com/news/detail-403815.html

到了这里,关于DirectX12(D3D12)基础教程(二十一)—— PBR:IBL 的数学原理(1/5)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • d3d12龙书阅读----绘制几何体(上)

    本节主要介绍了构建一个简单的彩色立方体所需流程与重要的api 下面主要结合立方体代码分析本节相关知识 输入装配器阶段的输入 首先,我们需要定义立方体的八个顶点 顶点结构体: 当然,对于更复杂的情况,我们不仅要定义顶点的位置与颜色,还要包括法线向量、纹理

    2024年03月27日
    浏览(61)
  • 一、D3D12学习笔记——初始化Direct3D

    工厂类IDXGIFactory4,这个类有两个作用: 1.枚举适配器(显卡); 2.创建交换链 这个类对象的创建如下: 用这个对象mdxgiFactory枚举我们可以使用的显卡等适配器: 对于一个选定的适配器pIAdapter,拿着它去创建设备 IID_PPV_ARGS这个宏实际包含了两个东西,uuid的COM ID和对象的指针

    2024年02月10日
    浏览(52)
  • d3d12龙书阅读----Direct3D的初始化

    使用d3d我们可以对gpu进行控制与编程,以硬件加速的方式来完成3d场景的渲染,d3d层与硬件驱动会将相应的代码转换成gpu可以执行的机器指令,与之前的版本相比,d3d12大大减少了cpu的开销,同时也改进了对多线程的支持,但是使用的api也更加复杂。 接下来,我们将先介绍在

    2024年03月12日
    浏览(46)
  • DirectX12_Windows_GameDevelop_3:Direct3D的初始化

    查看龙书时发现, 第四章介绍预备知识的代码不太利于学习 。因为它不像是LearnOpenGL那样从头开始一步一步教你敲代码,导致你没有一种整体感。 如果你把它当作某一块的代码进行学习,你跟着敲会发现,总有几个变量是没有定义的。这是因为书上的代码都是把框架里的某

    2024年02月08日
    浏览(44)
  • Java基础(二十一)十点半游戏

    十点半是一种流行的纸牌游戏,可以说是一种变体的二十一点游戏。游戏的规则是,每个玩家根据所拿到的牌点数的总和来决定是否继续要牌。目标是尽量接近但不超过十点半的点数,超过十点半即为爆牌。如果两名玩家都未爆牌,则点数更接近十点半的人获胜。这个游戏非

    2024年02月09日
    浏览(47)
  • 【JavaSE】Java基础语法(二十一):内部类

    内部类概念 在一个类中定义一个类。举例:在一个类A的内部定义一个类B,类B就被称为内部类 内部类定义格式 格式举例: 内部类的访问特点 内部类可以直接访问外部类的成员,包括私有 外部类要访问内部类的成员,必须创建对象 示例代码: 成员内部类的定义位置 在类中

    2024年02月07日
    浏览(50)
  • Docker学习(二十一)构建 java 项目基础镜像

    JDK各版本官网下载地址: https://www.oracle.com/java/technologies/downloads/archive/#JavaSE 这里我们以 JDK 8u351 为例,点击 Java SE (8U211 and later) 。 点击下载 jdk-8u351-linux-x64.tar.gz 。 勾选接受协议,点击下载。(这里会需要登录一下,没有账号可以注册一个,Oracle账号以后也会用到) 下载后

    2024年02月07日
    浏览(39)
  • Kubernetes基础(二十一)-k8s的服务发现机制

    Kubernetes(K8s)是一个强大的容器编排平台,提供了丰富的功能来简化容器化应用的管理。其中之一重要的特性就是服务发现机制,它使得应用程序能够在K8s集群中动态地发现和访问其他服务。本文将深入研究K8s中的服务发现机制,探讨其原理、使用方法以及通过详细的示例演

    2024年02月20日
    浏览(49)
  • Unity(第二十一部)动画的基础了解(感觉不了解其实也行)

    动画视频 Play Automatically 是否自动播放 Animate Physics 驱动方式,勾选后是物理驱动 Culling Type 剔除方式 默认总是动画化就会一直执行下去,第二个是基于渲染播放(离开镜头后不执行), 如果没有动画的话,可以自己做,点击窗口动画进入动画面板 选中物体,创建动画 动画就

    2024年03月11日
    浏览(45)
  • javascript基础二十一:说说你对BOM的理解,常见的BOM对象你了解哪些?

    一、是什么 BOM (Browser Object Model),浏览器对象模型,提供了独立于内容与浏览器窗口进行交互的对象 其作用就是跟浏览器做一些交互效果,比如如何进行页面的后退,前进,刷新,浏览器的窗口发生变化,滚动条的滚动,以及获取客户的一些信息如:浏览器品牌版本,屏幕分

    2024年02月07日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包