[游戏中的图形学实时渲染技术] Part1 实时阴影技术
原理篇:
常见的渲染方程如下:

在不考虑自发光项与考虑阴影对于着色结果的影响之后可以将方程变化为如下形式:
如果射线在到达光源前击中了其他物体时,就认为这条来自光源的光线对着色点没有贡献。

利用上述渲染方程进行正确的着色和阴影计算是非常耗时的因为它需要进行积分,因此在光栅化的实时渲染中需要对该方程进行简化:
(微积分的近似公式)

Image
而通过该方程可以将着色和阴影分开,也就是说,可以在先计算着色,在此基础上再乘上阴影计算的结果,即可近似正确的表示阴影。
基础篇:
1. Shadow Mapping
渲染阴影场景涉及两个主要的绘图步骤。第一个生成阴影贴图本身,第二个将其应用于场景。根据实施(和灯的数量),这可能需要两次或更多次绘图过程(多次绘图指的是场景中存在多个光源)。
shadow mapping 的基础原理:
总结:Shadow Mapping的原理是首先将场景从光源的视角进行深度图的渲染,然后再从观察者的视角进行渲染,并使用深度比较来检测可见性并生成阴影。
Shadow Mapping的基本步骤如下:
- 从光源视角渲染深度图:先将相机移动到光源位置,以光源为视点向场景中渲染深度图,即从灯光的角度生成一个视锥体,然后对视锥体内的场景使用透视投影矩阵进行投影。
- 生成阴影贴图:将深度信息保存,并将结果存入一个纹理,作为阴影贴图

Image
- 从相机视角渲染场景:现将相机移回到视点位置,在进行场景渲染前需要将阴影贴图传递给着色器

Image
- 计算阴影:在片元着色器中,使用深度测试函数来检查当前像素是否被光源照射到。首先通过使用当前片元的深度值与阴影贴图中对应位置处的深度值进行比较,如果当前像素被遮挡则该像素被认为是在阴影中,否则它处在光照下。
示例:
下图是第一个渲染 pass 中渲染出的光源

Image
下图示从相机视角,第二个 pass 中渲染场景深度图

Image
由此可以进行下一步深度比较,计算阴影操作。
传统shadow mapping 的问题
1.精度问题
在shadow mapping 由光源点生成的一张深度图中,由于深度图的本质是一张纹理,而纹理是一种离散化的数字信号,从深度图还原源场景深度信息时难免对发生精度不同的问题。

Image
而由于精度原因容易产生自遮挡的问题。
自遮挡问题产生的原因是:

Image
解决方案:

Image
上面左图显示了这种自遮挡的现象大多出现在原本没有阴影的地方。这些地方本该直接被光源照的,但却出现了条纹状的阴影。其原因是光源是倾斜照射的,并且Shadow Map产生的深度图的分辨率有限。
解决方案是容忍一段区间的遮挡物,即将阴影图中的深度值偏移一段。这一段距离就称为bias,如下。
但这种情况的 bias过大变会造成上面右图的人物的模型和阴影没有连上的情况。
此外还有一种解决方案是Games202中讲解的学术界(工业界中不用)中用的一个解决方法:
记录最小深度和次小深度的平均,作为后续的深度进行比较。

Image
工业界不用的原因
- 要求物体双面渲染(这在游戏中完全不可能),有正面就得有反面,面片也得做成box
- 开销太大,可能并不值得,虽然O(n),但是GPU里面并行处理下会爆炸(不过实时渲染不注重复杂度只注重速度)
问题: 必须要是两面的
2.走样问题

