自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(117)
  • 收藏
  • 关注

原创 Unity-NavMesh详解-其一

注意:Region 虽然是不重叠且没有洞的区域,但仍然有可能是凹多边形,无法保证 Region 内任意两点在二维平面一定可以直线到达。后续需要进行轮廓生成和凸多边形生成,为寻路做准备。在这个阶段结束时,我们有形成简化多边形的轮廓。顶点仍然在体素空间中,但是我们正在回到向量空间的路上。许多算法只能用于凸多边形。因此,这一步将构成轮廓的简单多边形细分为凸多边形网格。这是通过使用一个适用于简单多边形的三角形划分(triangulation),然后再将三角形合并为最大可能的凸多边形来实现的。

2025-06-10 16:26:01 840

原创 Unity-ECS详解

今天我们来了解Unity最先进的技术——ECS架构(EntityComponentSystem)。Unity官方下有源码,我们下载源码后来学习。ECS与OOP()对应,ECS是一种完全不同的编程范式与数据架构,ECS​(实体-组件-系统)以数据驱动为核心,通过组合与分离逻辑提升性能,适用于高并发场景。总的来说,如果场景内有大量的对象或者数据需要处理,我们就可以用ECS来完成以大大提高计算效率。当然,这里还是要提一嘴相关概念,关于DOTS:DOTS是以的高性能开发生态。

2025-06-09 19:07:41 787

原创 Unity-UI组件详解

今天我们来学习Unity的UI的详解,这部分的内容相对较少,对于程序员来说主要的工作是负责将各种格式的图片呈现在显示器上并允许操作这些图片。本篇帖子的理论依据依然是官方开源的UGUI代码,网址为:GitHub - Unity-Technologies/uGUI: Source code for the Unity UI system.我们首先来认识一下UGUI,全称​:Unity GUI,开发者习惯称其为UGUI,大体上可以根据功能分为这么几个部分:在工作流程中各个层的作用:我们在Unity或者说UGUI中

2025-06-03 16:39:12 879

原创 LearnOpenGL-笔记-其十三

什么是基于物理的渲染?简单地说,还记得我们之前学习的法线贴图的内容吗?我们希望不修改物体实际几何形状的前提下去修改表面的法线方向来实现不同的光照效果,实现这个内容的基础就是我们的光照效果是基于某个光照模型——比如布林冯模型来做的,但是这种渲染模式某种意义上不会让你觉得很繁琐吗?因为他太不真实了——物体的光照模型是模拟出来的,然后光照效果也是模拟出来的,我们能否换一种更真实的做法来渲染呢?

2025-06-02 20:31:54 996

原创 LearnOpenGL-笔记-其十二

看起来似乎非常复杂,但是其实本质上就是:当我们开启SSAO功能之后,我们的屏幕上会多一层四边形,也就是铺屏四边形,这个四边形会检查每一个在屏幕里的像素:准确地说是以每个像素为球心扩展出一个球,然后我们在这个球内容去采样后检查采样点和像素的深度进行比较,比如这个球内采样了一百个点,六十个的深度值小于该像素深度而四十个大于,那么这个像素的遮蔽因子就是0.4,也就是他只会收获到正常亮度的百分之六十。,它是我们渲染物体的一种非常直接的方式,在场景中我们根据所有光源照亮一个物体,之后再渲染下一个物体,以此类推。

2025-05-31 17:33:07 1102

原创 LearnOpenGL-笔记-其十一

又到了介绍法线贴图的地方,我感觉我已经写了很多遍了...法线贴图用最简单的话来介绍的话,就是通过修改贴图对应物体表面的法线来修改光照效果,从而在不修改物体实际几何形状的前提下实现不同于物体几何形状的视觉效果。因此对于法线贴图来说,最重要的内容就是去修改法线贴图对于物体表面的法线。这是我们在物体的片元着色器实现的内容,就是根据法线贴图的内容更换法线。

2025-05-30 23:34:17 983

原创 LearnOpenGL-笔记-其十

这时候我们就实现了基本的阴影渲染了,这个渲染的过程就是我们先根据之前生成的深度贴图获取到各个片元到摄像机的深度值,然后我们再正常进行渲染的过程,如果这个片元处于阴影之下(深度值更大)我们就把该片元的亮度减小,也就是形成阴影的效果,这样我们就能实现基本的阴影效果了,但是这个效果很“硬”,也就是边缘会产生锯齿。如果我们使用立方体贴图会怎样?我们的纹理是基于显示器的RGB空间来实现的,如果我们采用手动伽马矫正,那么虽然我们的显示器亮度颜色空间变成了线性空间,但是我们的纹理就会收到影响变成完全不同的效果。

