0%

为了写一个半透明物体的shader,有以下几点基础要求:

  1. 更近的不透明物体要挡住透明物体。因此透明物体需要深度测试来决定是否渲染。
  2. 透明物体不能挡住透明物体。因此透明物体之间不能进行深度测试来剔除渲染,即透明物体不能写入深度开启深度写入,透明物体错误地挡住透明物体
  3. 既然不能写入深度,不透明物体与透明物体之间的渲染顺序就十分关键。如果更远的不透明物体晚一点渲染,其会不合理地挡住更近的透明物体(因为透明物体没有写入深度值)。因此需要分离渲染顺序队列
  4. 透明物体之间的顺序问题。当然Unity也知道顺序很关键,由于没有fragment-level的顺序信息,因此unity会对透明物体按object-level从远到近排序,再进行渲染。这通常没有问题,但是当两个透明物体的深度是交叉的时候就会产生错误。因此理想解决方案是顺序无关透明(order independent transparency, OIT),即逐像素排序。 透明物体之间的渲染顺序错误。交叉地带应该由A覆盖B,实际上由于B的中心点更近,因此其所有fragment都在A之后渲染,导致B错误的覆盖A。
阅读全文 »

在三维空间中描述旋转是一件挺麻烦的事。常用的欧拉角虽然直观简单,但是存在顺序依赖万向节死锁的问题,在通用的旋转运算上并不可行。进而引入的四维数虽然在运算上很有效,但是对于第一次见到的人来说一点也不算直观、易懂。

Krasjet的文章从二维复数出发,进而理解三维四元数的表示意义,循序渐进,通俗易懂,因此记录一下学习笔记。

复数与2D旋转

复数的定义和运算性质不再赘述。对于$ z = a + bi $,相当于对复数基底 $ (1,i) $ 的线性组合,因此可以表示为一个列向量 \(z=[a,b]^T\),但更进一步,其实我们能把复数表示为矩阵。

对于两个复数\(z_1 = a + bi , z_2=c + di\),可以得到观察一下其乘法结果:

\[ \begin{aligned} z_1z_2&=a \boldsymbol{c} -b \boldsymbol{d} \\ &+(b \boldsymbol{c}+a \boldsymbol{d})i \\ &=\left[\begin{array}{cc} a & -b \\ b & a \end{array}\right]\left[\begin{array}{l} c \\ d \end{array}\right] \end{aligned} \]

我们知道右边的\([c,d]^T\)\(z_2\)的列向量表示形式,而左边的矩阵,也只和\(z_1\)的系数有关,因此也可以看做是\(z_1=a+bi\)的矩阵表示。我们不妨尝试将两边都写成矩阵形式:

\[ z_1z_2=\left[\begin{array}{cc} a & -b \\ b & a \end{array}\right] \left[\begin{array}{l} c & -d\\ d & c \end{array}\right] =\left[\begin{array}{cc} ac-bd & -(bc+ad) \\ bc+ad & ac-bd \end{array}\right] =ac-bd + (bc+ad)i \]

上式可以看出\(z_1,z_2,z_1z_2\)在矩阵表示下也同样满足复数基本运算。这时我们可以发现一个神奇的现象:复数可以表示为矩阵,复数乘法可以表示为矩阵乘法,而矩阵乘法进而可以让我们联想到矩阵表示的仿射变换:

\[ z=\left[\begin{array}{cc} a & -b \\ b & a \end{array}\right] =\sqrt{a^2+b^2} \left[\begin{array}{cc} \frac{a}{\sqrt{a^2+b^2}} & \frac{-b}{\sqrt{a^2+b^2}} \\ \frac{b}{\sqrt{a^2+b^2}} & \frac{a}{\sqrt{a^2+b^2}} \end{array}\right] \]

这种式子是不是很眼熟——即以a,b为边的三角变换式:

\[ z=\sqrt{a^2+b^2}\left[\begin{array}{cc} cos\theta & -sin\theta \\ sin\theta & cos\theta \end{array}\right] =\left[\begin{array}{cc} ||z|| & 0 \\ 0 & ||z|| \end{array}\right] \left[\begin{array}{cc} cos\theta & -sin\theta \\ sin\theta & cos\theta \end{array}\right] \]

此时复数\(z=a+bi=||z||(cos\theta+sin\theta i)\)表示的二维变换水落石出,左边的矩阵是一个 等比放缩矩阵,右边的矩阵是一个 旋转矩阵复数乘法,即是两个变换矩阵的作用。

并且再将复数的三角形式代回\(z_1z_2\)可知,\(z_1z_2=cos(\theta+\alpha)+sin(\theta+\alpha) i\) ,即复数的累乘,在变换上体现为旋转角度的累加\(\theta+\alpha\),以及缩放上的累乘。

阅读全文 »

看到几篇很棒的博客,如何阅读——刘未鹏怎样花两年时间去面试一个人,想要从中汲取一些知识,并且记录一些自己的思绪。

学习的方向

其实现在的在校生根本不缺学习的动力(特别是计算机,特别是研究生),毕竟现在的大环境已经卷的不成样子。看着各大公司的招聘简历,以及相关面经,会发现大学的课程完全不足以培养你进入大厂工作,如果真只是按部就班上完了全部课程,那恭喜你达到了新成就毕业即失业。在这个能力为硬指标的行业,但凡对工作有所期望的人,都会想方设法去学习更多的东西,起码面试三轮可以有能力通过一轮吧。

阅读全文 »

  • Liu Z, Lin Y, Cao Y, et al. Swin transformer: Hierarchical vision transformer using shifted windows[C]//Proceedings of the IEEE/CVF International Conference on Computer Vision. 2021: 10012-10022.
  • 微软

在视觉中做Transformer有两大问题,图片比起语言分辨率过高,以及图片中的目标尺度有大有小,变化很大。为了解决这两个问题,Swim Transformer一方面做了多分辨率的层级式结构,另一方面设计了 shift of the window partition between consecutive self-attention layers

多分辨率层级结构
shifted window:l+1层相对与l层,其子窗口划分进行了偏移。由于在新的一个子窗口内进行自注意力计算,会设计到上一级的多个窗口,因此提供了窗口的连接性。
阅读全文 »