Image
由于单一的shadowmap会存在精度不足,我们在性能与效果中平衡提出Cascade Shadowmap技术。
Cascade Shadow Mapping是一种用于实时渲染的实时阴影技术。通常在实时渲染中,光源(如太阳)的影响区域比较大,如果只使用单个深度图(Shadow Mapping)来计算阴影,很容易出现阴影质量不佳或者阴影断层的问题。而阴影CSM技术可以将一个视锥体分割成多个级别,每个级别使用不同的投影矩阵和深度贴图来计算阴影,从而提高阴影的质量和稳定性。
阴影CSM的基本原理如下:
将摄像机的视锥体划分为多个子视锥体:将摄像机的视锥体沿着近裁剪面到远裁剪面进行划分,将每个子视锥体映射到一个具有固定大小的2D矩形区域内。
对于每个子视锥体,渲染深度贴图:对于每个子视锥体,使用投射矩阵将场景渲染到一个深度贴图中,并保存深度值信息。
计算阴影:对于每个像素,使用与Shadow Mapping类似的算法来比较深度贴图中对应点的深度值和当前像素与光源的距离,来判断该像素是否被阴影所遮盖。
合并结果:将所有子视锥体的阴影贴图进行合并,并将阴影应用于场景中的对象。
中等篇
软阴影的形成

Image
umbra:
本影指的是阴影最里面的区域,它看起来是最暗的。换句话说,本影代表光完全被阻挡体阻挡的阴影部分。
Penumbra:
半影是一个 物体阴影的一部分,其中只有一部分光束被遮挡体阻挡。半影区就是我们在图形学中的软阴影部分
antumbra:
是指遮挡物体似乎完全位于光源的中心区域内。 (这在咱们的文章中不做讲解)
理想中的点光源会造成硬阴影,但是现实中的光源由于本身存在体积,会形成拥有半影区的软阴影。
硬阴影与软阴影之间的关系不是简单地将阴影的边缘模糊化处理,而是由于现实生活中的光源都存在一定的面积和体积,而这种面积和体积会产生软阴影。
更多自然世界中的阴影的知识可以从下面链接中了解。
什么是影子:13 个有趣的事实 -zh-cn.lambdageeks.com/how-is-shadow-formed/#um编辑
PCF的原理

Image
如图,上图为硬阴影,下图为软阴影。
PCF相对于传统的shadow mapping 做了那些改变::
之前的ShadowMapping过程中,假设现在得到了一张阴影图,接下来需要对一个着色点的深度 �(�) 和阴影图的采样结果 �(�) 作比较,得到一个二元的结果即为在阴影中为1,不在阴影中为0。正因为这种二元性,才产生了硬阴影的没有过渡(或者说走样现象)。
PCF的做法是得到阴影图后,如下图所示,选择一个以该着色点映射在阴影图中的位置为中心的 n x n 的filtering(核),用这个着色点的深度值 �(�) 分别和filtering中每个深度值的采样结果 �(��) 进行比较,最后得到一个 n x n 的二元比较结果,再对这个 n x n 的二元的比较结果进行filter(平均),最终得到这个着色点的阴影可见性的值,而这个结果不再是非0即1的值,而是一个在(0,1)之间的浮点数。
总结:
PCF技术通过对阴影贴图进行采样的方式,对像素周围的多个采样点进行插值和混合,从而更加准确地确定每个像素点的阴影强度。具体而言,PCF方法将每个像素的阴影采样点划分为一个网格区域,并在每个区域内进行多个采样。通过对这些采样点的深度值进行比较和插值,可以得到一个更加平滑和准确的阴影效果。
这项技术的重点在如你去如何理解Filtering(本质上是平均)的意义。在这个过程中,Filtering的尺寸决定了阴影的软硬程度。Filtering的尺寸越大,得到的阴影越软,尺寸越小,得到的阴影越硬,如下图可见。

Image
经过PCF之后就可以得到一个相对真实的阴影结果。基本上不会存在错误!

Image
PCF的缺点与改进措施概述
在实时的渲染中PCF的致命缺点是慢,原本的在shadow map贴图中的一次查找变成了 7乘7 甚至是 9乘9 的像素。
所以,如果想在实时渲染中使用这种方式的软阴影技术需要对渲染过程进行优化:
在抗锯齿的是时候的第一个算法一定是SSAA,但是这样抗锯齿处理算法需要4倍的显存...,但是MSAA其举出思想依旧是一个像素点采样多次,但从原来的全部整个屏幕全部的像素,变成了屏幕画面的边缘部分。
PCF的优化也是同理-如下图,软阴影与硬阴影的之间的变化随着阴影的投射物(笔杆)与阴影的接受物(书本)的距离有关

