DevLog1 AYRenderer
开发日志 AYRenderer
渲染Pass,VertexShader
模型矩阵与法线矩阵
在AYRenderer的UI界面中,用户可以自行设置渲染物体的 Transform :
Transform
这个 Transform 会形成所谓的 Model 矩阵,在顶点着色器(VertexShader)中会用到这个矩阵来对顶点进行变换。(即M变换)
当然所谓的顶点不只有位置和旋转的属性,还有法线属性,而法线的变换所对应的 Normal Matrix 则是 Model Matrix 的逆转置矩阵:
123Mat4 modelMatrix = object.transform.GetModelMatrix();// 法线矩阵是模型矩阵的逆转置矩阵Mat4 normalMatrix = modelMatrix.Inverse().Transpose();
我们来证明一下,首先假设模型空间中某顶点对应的切线为 t⃗,该切线可以由模型空间的两个顶点 A, B 表示: t⃗ = B − A.
经过模型变换后,对应的切线 $\vec{t'}$ 为: $$
\vec{t'}...
cpp八股1
cpp八股1
多态
什么是多态?C++中如何实现多态?
多态指的是同一个接口(在不同对象上)有着不同的行为。C++中多态分为编译时多态(静态多态)和运行时多态(动态多态)。
编译时动态顾名思义指的是在编译阶段就能决定哪个接口对应于哪个对象。
典型实现一:函数重载
注意返回值类型不参与重载判断
1234567891011121314151617#include <iostream>using namespace std;// 函数重载:同名函数根据参数不同实现不同行为int add(int a, int b) { return a + b;}double add(double a, double b) { return a + b;}int main() { cout << add(10, 20) << endl; // 调用 int 版本 cout << add(3.5, 2.7) << endl; // 调用 dou...
DesignPatterns
设计模式
资料来源于NJU研究生课程《高级软件设计》
设计模式指的是在软件工程中,针对特定问题的典型解决方案的一种标准化描述。
通常可分为三大类(Design Pattern Catalog): - 创建型模式:与对象创建有关:单例、工厂、抽象工厂等 - 结构型模式:将类或对象按某种布局组成更大的结构:装饰、适配器、外观、组合、代理等 - 行为型模式:类或对象之间怎样相互协作共同完成单个对象无法单独完成的任务,以及怎样分配职责:策略、状态、观察者、迭代器、模板、命令等
本文给出以上14个常用设计模式的cpp实现示例。
设计原则
单一职责原则(SRP,Single Responsibility Principle):一个类只负责一项职责
开闭原则(OCP,Open-Closed Principle):软件实体应对扩展开放,对修改关闭
里氏替换原则(LSP,Liskov Substitution Principle):子类对象必须能够替换掉所有父类对象
依赖倒置原则(DIP,Dependency Inversion Principle):高层模块不应该依...
ue-light-flicker
UE5 实现灯光闪烁效果
一种naive的想法是在蓝图用Timeline不断改变灯光的intensity属性。但最近在网上看到了一个更优雅的实现方式,使用灯光材质函数(Light Material Function)来实现。
具体实现如下,定义一个材质(不是材质函数),在Material Domain选择Light Function:
Light Function
你或许已经注意到了关键点,就是“Time”节点和“Sine”节点。具体数学原理如下: 1234567// 参数:Time(运行时间),RandomnessScale, FlickerSpeed, RandomnessShift, LowestBrightness T = (Time + RandomnessScale) * FlickerSpeed; // 时间基准S1 = sin( T * (RandomnessShift + 1.000) ); // 正弦波1S2 = sin( T * (RandomnessShift + 0.735) ); ...
quaternion
在游戏编程中,我们经常需要处理三维旋转。在UE编辑器中,我们常常通过直截了当地设置Pitch、Yaw和Roll来控制旋转。同时在数学运算中我们可以很自然地用一个正交3x3矩阵来表示旋转。 这篇博客将阐述另一个更加高效地表示三维旋转的工具:四元数(Quaternion)。
四元数
1. 复数
我们都知道复数,即 z = a + bi, z ∈ ℂ,其中 a, b ∈ ℝ,以及一个神奇的规定 i2 = − 1。
放到二维平面上来看,如果一个轴表示复数的实部 a,另一个轴表示虚部 b,那么复数 z 就可以表示为平面上从原点 (0, 0) 指向点 (a, b) 的一个向量:
complex1
由于我们要讨论的是四元数和三维旋转的关系。因此在这里,我们可以初步猜想,复数应该与二维空间的旋转有关。
复数加减应该都很熟悉,我们就不提了。来看看复数的乘法,前面我们提到一个神奇的规定 i2 = − 1。
因此,假设有两个复数 z1 = a + bi 和 z2 = c + di,它们的乘积为:
$$
\begin{aligned}
z_1 z_2 &...
lc-linkedlist
我们专门开个链表的算法题坑,方便总结在笔面试中可能会涉及到的链表操作。
在ACM中我们都用数组模拟双向链表,所以就不要嘲笑为什么我一个ACMer还要整理力扣的题了,是真不会啊。
Easy
求两个单向链表的相交点
力扣链接
一般链表的题,输入只给你一个指向链表头的头指针。但是这题我们要求两个单向链表的相交点,所以我们开始有两个头指针 headA 和 headB。
怎么求相交点呢?或许可以枚举第一个链表上的每个点,然后遍历第二个链表的每个点,看看二者是否有相同的地址。这种显然是 O(n2) 的。
有没有更简单的解法呢?假设我们目标是想出一个 O(n) 的解法,那么似乎我们遍历一次链表就 O(n) 了。
遍历完了然后呢?假设我们此时从另一个链表重新开始遍历,会发生什么?
假设链表A和链表B有共同后缀长度 z,而A的前缀长度为 x,B为 y,那么我们同时从头遍历链表 A 和 B,若到头了就从另一个链表重新开始遍历。
那么你会惊讶地发现,当我们这么遍历 x + y + z 步后,二者所在的点就是交互点!
也就是说,如果我们直接按照“遍历完当前链表就换链表遍历”...
LC2221-数组的三角和
原题 这题涉及到了一些求逆元的知识,我们刚好回顾一下。
首先很明显这题答案是: $$
\sum_{i=0}^{n-1} a_i C_{n-1}^i \bmod 10.
$$
数据范围也不大,可以暴力 O(n2) 求组合数,或者你直接模拟题意就行。
但作为Acmer必然要考虑更高效的做法。如果模数不是10而是一个质数 p,那么可以直接使用费马小定理来直接计算组合数分母的那些阶乘的逆元: $$
a^p \equiv a \space (\bmod \space p).
$$
但是这题的10显然不是质数,怎么办呢?诶,我们还有个欧拉定理: $$
a^{\phi(b)} \equiv 1\space (\bmod \space b),\gcd(a,b)=1.
$$
只要我们要求逆元的数 a 和10互质,就可以用欧拉定理求出它的逆元,即 aϕ(10) − 1 = a3.
可以考虑先将 a 中的质因子2和5全都提出。考虑我们要求的组合数 $C_n^m=\frac{n!}{m!(n-m)!}$,我们先考虑提出 m! 和 (n − m)! 中所有的2和5的质因子...
games101
Games101学习笔记
1. 线性代数
1.1. 线性变换
我们首先举个二维平面下的例子。
二维线性变换可以写为:
$$
\begin{aligned}
x' = ax + by. \\
y' = cx + dy.
\end{aligned}
$$
可以用矩阵 M 来表示: $$
\begin{bmatrix} x^{'}\\y^{'} \end{bmatrix}= \begin{bmatrix} a & b\\c & d \end{bmatrix} \begin{bmatrix} x\\y \end{bmatrix}.
$$
这里有一个小技巧,就是将两个基向量 (1, 0), (0, 1) 分别代入,得到 (a, c), (b, d) 就是这两个基向量经过变换后的向量,从而快速得到矩阵 M。
1.2. 齐次坐标(Homogeneous Coordinates)
在线性变换的基础上添加平移变换。
线性变换不能表示平移: $$
\begin{bmatrix} x^{'}\\y^{'} \end{bmatrix}=...
ASC and AS
目前GAS系列文章是在作者边学边实践的过程中的产出,因此未来100%会继续改善。
GAS-1
在这篇文章,我们来引进GAS系统中的两个部件。
Ability System Component
Ability System Component(ASC)是整个GAS系统中最基础的一个组件,它负责主要的对象与GAS的交互。在后续提及Gameplay Effect(GE)的时候,可以发现GE本身就是通过ASC进行施加的,同时这个过程中需要的 FGameplayEffectContextHandle 和 FGameplayEffectSpecHandle 都是通过ASC进行构建。不仅如此,ASC还和其所在类对应的AttributeSet,以及处理各种Gameplay Effect与使用技能Gameplay Ability都密切相关。因此对于一个角色,如果要将其加入GAS系统,你第一时间就是给予其一个Ability System Component。
ASC有两个代表Actor,分别是OwnerActor和AvatarActor,前者是实际构建(拥有)该ASC的Actor,...
GAS_Intro
Gameplay Ability System前置知识
再进入我们UE5特供的GAS插件之前,我们需要回顾一些关于虚幻的知识~
Controller
在我之前使用UE4制作一些demo的时候,我通常直接在要控制的Character类中,实现一些逻辑(如控制输入)。然而,受MVC设计模式的启发,对于我们要possess的Character(或者Pawn),应当尽量将逻辑与功能解耦合。
我自己举一个例子吧,例如在射击游戏中,可能存在固定位置的机枪、岸防炮,我们应当将这些作为Pawn的子类,因为它们需要被玩家控制。对于各自武器的特定功能,例如发射子弹或者炮弹,应当在Pawn中实现,因为它们是独立于Controller的。对于Controller,我们可以切换自己possess的pawn,例如在使用固定机枪前控制我们的角色,这时候可以进行移动,而使用机枪时,则可以控制机枪射击,无法进行移动。而这便是Controller的职责。(对于切换移动,我目测可以采用UE5的Enhanced Input系统,通过切换Input Mapping Context来实现。
当然,对于Contro...