2025-05-30 22:02:49 1074

原创 Unity引擎源码-物理系统详解-其三

今天我们来深入了解一下PhysX引擎底层的具体实现,当然话是这么说,但显然我的能力有限,不太可能在这么短的时间全部融会贯通,我就说一下我自己的视角能看到的东西吧。首先整个PhysX引擎干的事情非常简单:就是物理的模拟,那么我们想象一下自己生活中的真实情况:我们在生活中把物体分为了固液气三种形态,于是PhysX也要对物体有一个基本的分类:在计算机中,这样分类的根本原因是为了去写相关的数据结构,比如液体和固体,你写相关基类的时候显然需要的内容不一样。

2025-05-25 11:57:52 939

原创 Unity-编辑器扩展-其二

ShaderUtil.GetVariantCount是Unity编辑器内部的一个方法,通过反射获取后可以计算指定着色器的变体数量,它通过分析着色器中的#pragma multi_compile和#pragma shader_feature指令,考虑变体之间的依赖关系和平台限制,计算所有可能的组合数量。反射就是程序在运行时可以对元数据进行访问的一个机制,然后像我们着色器变体的信息也是以元数据的形式存储在当前程序集的,理论上我们通过反射可以获取所有程序集中涉及到的所有类型对象方法的内容。

2025-05-21 16:24:12 1004

原创 Unity-编辑器扩展

学会了操作Unity编辑器的基本操作后,我们来尝试自己写出一个Inspector界面:这是我们正常的Inspector界面。Chinese,English这个脚本定义了一个枚举和一些变量,其Inspector如图://target指该编辑器类绘制的目标类,需要将它强转为目标类} }//GUI重新绘制效果如图:不难看出这段函数中最重要的内容就是EditorGUILayout这个函数://定义序列化属性。

2025-05-20 22:31:14 1072

原创 剑指Offer-部分题详解

于是就出现了这样的代码:直接和nums[r]进行比较,大的话说明你在左半区,小的话说明你在右半区,相等说明你遇到了之前所言的情况:相等时我们就直接移动右指针,这样如果此时中间值在右半区你的移动就是正确的,哪怕是在左半区,只要你的右指针遇到那个不重复的数字,也就是最小值,那么你就可以触发第一个情况从而得到答案。因为我们要从小到大排列只包含2,3,5作为因子的数,那么我们可以用三个指针分别代表2,3,5,然后成立一个动态规划数组,挨个取最小值更新即可。非常的干净整洁啊,其中n是当前人数而m是要数的个数。

2025-05-19 15:02:08 574

原创 Unity引擎源码-物理系统详解-其二

继续我们关于Unity的物理系统的源码阅读,不过这一次我们的目标是PhysX引擎——这个Unity写了一堆脚本来调用API的实际用C++写成的底层物理引擎。下载后发现由三个文件组成:其中blast主要是负责实现爆破、破坏效果计算的部分,flow则是负责实现流体效果,physX则是主题。PhysX是一个内容非常繁多的引擎——其本质就是一堆API和封装好的算法,如果生硬地去学那么很快就会不知所措,你上学的时候也没人会叫你去背字典吧。

2025-05-14 22:02:18 1109

原创 Unity引擎源码-物理系统详解-其一

从今天开始我们要对Unity下手了:想要在后续的开发中执行,扩展Unity的内容,我们得先学习Unity的内容。目前主流的商业引擎中,Unity和UE就是最热门的。我大概率后续会出UE的部分,但是现在让我们先学习Unity引擎吧。Unity的源码并没有完全公开,我们阅读公开的部分。源码来自于Github。一个引擎中是有多个系统组成的,比如渲染系统,物理系统,UI系统,动画系统等等,显然我也没有精力进行全面的学习,所以我们先挑一些重要的系统的部分进行理解。

2025-05-13 14:44:48 977

原创 Unity-Shader详解-其五