Image
(由此我们就可以引出PCSS,即在阴影生成过程中 blocker distance <-> Filter size呈现一定的关系)
PCSS的原理
PCSS 是非常经典的一个制作软阴影的算法
PCSS的核心原理是根据光源大小和着色点与遮挡物的距离自适应调节PCF的滤波核大小。阴影边缘的滤波核大小由半影距离决定,如下图所示。 通过相似三角形原理可知, 半影距离由光源的尺寸 、光源与遮挡物的距离 、以及着色平面与遮挡物的距离决定。
下图用来详细说明对应的数学公式来源,通过相似可以得到 ��������� 而我们通过 ��������� 的大小就可以对应出filtering 的大小。 ��������� 越大 filtering 就越大。

Image
PCSS首先假定光源是一个区域光,传统的点光源,聚光灯和平行光,都对应着某种模拟但从广义上来讲他们依旧是属于面光源。
����������=(��������−��������)∗����ℎ�/��������
那么根据上面的操作我们可以总结PCSS生成软阴影的步骤:
● 步骤1:Blocker Search 某个着色点连向光源,找到shadow map上该像素周围一块区域的纹素所记录的深度值,把区域所有texel都找一遍,判断是不是遮挡物,如果是遮挡物,则累加,最后除以遮挡物的个数,以这个平均值作为遮挡物的深度即上面的 �������� 。
● 步骤2:Penumbra estimation 用$d_{Blocker}$计算得到 ���������� ,从而计算得到filtering尺寸
● 步骤3:PCF 利用filtering尺寸,进行可见性值的计算。
注意在可见性计算部分可以,最简单的可以从周围的取若干像素信息然后平均混合;也可以根据一定比例插值;比如按照泊松分布来进行采样。
PCSS算法的优化
在PCSS算法中步骤1与步骤3比较慢。
step1 寻找 blocker的效率低下 step3 在 filtering 进行采样依旧是很耗费性能。
优化方法1:稀疏采样 缺点:由于稀疏草药会出现噪点,需要在最后在图像空间上做一次滤波。稀疏采样计时滤波之后会产生抖动。
优化方法2:对于PCSS计算的过程中做一系列的近似操作,这就引出了VSSM (Variance Soft Shadow Mapping)
VSSM的原理
VSSM的核心思想是快速寻找 blocker and filtering ,他的快速寻找是通过一系类近似操作降低时间复杂度。
可见性值的优化处理: 在刚刚步骤3的核心是找到着色点的可见性值,而可见性值是通过,p的深度值 �(�) 在阴影图中的filtring �� 中排第几。换句话说,需要得到 �(�) 占 �� 的百分比。
近似处1
我们将深度值,近似的设想为正态分布,正态分布图像由期望和方差决定(也就是说我们只要知道Filtering中深度值的期望与方差就可以大致知道深度分布的一个情况)。
剩下的全部问题在于期望(均值)和方差的获取。
- 期望通过 SAT和mipmap。
- 方差,数学公式计算 �(�)=�(�2)−�2(�) :
一块区域的平均值(方差)的计算:
使用MipMap
优点:
- 快速、近似、正方形
缺点:
- 插值结果只是近似。当查询区域在某层上不太对齐像素格的时候,需要双线性插值。
- 当查询的范围不为2的n次方时,还要再进行一次层间插值,即三线性插值
- 如果查询区域是长方形区域查询,还得加入各向异性过滤
使用SAT (类似算法中的前缀和) Summed Area Table可以用来高效地计算图像上任意矩形区域内所有像素值的和,而不需要遍历该区域内的每个像素。这对于一些需要频繁计算图像区域总和的算法非常有用,如图像滤波、特征检测等。
具体来说,Summed Area Table是通过对原始图像进行一次积分得到的。对于给定的像素坐标(x, y),Summed Area Table中该位置的值表示了原始图像中从(0, 0)到(x, y)的矩形区域内所有像素值的累积和。换句话说,Summed Area Table中的每个元素表示了其左上角矩形区域内所有像素值的累积和。
特点:
- 百分百准确范围查询结果,但是计算花销较大
得到 E(X) 和 D(X) 之后我们就有了正态分布图像,接下来就需要计算可见性。
可见性值的计算
我们需要通过正态分布,确认百分比数值(可见性值)。
在概率论中,PDF(概率密度函数)为连续型随机变量的概率密度函数,CDF(累积分布函数)为概率密度函数的积分。
也就是说,对于一个值x,只需要求出CDF(x),就可以得到百分之多少的值是小于x的,即1 - 可见性的值。

