Unity Shader入门精要学习笔记:使用深度和法线纹理
前言
在进行边缘检测时,直接利用颜色信息会使检测到的边缘信息受物体纹理和光照等外部因素影响,得到很多我们不需要的边缘点。
我们可以在深度纹理和法线纹理上进行边缘检测,这些图像不会受光照和纹理的影响,仅仅保存了当前渲染物体的模型信息,通过这样的方式检测出来的边缘更加可靠。
获取深度和法线纹理
背后的原理
深度纹理实际就是一张渲染纹理,里面存储的像素值是高精度的深度值,由于被存储在一张纹理中,深度纹理中深度值范围为[0,1],通常是非线性分布的。
这些深度值来自于顶点变换后得到的归一化的设备坐标(NDC)。
看下面一组透视相机投影变换的过程图(使用的变换矩阵是非线性的),最左边是投影变换前(观察空间下视锥体的结构及相应的顶点位置),中间是应用透视裁剪矩阵后的变换结果(顶点着色器阶段输出的顶点变换结果),最右边是底层硬件进行了透视除法后得到的归一化的设备坐标。
看下面一组正交相机投影变换的过程图(使用的变换矩阵是线性的)
在得到NDC后,深度纹理中的像素值就可以很方便的计算得到了,这些深度值就对应了NDC中顶点坐标的z分量的值,由于NDC中z分量的范围在[-1,1],为了让这些值 ...
Unity Shader入门精要学习笔记:基于物理的渲染
引言
随着计算机的处理能力越来越强,人们开始考虑使用更加复杂的算法来渲染更加真实的画面。 在二十世纪八十年代左右, 基于物理的渲染技术(Physically Based Shading, PBS) 首次被引入图形学的正统研究中,学者们提出了使用光线追踪的方法来渲染全局光照,由此打开了精确渲染光线传播的大门。
在实时渲染领域, 人们也发现了这种基于物理的光照模型的巨大优势。 在这之前, Lambert光照模型、 Phong 光照模型和 Blinn-Phong 光照模型等经验模型占据了主流。 然而,这种不满足能量守恒的光照模型使得美术人员需要花费大量的时间在参数调节上。 尤其是, 美术人员往往好不容易为一个物体调节好了所有参数,使得它在当前的光照条件下看起来是满意的。然而, 一旦光照环境发生了变化, 这一切都得从头再来。 因此, 近年来游戏从业者开始着手把基于物理的光照模型应用于实时渲染中。
PBS的理论和数学基础
光是什么
在物理学中,光是一种电磁波。首先,光由太阳或其他光源中被发射出来,然后与场景中的对象相交,一些光线被吸收(absorption),而另一些则被散射(scatt ...
xasset 4.0入门指南
什么是xasset 4.0
众所周知,Unity资产管理方面的知识十分细碎,很多细节稍不注意就会导致资源冗余或者内存泄漏,很多前辈也在为解决这个问题不懈的努力。
今天为大家介绍的是之前有直播过的一个开源的Unity项目资源管里利器,因为它发布了新的4.0版本,支持了很多新的特性所以需要重新给大家再介绍下。
我本人的风格一向是从运行Demo开始,逐步分析理解它的架构,所以这个指南也不会一开始就从宏观上带大家去理解(其实是功课没做足,确实不知道是什么个情况 XD),不过有一说一,个人觉得以这种行文方式非常适合做入门指南
下载
https://github.com/xasset/xasset
git大家肯定都会用,如果速度慢,可以从我的xasset码云镜像拉取:https://gitee.com/NKG_admin/xasset_Gitsync.git
环境
游戏引擎: Unity 2019.4.0 LTF
.Net框架:.Net Framework 4.7.2
IDE:Rider 2019.3
xasset版本:截至此Commmit https://github.com/xasse ...
2020.2.3日记
铭记此时的温暖冬阳,奔向更加光明的未来。
对于C++/C#中的i++,++i性能问题探究(汇编分析)
前言
这阵子在看面经,里面有一道题,C中的i和i哪个效率更高。说实话,看到这道题当场就蒙了,平时用C#写项目都是怎么高兴怎么来,到C这里还有这一说了? 不懂就看答案,答案给出的是++i性能更高,理由是i++会有一次临时变量的分配消耗,存储初始i值用来返回,而++i则直接返回i+1后的值。 嗯,看上去很有道理,但是咱也不知道到底实现是不是这样的啊,看汇编去。
C++汇编分析
环境
C++环境:MinGW64 w64 3.4
CMake:Bundled 3.15.3
Debugger:MinGW-w64 GDB 7.8.1
IDE:CLion 2019.3.3
汇编语法:标准的GAS AT&T语法
优化等级 O0(无优化)
前提分析
C只在早期的时候借助C编译器把自己翻译成汇编语言,很久之前就有了自己的编译器,所以直接反编译得到的就是C的汇编代码。
测试用例
源代码
1234567int main(){ int i = 0; i++; ++i; return 0;}
汇编代码
123456789101112131415Du ...
对于游戏中的回放系统设计架构的畅想
前言
今天看到群友提出游戏回放功能怎么设计的问题,感觉挺有意思,胡思乱想片刻,就有了此文。
正文
什么是回放功能
回放功能也可以叫录像功能,指的是玩家可以从服务端拉取数据,然后在本地进行历史游戏的复现。 直观点的例子就是LOL的观战系统还有录像功能,R6或者OC里的死亡回放功能。
各种类型的回放区别
LOL的录像和观战都不是实时的,也就是说一个人并不能一边看录像,一边玩游戏。 R6和OC里的死亡回放是实时的,因为他是在游戏运行时进行的,玩家死了就要死亡回放。 这种差异也直接导致了实现难度的差异。 首先是LOL的录像,解决方案很简单,只需要保存每次玩家输入的消息以及那些会与客户端产生交互的信息,然后解析消息,向系统内发送信息即可。优点很明显,录像文件体积极小,当然了,这种方法也有很大缺点,无法保证回退到播放过的时间段时游戏中的各个实体状态是否与当时的游戏一致,因为并没有记录世界快照,回退也就无从说起了。也就是说,只能进,不能退。 但是OC的死亡回放单纯用上面那种方法却行不通,因为他是实时的,强硬的更改状态会破坏当前游戏逻辑顺序。只能保存每个时间点的世界快照,然后让客户端表现。 ...
接入Recastnavigation寻路到ET5.0
前言
因为Unity版本的更新迭代,老版本的A*插件在新版本Unity已经无法正常使用,包括一些运行时代码也已经过时,重新接入要花费很多时间,干脆接入一个新的寻路方案吧。
这里选择的是久负盛名的https://github.com/recastnavigation/recastnavigation,但因为他是基于C++的,所以我们要使用C#的P/Invoke来调用它的dll来实现寻路。
由于篇幅与操作复杂的原因,本文会更加注重大体的工作流程,而不会有太多细节上的图片,但是会有一个配套的详细教学视频供大家学习,视频链接:https://www.bilibili.com/video/bv1uK4y1E7CV。
C++/C#的桥接源码也会以在码云开源的形式分享给大家,完整的示例可以在我的Moba项目 https://gitee.com/NKG_admin/NKGMobaBasedOnET 中看到。
通过本文和配套视频你将能学习到recastnavigation的大体设计思路,使用方式,Unity/服务器接入recastnavigation的完整流程。
感谢@footman大佬在我学习过程 ...
C#对于非托管资源的释放原理探究
前言
我们都知道CLR有一个使用根的可达性算法的垃圾回收机制来回收托管内存,那么对于那些本机资源(非托管内存)他又是怎么清理的呢?
正文
要看他怎么清理资源,首先要知道这个资源是怎么来的,这里我们用FileStream这一经典类来探讨这些问题。 首先是它的构造函数
12345678910111213141516171819202122[SecuritySafeCritical]public FileStream(string path, FileMode mode) : this(path, mode, mode == FileMode.Append ? FileAccess.Write : FileAccess.ReadWrite, FileShare.Read, 4096, FileOptions.None, Path.GetFileName(path), false){}[SecurityCritical]internal FileStream( string path, FileMode mode, FileAccess access, Fi ...
数字图像处理复习纲要
第一章
1.数字图像的概念:
数字图像:数字图像是对连续图像数字化或离 散化的结果,也称离散图像
2.广义的图像处理(图像工程)包含的三个层次
3.像素的概念
一幅图像可分解为许多个单元。每个基本单元叫做图像元素,简称像素
4.灰度图像存储容量的计算
空间分辨率:图像的尺寸(M∗NM*NM∗N),在成像时采了MN个样,图像包含了MN个像素。
幅度分辨率:在成像时量化成了G(G=2kG = 2^kG=2k)个灰度级,存储一幅图像所需的位数b(b=M∗N∗kb = M * N * kb=M∗N∗k)(单位是bit)
第二章
1.像素的邻域
2.像素间距离,三种距离公式
像素间距离 :
欧氏距离(也是范数为2的距离):DE(p,q) = [(x − s)2 + (y − t)2]12D_E(p,q)\;=\;\lbrack{(x\;-\;s)}^2\;+\;{(y\;-\;t)}^2\rbrack^{\frac12}DE(p,q)=[(x−s)2+(y−t)2]21
城区距离(也是范数为1的距离): D4(p,q) = ∣x − s∣ + ∣ ...
数据结构篇:邻接表
每一个顶点后面就是一条链表,每个顶点都存在数组里。 以这张图为例 结构如下 运行截图 结构体定义
12345678910111213141516171819202122 //边表结点typedef struct EdgeNode { //顶点对应的下标 int adjvex; //指向下一个邻接点 struct EdgeNode *next;} edgeNode;//顶点表结点typedef struct VertexNode { //顶点数据 char data; //边表头指针 edgeNode *firstedge;} VertexNode, AdjList[100];//集合typedef struct { AdjList adjList; //顶点数和边数 int numVertexes, num ...