这里的边缘光强度计算的内容可能比较难以理解,我们先用法线和视线方向进行一个点积之后调整该值到[0,1]之间,然后根据宽度和亮度来调整光强,这里我们采用了幂次计算,宽度作为幂,那么宽度值越小则光强越小,同时注意我们的base是一减去点积,意思就是法线和视线的夹角越大则光强越强(夹角越大则越边缘),我们通过这些函数实现了边缘光越边缘强度越大的效果。第一个函数,我们首先计算一个屏幕的高宽比,然后把uv的x轴和y轴各减去0.5之后乘以这个比值,因为我们知道uv坐标是一个从0到1的坐标系,所以这样能得到正确的向量。

2025-05-08 15:34:08 905

原创 Unity-Socket通信实例详解

今天我们来讲解socket通信。首先我们需要知道什么是socket通信:Socket本质上就是一个个进程之间网络通信的基础,每一个Socket由IP+端口组成,熟悉计网的同学应该知道IP主要是应用于IP协议而端口主要应用于TCP协议,这也证明了Socket通信是一个多个层共同工作的过程。总结:Socket是网络编程的基石,通过简单API抽象底层协议,实现进程间灵活高效的数据交换。

2025-05-07 14:43:47 1183

原创 Unity-Shader详解-其四

今天我们来聊Unity特有的表面着色器以及很少提到的几何着色器。

2025-05-05 14:35:54 1200 1

原创 Unity-Shader详解-其三

今天我们继续Unity的Shader部分。

2025-04-29 14:39:00 858

原创 Unity-Shader详解-其二

前向渲染和延迟渲染总的来说是我们的两种主要的渲染方式。

2025-04-26 22:58:22 1018

原创 Unity-Shader详解-其一

今天我们来介绍Unity的一大核心组件:shader。

2025-04-26 20:46:07 960

原创 Unity-无限滚动列表实现&&Timer时间管理实现

然后在我们的update里,我们会把准备加入数组的计时器加入数组并清空另一个数组,然后对数组中每一个计时器执行Update函数(前文已定义),最后我们批量删除满足IsDone的计时器。第三个函数计算两次更新之间的时间间隔。渲染函数中,我们先移除头部尾部元素,之后如果链表的长度为0则一口气填充所有可视区域,否则我们就填充滑动离开列表的空缺,对于已经离开列表的元素我们进行清除。GetIndex函数的作用是根据具体的坐标得到具体的序号,RoundToInt的用法就是一个基于四舍五入的将浮点数转换成整数的方法。

2025-04-23 22:01:24 971

原创 C++手撕STL-其四

这里可以看到存在一种哈希表的最坏情况,这个就是哈希表的键设置有问题,最极端的情况下,所有值被放入一个键中,这个时候哈希表就退化成链表,复杂度来到On,不过这种情况极少发生,正常情况下哈希表的增删查改都将是O1复杂度。对于Unordered_set来说,我们依然先计算出插入的值的哈希值,然后来到对应的桶,我们会遍历桶中的元素,如果发现有相等的值我们就会终止插入操作,这就是我们实现unordered_set去重的方法。而中括号的重载的作用就是返回对应键值对的键的值,可能有点绕。

2025-04-23 15:18:07 923

原创 C++手撕STL-其叁

然后我们是一个返回缓冲区大小的函数,一个是否允许随机访问的变量(之前的vector中出现过),数据类型,指针,引用,数据大小,指针差异(之前vector都有),然后是一个T**的数据类型(T**是什么呢其实就是一个指向T类型指针的指针(从右往左看))变量map_pointer,这里他指向的自然就是我们的中控数组(确切地说,数组指针)。这是deque的大体代码,其中的map_pointer类型就是我们的中控数组类型,size_type类型的map_size则是表明我们的中控数组具体可以容纳多少指针。

2025-04-22 22:10:46 723

原创 Unity-GC详解

可以看到两种编译方式的主要区别就在于CIL(中间语言)到机器码之间的这个过程,Mono方案是生成JIT/AOT而IL2CPP是生成C++,具体区别如图所示,简单的说就是Mono最大的好处就是支持热更新,其他不论性能还是安全性IL2CPP都更高一筹。我们都知道Unity是用C#写成的,或者说我们的源码是C#构成的,按照正常的流程,我们要将代码进行编译后再汇编才能变成机器可以阅读的机器码。大多数我们使用的容器都支持动态扩容,那么每次动态扩容都会涉及到堆上的内存分配,所以尽可能地我们去减少容器的扩容。

2025-04-22 13:11:09 899

原创 C++手撕STL-其二