Image
CDF一般比较难计算,VSSSM又找到一个不等式对它进行近似,即切比雪夫不等式:
�(�>�)≤σ2/(σ2+(�−μ)2)
所以有:
���=1−�(�>�)≈1−�2�2+(�−�)2
同时切比雪夫不等式有一个苛刻的假设:t必须在均值的右边。
(当笔者做到这里的时候有一个疑问:把阴影区间的分布的CDF(x)为什么不将正态分布图像转变为标准正态分布后查表得出呢QAQ)
VSSM加速PCF步骤的总结:
- 生成shadow map的同时,生成一张存放深度的平方的平方深度图(Square depth map)。两个通道分别存放即可,不需要额外一张texture,
- 求深度图上某区域的均值,MipMap或者SAT,O(1)
- 求平方深度图上某区域的均值,依旧MipMap或者SAT,O(1)
- 知道均值,根据公式得到方差
根据切比雪夫不等式直接求出该点可见性Visibility
VSSM 的问题
VSSM 做了很多的假设,所以会存在种种的问题。
比如漏光(Light leaking)
当物体的深度不是呈现正态分布的时候会出现的问题。这是一个很明显的错误,(为了解决该问题可以使用Moment shadow mapping)

Image
虽然VSSM很快,但是准确度有些堪忧。
高级篇
距离场软阴影
距离场,它反映了任意一个点到某个物体的最小距离。将它可视化后如下:

Image
优点:
- 快速(查询快)
- 质量高
缺点:
- 需要预处理(慢)
- 需要大量存储空间
ray-SDF intersection
在ray marching的过程中,是解求光线打到物体上的点。
SDF(p) 是点 p 到达最近表面的距离,在ray marching过程很重要的概念是步长,每一次射线前进的距离就是步长也就是SDF(p)。正因如此,就可以认为SDF(p)为点p的“安全距离":从点p出发,按任意方向走SDF(p)距离,都不会碰到物体。 有了“安全距离”的概念后,选定一个起点 �1 后和方向后,按方向走 ���(�1) 距离到 �2 ,再按方向走 ���(�2) 距离,递归直到打到物体。(我们认为当直线与最近平面的距离小于某一个值的时候就是大中了物体)

Image
Distance Field Soft Shadow
SDF还可以应用在软阴影中。在软阴影中,我们用SDF来近似得到一个着色点被遮挡物遮挡的程度。 我们引入"安全角度“的概念:将光源抽象成面光源,从着色点 P沿某方向 ���� 看向光源,将光线从 ���� 朝物体方向旋转最大角度 � ,光线不会打到物体,则 � 为”安全角度“。
那么 � 的计算如下:
对于光线上任意一点Q,它的”安全距离“为SDF(Q),则”安全角度“为光线方向和着色点到圆切线的角度。 于是,安全角度的大小可以反映阴影的软硬程度(Visibility)。安全角度越小,遮挡越多,越趋近于硬阴影。安全角度越大,遮挡越少,越趋近于软阴影。

Image
如上图所示,安全角度的求解方法
问题又变成了如何求 � ?一种思路是求反三角函数,
�=���������(�)|�→−�→|
用简单的乘法运算去近似该公式
�=min�⋅���(�)|�→−�→|,1.0 。 这个近似式的k项,它决定阴影的软硬程度。当k小时, ���(�)|�→−�→| 需要更大的值(更少区间)才能>=1,最终映射到1。当k大时, ���(�)|�→−�→| 只需要较小的值(更多区间)就能>=1,最终映射到1。也就是说,k越大反映阴影更硬。