这是一个拷贝构造函数、拷贝赋值运算符重载、移动构造函数、移动赋值运算符重载的示例,可以看到拷贝和移动最大的区别就是我们的参数中一个是&代表左值引用,一个是&&代表右值引用,这也是我们在实例化对象后决定具体是调用移动还是拷贝的重要判断条件:我们根据传入的参数具体是左值还是右值来决定是调用拷贝还是移动。所谓的右值,顾名思义似乎就是等号右边的值,常常用等号的朋友都知道,等号的作用是把等号右边的值赋给左边,那么按理来说,左边的值作为接受值的值,当然就要求得有地址、是持久的;要知道很多变量之类的东西可都是左值呀。

2025-04-19 14:43:44 870

原创 C++手撕STL-其一

C++作为我们的老朋友,伴随我们从18岁的懵懂无知到23岁的找不到工作,今天就让我们来手撕一下基本的STL!

2025-04-18 17:55:07 1476

原创 杂记-LeetCode中部分题思路详解与笔记-HOT100篇-其四

我们的p0和p1分别是0和1的边界,显然我们的p1会始终在p0右边(当然也有可能重合(数组内无0的时候)),有1我们就移动p1,有0的话我们移动p0的同时还要检查p1的位置,因为如果有1的话我们移动的p0的值就是1(这是一定的),所以我们swap值为0的值时还要多一层考虑。那今天我们就把Hot100的所有题都完结了吧,Hot100作为大多数人笔试题的入门之选,可以说是非常的经典了,但是俗话说得好,书读百遍,其意自现,我不支持反复地只刷部分算法题,但是我支持周期性地刷刷写过的题,会有新收获的。

2025-04-18 15:40:02 736 2

原创 杂记-LeetCode中部分题思路详解与笔记-HOT100篇-其三

这里最难的部分其实是想到用双向链表来标记最长时间未使用的数据,这样我们可以直接把虚拟头结点的上一位丢掉,没有更繁琐的步骤。我们要将二叉树退化成链表且要求链表的顺序符合先序链表,我们从根节点出发遍历所有节点,往左检查,如果当前根节点的左节点的值大于当前节点,我们就得丢到右边去,那么我们首先从左节点开始,往右边遍历到最后一个节点,然后把根节点的整个右子树接到左节点的最后一个右节点,然后再把整个左节点搬到右节点去:这么复杂的操作,无非是保留右子树的结构的同时把左节点换到右边,然后我们继续遍历左边的节点即可。

2025-04-17 20:45:43 1000

原创 Unity-Xlua热更和AssetBundle详解

从今天开始我们深入Unity的组件,最近的一系列事让我明白学习技术不能只有广度,如走马观花,虽然你可能确实学到了皮毛,但是没有足够深厚的理解,是无法融入自己的东西的,那么你就只是在用别人的工具而不是自己的工具,对于追求技术的人来说,这是无法接受的。不多废话,我们来到第一个部分。

2025-04-08 21:20:25 1270

原创 LearnOpenGL-笔记-其九

我们可以看到,我们生成VBO之后,我们从指向模型变换矩阵的数组指针开始,我们需要单独取出每个子碎石的VAO来绑定庞大的模型变换矩阵数组,我们从layout=3的位置开始一行一行地读取,然后每一个实例都要更新一个实例ID,因为一个顶点数据的最大大小为vec4,所以我们需要四个顶点数据组成完整的mat4变量。小行星带,显然难的不是行星而是行星带比较难处理,当我们想象行星带时,我们很容易想到大量的碎石,显然这些碎石的数量远远大小我们的Uniform的数据大小上限(非常大的数量级)。

2025-04-06 22:35:22 1036

原创 LearnOpenGL-笔记-其八

默认的顶点数组数据,我们之前默认是交错进行处理,也就是比如前3个数据,第一个代表位置,第二个代表颜色,第三个代表纹理坐标,然后我们的第四个数据就会是第二个顶点的位置,第五个数据就是第二个顶点的颜色...现在让我们换种方式来做,我们将所有的顶点位置数据放置在整个数组的前方,颜色数据放置在整个数组的中部,纹理坐标放置在整个数组的尾部。以上代码是我们一个接口块的定义方式,可以看到我们用in或out来定义我们是输入还是输出,然后是这个接口块的类型名,内部写好要传输的变量,最后再写上这个接口块的实例名。

2025-04-01 15:14:43 665

原创 LearnOpenGL-笔记-其七