Image
参考:
- Real-Time Rendering 4th Edition-2018-英文版
- http://www.ownself.org/blog/2010/percentage-closer-filtering.html
- games202
- https://www.yuque.com/gaoshanliushui-mbfny/sst4c5/sl2q1b#49a7623c
相关文章:
[游戏中的图形学实时渲染技术] Part1 实时阴影技术
原理篇: 常见的渲染方程如下: 在不考虑自发光项与考虑阴影对于着色结果的影响之后可以将方程变化为如下形式: 如果射线在到达光源前击中了其他物体时,就认为这条来自光源的光线对着色点没有贡献。 利用上述渲染方程进行正确的着…...
NtripShare Mos地铁自动化监测终端盒子硬件设计
自动化监测产品到目前为止做了接近一年,在软件层面上,控制终端软件、平台软件、网平差算法都已解决,硬件盒子始终是心里过不去的坎,最终还是没有耐住性子自己做了一把。 选型如下: 1、主板:瑞芯微RK3568主板。 2、外…...
第 117 场 LeetCode 双周赛题解
A 给小朋友们分糖果 I 动态规划:设 p [ k ] [ i ] p[k][i] p[k][i] 为将 i i i 个糖果分给 k k k 个小朋友的方案数,先求 p [ 2 ] [ i ] p[2][i] p[2][i] ,再求 p [ 3 ] [ n ] p[3][n] p[3][n] class Solution { public:using ll long …...
OpenCV C++ 图像处理实战 ——《多二维码识别》
OpenCV C++ 图像处理实战 ——《多二维码识别》 一、结果演示二、zxing库配置2.1下载编译三、多二维码识别3.1 Method one3.1.1 源码3.2 Method two3.2.1 源码四、源码测试图像下载总结一、结果演示 </...
经典算法(查找与排序)
查找 顺序查找 顺序查找(Linear Search)是一种在有序数组中查找目标元素的基本算法。它的时间复杂度为 O(n),适用于查找少量数据。顺序查找的基本思想是从数组的第一个元素开始,逐个与待查找的元素进行比较,直到找到…...
微软和Red Hat合体:帮助企业更方便部署容器
早在2015年,微软就已经和Red Hat达成合作共同为企业市场开发基于云端的解决方案。时隔两年双方在企业市场的多个方面开展更紧密的合作,今天两家公司再次宣布帮助企业更方便地部署容器。 双方所开展的合作包括在微软Azure上部署Red Hat OpenShift…...
ZYNQ_project:IP_ram_pll_test
例化MMCM ip核,产生100Mhz,100Mhz并相位偏移180,50Mhz,25Mhz的时钟信号。 例化单口ram,并编写读写控制器,实现32个数据的写入与读出。 模块框图: 代码: module ip_top(input …...
Leetcode刷题详解——优美的排列
1. 题目链接:526. 优美的排列 2. 题目描述: 假设有从 1 到 n 的 n 个整数。用这些整数构造一个数组 perm(下标从 1 开始),只要满足下述条件 之一 ,该数组就是一个 优美的排列 : perm[i] 能够被…...
[PHP]Kodexplorer可道云 v4.47
KodExplorer可道云,原名芒果云,是基于Web技术的私有云和在线文件管理系统,由上海岱牧网络有限公司开发,发布于2012年6月。致力于为用户提供安全可控、可靠易用、高扩展性的私有云解决方案。 用户只需通过简单环境搭建,…...
C/C++数字判断 2021年9月电子学会青少年软件编程(C/C++)等级考试一级真题答案解析
目录 C/C数字判断 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 C/C数字判断 2021年9月 C/C编程等级考试一级编程题 一、题目要求 1、编程实现 输入一个字符,如何输入的字符是数字&#x…...
云栖大会丨桑文锋:打造云原生数字化客户经营引擎
近日,2023 云栖大会在杭州举办。今年云栖大会回归了 2015 的主题:「计算,为了无法计算的价值」。神策数据创始人 & CEO 桑文锋受邀出席「生态产品与伙伴赋能」技术主题,并以「打造云原生数字化客户经营引擎」为主题进行演讲。…...
如何用java写一个网站:从零搭建个性化网站
随着互联网的迅猛发展,Java作为一种强大而灵活的编程语言,为构建各类网站提供了丰富的解决方案。本文将探讨如何使用Java编写一个个性化网站,并通过具体实例进行深入分析。 第一步:选择适当的技术栈 在着手构建网站之前࿰…...
Easyui DataGrid combobox联动下拉框内容
发票信息下拉框联动,更具不同的发票类型,显示不同的税率 专票 普票 下拉框选择事件 function onSelectType(rec){//选中值if (rec2){//普通发票对应税率pmsPlanList.pmsInvoiceTaxRatepmsPlanList.pmsInvoiceTaxRateT}else {//专用发票对应税率pmsPlan…...
力扣学习笔记——11. 盛最多水的容器
链接:https://leetcode.cn/problems/container-with-most-water/ 11. 盛最多水的容器 给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线,使得它们与 x 轴共同构成的…...
Spring Boot: 约定优于配置的软件设计思想
文章目录 传统Spring框架的繁琐配置1. **管理jar包依赖**2. **维护web.xml**3. **维护Dispatch-Servlet.xml配置项**4. **应用部署到Web容器**5. **第三方组件集成到Spring IOC容器中的配置项维护** Spring Boot的简化与自动化1. Spring Boot Starter启动依赖2. 自动装配机制3.…...
TCP触发海康扫码相机S52CN-IC-JQR-NNN25
PC环境设置 为保证客户端正常运行以及数据传输的稳定性,在使用客户端软件前,需要对 PC 环境 进行设置 关闭防火墙 操作步骤如下: 1. 打开系统防火墙。 2. 在自定义设置界面中,选择关闭防火墙的对应选项,并单击…...
ArcGIS:如何迭代Shp文件所有要素并分别导出为Shp文件?
01 前言 尝试用IDL实现,奈何又涉及新的类IDLffShape,觉得实在没有必要学习的必要,毕竟不是搞开发,只是做做数据处理,没必要拿IDL不擅长的且底层的东西自己造轮子。 这里想到使用Python去解决,gdal太久没用…...
[工业自动化-11]:西门子S7-15xxx编程 - PLC从站 - 分布式IO从站/从机
目录 一、什么是以分布式IO从站/从机 二、分布式IO从站的意义 三、ET200分布式从站系列 一、什么是以分布式IO从站/从机 在工业自动化领域中,分布式 IO 系统是目前应用最为广泛的一种 I/O 系统,其中分布式 IO 从站是一个重要的组成部分。 分布式 IO …...
Linux技能篇-yum源搭建(本地源和公网源)
文章目录 前言一、yum源是什么?二、使用镜像搭建本地yum源1.搭建临时仓库第一步:挂载系统ios镜像到虚拟机第二步:在操作系统中挂载镜像第三步:修改yum源配置文件 2.搭建本地仓库第一步:搭建临时yum源来安装httpd并做文…...
电脑清灰涂硅脂后电脑CPU温度不降反升
目录 一.问题描述二.问题解决三.拆机注意事项四.影响散热的主要因素说明1.通风差2.硅脂材料差3.硅脂涂抹方式错误 一.问题描述 电脑型号:暗影精灵5 测温工具:硬件狗狗(只要是测温软件都可以,比如omen hub和Core Temp…࿰…...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
C++_核心编程_多态案例二-制作饮品
#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
Admin.Net中的消息通信SignalR解释
定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...
UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
企业如何增强终端安全?
在数字化转型加速的今天,企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机,到工厂里的物联网设备、智能传感器,这些终端构成了企业与外部世界连接的 “神经末梢”。然而,随着远程办公的常态化和设备接入的爆炸式…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...