简单地说,我们的面剔除就是负责得到立方体的哪些面是被摄像机所观察到的而哪些没有被观察到,对于没有被摄像机观察到的面,我们没有必要去浪费时间渲染。现在的问题是:我们要如何得知我们哪些面是摄像机能看到的哪些是不能被看到的呢?是的,本质上来说其实我们就是利用我们定义三角形时的顶点索引顺序来确定这个面是正面还是反面,从而确定哪些面可以被剔除而哪些面不可以被剔除。OpenGL已经为我们封装好了面剔除方法,我们只需要去开启即可。

2025-04-01 12:40:05 628

原创 LearnOpenGL-笔记-其六

今天我们来聊一些更深入的东西

2025-03-28 15:32:04 592

原创 LearnOpenGL-笔记-其五

今天我们来学一些关于模型加载的内容:之前的内容中,我们始终使用我们的两个图片作为我们的操作对象(笑脸和箱子),但现在让我们来考虑导入一些真正的cool的模型。

2025-03-27 20:19:06 819

原创 代码随想录-训练营-day52

之前我们涉及的迪杰斯特拉算法和贝尔曼福德算法都是针对单源最短路径的,而当问题来到多源的最短路径时这两种算法就不适用了。针对多源最短路径问题,我们一般用floyd算法或者A星算法。这个就是A星算法了。

2025-03-15 20:34:48 227

原创 LearnOpenGL-笔记-其四

因为其实这两个变量的本质是两个角度的余弦值,对于余弦函数,在九十度以内(你的内切角的范围只会在零到九十度),你的角度越小你的余弦值越大。我们之前讨论的光源都是一个点光源,简单的光源非常方便我们进行整个光照过程的模拟和研究,但是在实际的环境中,一个理想化的点光源是可遇不可求的。光照贴图的概念其实非常简单,简单地说,我们希望不同的材质拥有不同的光照属性,所以不同的材质要应用不用的光照贴图,最常见的有我们的漫反射贴图和镜面反射贴图。最后我们讨论的光源是聚光,聚光就是只在一定范围内的光,离开这个范围就不可见。

2025-03-14 15:25:04 424

原创 代码随想录-训练营-day51

其实不难理解,按理说我们的算法正常情况下经过n-1次松弛之后,再怎么松弛我们的最小距离数组也不会进行更新了,但是出现负权值的回路时他依然会去更新,我们只需要在完成n-1次松弛之后再进行一次松弛判断最小距离数组是否发生变化即可。核心的做法是没有太多变化的,最明显的区别就在于我们:一是用邻接表来构建图,二是使用了一个队列和一个bool数组记录了每个点相邻的点,这样我们可以每次只松弛遍历的点的相连的边,也就是把一些无用的松弛操作给取消了。这个题在存在负权回路的基础上,还有一个设定是我们的松弛次数是有上限的。

2025-03-14 09:42:38 268

原创 代码随想录-训练营-day50

但是对于最短路径来说存在一个问题就是:我们不仅仅是要记录所有的边,还需要去记录边的权值,且需要去根据边的权值进行一个选择,也就是出现一个排序的需求。所谓的松弛,其实本质上就是根据当前节点到该节点的权重总和与该节点的最小权重作比较实现更新,我们把除了源节点以外的所有节点都更新一次就可以得到对于所有点来说的最小权重,而不是像贪心算法一样去遍历相邻节点之间的最小权重。就像之前的最小生成树的算法有存储点状态的Prim算法和存储边状态的K算法一样,我们的最短路径算法也应该去考虑去存储边的状态。

2025-03-13 11:23:38 244

原创 代码随想录-训练营-day49

总的来说核心点有三个:找到入度为0的节点、移除入度为0的节点、根据最后结果数组的大小是否等于节点数判断有向图中是否有环。可以看到我们的迪杰斯特拉算法在思路上来说和之前的最小生成树的prim算法类似,说白了本质上都是贪心算法的思维底座。开始进入我们的最短路径问题了,今天我们接触的是经典的迪杰斯特拉算法。上来是一道拓扑排序的题,什么是拓扑排序呢?

2025-03-13 10:24:47 141

原创 LearnOpenGL-笔记-其三

在之前的章节中我们学习了基本的窗口构建方法、着色器的定义与使用以及摄像机的构建,而从今天这个大章节开始我们要来学习光照有关的知识。

2025-03-12 20:16:47 1101

原创 LearnOpenGL-笔记-其二

鉴于之前学习的效率太低,我决定采用效率更高,见效更快的学习方法来学习我们的OpenGL章节。

2025-03-11 23:47:53 676

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除