<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>InverseDa Blog</title>
        <link>https://blog.inverseda.top/</link>
        <description>分享我的小碎念</description>
        <lastBuildDate>Thu, 01 Aug 2024 02:11:28 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>zh-CN</language>
        <copyright>All rights reserved 2024, InverseDa</copyright>
        <item>
            <title><![CDATA[Git压缩提交]]></title>
            <link>https://blog.inverseda.top/article/git-rebase</link>
            <guid>https://blog.inverseda.top/article/git-rebase</guid>
            <pubDate>Mon, 17 Jun 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[Git的压缩提交可以将多个提交commit压缩成一个，在工作中比较实用，原理是利用rebase的交互功能。]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-295dbce160de47228daba69ca53d0e2e"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-text notion-block-2671c0b67fed495cb898e700c80eb47f">在 Git 中，你可以使用强大的 <code class="notion-inline-code">interactive rebase</code>（交互式 rebase）将多次提交合并成一次。</div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-aab51dfc14ce45739b09b045823d83c3" data-id="aab51dfc14ce45739b09b045823d83c3"><span><div id="aab51dfc14ce45739b09b045823d83c3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#aab51dfc14ce45739b09b045823d83c3" title="命令行"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">命令行</span></span></h2><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-a5d59b19d1d44f1f992f171c9b0d8f64" data-id="a5d59b19d1d44f1f992f171c9b0d8f64"><span><div id="a5d59b19d1d44f1f992f171c9b0d8f64" class="notion-header-anchor"></div><a class="notion-hash-link" href="#a5d59b19d1d44f1f992f171c9b0d8f64" title="选择起始commit"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">选择起始commit</span></span></h3><div class="notion-text notion-block-21fd6fdc12be45de9707f9f4ef5d1366">N是从HEAD开始想要合并的提交的数量（从最近的一次提交往前数）</div><div class="notion-text notion-block-de8c822e96a44b36a8fe78be289d8991">假如：</div><div class="notion-text notion-block-d4ed91476a7340b6a4c410aba09611fb">我们需要达成这样的Git树：</div><div class="notion-text notion-block-0c5b864211db4b21b2e48705dba3aaca">那么需要用到：</div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-14f3b4f260fb494ea0474127c46d874a" data-id="14f3b4f260fb494ea0474127c46d874a"><span><div id="14f3b4f260fb494ea0474127c46d874a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#14f3b4f260fb494ea0474127c46d874a" title="交互"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">交互</span></span></h3><div class="notion-text notion-block-8b8617f4ac054e9ab06add78566329e2">在vim上会弹出：</div><div class="notion-text notion-block-385831f5325f42e29a5a831e7e75a9c6">我们只pick最老的commit，其他的commit都squash：</div><div class="notion-text notion-block-56781378a6ba484388511b3e416ed27f">:wq保存关闭</div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-f0260b2dcc2b4d16a36a5c34a8b4cc5f" data-id="f0260b2dcc2b4d16a36a5c34a8b4cc5f"><span><div id="f0260b2dcc2b4d16a36a5c34a8b4cc5f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#f0260b2dcc2b4d16a36a5c34a8b4cc5f" title="创建新commit"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">创建新commit</span></span></h3><div class="notion-text notion-block-a0ae9918215743ba954836586d3527e8">接下来直接创建一个新的commit，然后提交即可。</div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-d233ea9be3584229be7ea08523f29a6d" data-id="d233ea9be3584229be7ea08523f29a6d"><span><div id="d233ea9be3584229be7ea08523f29a6d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#d233ea9be3584229be7ea08523f29a6d" title="一个更简单的方法"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">一个更简单的方法</span></span></h3><div class="notion-text notion-block-494f7a709a294bd7ac9730c06475ed49">可以不用squash而是fixup，他直接帮你忽略掉了其他提交信息，只需要push即可（不需要再创建新的提交而是直接push）：</div><div class="notion-text notion-block-c336b4d1158e48728813d6366002e245">然后保存，直接git push -f即可。</div><div class="notion-blank notion-block-0ae50b613d4f40989d1d4b8495b662ea"> </div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[旋转变换]]></title>
            <link>https://blog.inverseda.top/article/quant</link>
            <guid>https://blog.inverseda.top/article/quant</guid>
            <pubDate>Tue, 30 Jan 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[旋转矩阵是常用的旋转手段，但由于万向节死锁问题，现在普遍的游戏引擎采用的是四元数。]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-852d7531ae3b469f9802a9896b800a1c"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-row"><a target="_blank" rel="noopener noreferrer" class="notion-bookmark notion-block-6b1f4f84898d47438ead36beef0cae8a" href="https://en.wikipedia.org/wiki/Gimbal_lock"><div><div class="notion-bookmark-title">Gimbal lock</div><div class="notion-bookmark-description">Gimbal lock is the loss of one degree of freedom in a multi-dimensional mechanism at certain alignments of the axes. In a three-dimensional three-gimbal mechanism, gimbal lock occurs when the axes of two of the gimbals are driven into a parallel configuration, &quot;locking&quot; the system into rotation in a degenerate two-dimensional space.</div><div class="notion-bookmark-link"><div class="notion-bookmark-link-icon"><img src="https://www.notion.so/image/https%3A%2F%2Fen.wikipedia.org%2Fstatic%2Fapple-touch%2Fwikipedia.png?table=block&amp;id=6b1f4f84-898d-4743-8ead-36beef0cae8a&amp;t=6b1f4f84-898d-4743-8ead-36beef0cae8a" alt="Gimbal lock" loading="lazy" decoding="async"/></div><div class="notion-bookmark-link-text">https://en.wikipedia.org/wiki/Gimbal_lock</div></div></div><div class="notion-bookmark-image"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fupload.wikimedia.org%2Fwikipedia%2Fcommons%2F4%2F49%2FGimbal_Lock_Plane.gif?table=block&amp;id=6b1f4f84-898d-4743-8ead-36beef0cae8a&amp;t=6b1f4f84-898d-4743-8ead-36beef0cae8a" alt="Gimbal lock" loading="lazy" decoding="async"/></div></a></div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-d73bbc0251934cea90b438f1d5b08cee" data-id="d73bbc0251934cea90b438f1d5b08cee"><span><div id="d73bbc0251934cea90b438f1d5b08cee" class="notion-header-anchor"></div><a class="notion-hash-link" href="#d73bbc0251934cea90b438f1d5b08cee" title="二维旋转矩阵"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">二维旋转矩阵</span></span></h2><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-a825931df79843cfaeadacfccf135c71"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:288px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F5b41901f-d076-4365-8497-44b4b7efff50%2FUntitled.png?table=block&amp;id=a825931d-f798-43cf-aead-acfccf135c71&amp;t=a825931d-f798-43cf-aead-acfccf135c71&amp;width=288&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-9c2f216f71764ebaa9e13fd626a920b5">考虑两个向量<!-- -->和<!-- -->，设旋转矩阵为<!-- -->，就需要满足：</div><div class="notion-text notion-block-8a85be4d2526451ea451c248b06142c0">因此可以得出，旋转矩阵是一种正交矩阵，满足：</div><div class="notion-text notion-block-c0fdfdbce6af49bda3e0f1ae894cd2e7">并且满足：</div><div class="notion-text notion-block-8ef3de192ca04ee68943c42ffc4135f2">为什么旋转矩阵的行列式为1？这是因为行列式本质是一种缩放因子，而旋转矩阵是一种变换坐标基的操作，所以也就是相当于旋转了坐标系，因此并没有发生缩放，所以值就是1。</div><div class="notion-text notion-block-d070bd6689a44c13afe0b167f5949247">另外，任何旋转矩阵都可以写成反对称矩阵A的指数：</div><blockquote class="notion-quote notion-block-d2ed83348c6140afa0fae3e970da2445"><div>反对称矩阵是一种转置矩阵和自身加法逆元相等的矩阵，简单来讲：</div></blockquote><div class="notion-text notion-block-850a886656f64afcb49032451185304a">在<!-- -->维空间内，上述结论仍然成立，这里不展开证明了（非常简单）</div><div class="notion-text notion-block-bf1fb6dd0ba74781a5bea0b1933648c8">那具体在二维情况下旋转矩阵的值是多少呢？</div><div class="notion-text notion-block-66c0d8b83da14f1f989a963be31f83dd">二维情况下，旋转矩阵是一种关于旋转角度<!-- -->的函数（矩阵是可以定义为函数的，类似于透视函数）：</div><div class="notion-text notion-block-8b34f98a24964626b1d692f6cb6c0549">证明如下：</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-e9d0234fbaa14fabb1402713f5304993"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:288px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F5a8266da-574e-4b52-984c-bdf30955d8d4%2FUntitled.png?table=block&amp;id=e9d0234f-baa1-4fab-b140-2713f5304993&amp;t=e9d0234f-baa1-4fab-b140-2713f5304993&amp;width=288&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-ef580fc262b54e198d75617df4f1cd06">假设从<!-- -->旋转到<!-- -->：</div><div class="notion-text notion-block-93d41c73304f4ece91e4e73dc976c28b">从而推出：</div><div class="notion-text notion-block-fa3cfa107d8d4b01930a8f7bf532424b">写成线性变换的形式：</div><div class="notion-text notion-block-b26939e992da4dd588c8056f80d24698">这就是二维旋转矩阵了，可以验证这个矩阵满足行列式为1.</div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-8a4123cf75934d1e92b39f126431366d" data-id="8a4123cf75934d1e92b39f126431366d"><span><div id="8a4123cf75934d1e92b39f126431366d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#8a4123cf75934d1e92b39f126431366d" title="三维旋转矩阵"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">三维旋转矩阵</span></span></h2><div class="notion-text notion-block-d61d5fc7cb6143278d2470f06e6ce805">三维旋转的复杂度会大大提高，主要是需要确定旋转轴。在二维上的旋转，只有绕z轴旋转（这里暂时不引入OpenGL的标架）的情况。但在三维，会有饶x、y、z轴旋转的情况。其实推导很简单，就是类似于二维旋转。</div><div class="notion-text notion-block-bd99e74c038440e68f3d569e0f664331">并且，三维旋转可以细分为旋转矩阵表示、欧拉角表示和四元数表示。</div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-d7d7c3ec6d094443a14e2f4180ec7929" data-id="d7d7c3ec6d094443a14e2f4180ec7929"><span><div id="d7d7c3ec6d094443a14e2f4180ec7929" class="notion-header-anchor"></div><a class="notion-hash-link" href="#d7d7c3ec6d094443a14e2f4180ec7929" title="旋转矩阵表示"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">旋转矩阵表示</span></span></h3><div class="notion-text notion-block-9978d1310f1943b89c67f66f7079c214">如果用旋转矩阵表示，需要分三种情况：饶x、y、z轴旋转的情况</div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-be6467580769463da30ace1e689ee67c" data-id="be6467580769463da30ace1e689ee67c"><span><div id="be6467580769463da30ace1e689ee67c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#be6467580769463da30ace1e689ee67c" title="欧拉角"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">欧拉角</span></span></h2><div class="notion-text notion-block-0ed3bcd0eae149babd7c2b640329fcce">如果用欧拉角表示，则需要定义三个欧拉角roll（<!-- -->）、pitch（<!-- -->）和yaw（<!-- -->）：</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-5154d6edda7f44979c469556348ed31c"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:384px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F8a424c28-dd31-4a0e-bba6-523865d5b601%2FUntitled.png?table=block&amp;id=5154d6ed-da7f-4497-9c46-9556348ed31c&amp;t=5154d6ed-da7f-4497-9c46-9556348ed31c&amp;width=384&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-c74b89aed335413481aefa2ad273e708">在三维情况下旋转可以用欧拉角<!-- -->表示。可分为动态欧拉角和静态欧拉角，两者均有万向节死锁问题。</div><div class="notion-text notion-block-e3ddabb7f2ad42809fb813033c689227">欧拉角的定义基于旋转矩阵，它规定了物体的旋转次序只能有xyz的组合，即：xyz，xzy，yzx，yxz，zxy，zyx。这里举的例子是xyz。</div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-a819d550d1bb4f3baef436912813d723" data-id="a819d550d1bb4f3baef436912813d723"><span><div id="a819d550d1bb4f3baef436912813d723" class="notion-header-anchor"></div><a class="notion-hash-link" href="#a819d550d1bb4f3baef436912813d723" title="静态欧拉角"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">静态欧拉角</span></span></h3><div class="notion-text notion-block-ca5316fa811b491ea03a6ca940f6e004">静态欧拉角是根据世界坐标系的三个坐标轴xyz为基准进行旋转的，这三个坐标轴是不会变化的，始终是相互正交的，因此可以这样描述静态欧拉角：</div><div class="notion-text notion-block-cbc3e404e0be42f7b53a8f0d32ba59c0">计算得出：</div><blockquote class="notion-quote notion-block-697bc7e3d2ed4a7b88fb6ea83d9ddf38"><div>一个有趣的数学现象，所有静态欧拉角的旋转矩阵，如果我们把矩阵的列单独拿出来看，可以发现矩阵的三个列分别对应了旋转之后的xyz轴分别在原本的xyz轴上的映射的分量。</div></blockquote><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-f61e5d9410a2433bb689561b5dafa02c" data-id="f61e5d9410a2433bb689561b5dafa02c"><span><div id="f61e5d9410a2433bb689561b5dafa02c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#f61e5d9410a2433bb689561b5dafa02c" title="万向节死锁"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">万向节死锁</span></span></h4><div class="notion-text notion-block-22bd9ce1f2224cb18878c67b13f848a7">那为什么静态欧拉角会发生万向节死锁呢？坐标轴不是固定的吗？按理来说不应该出现自由度消失的情况。</div><div class="notion-text notion-block-d67e35e753584b4394115c45716a1294">其实我们一直都理解错了。欧拉角一个重要的概念就是，他每次的旋转变换都是以最初的姿态为初始状态变换的。我们从数学上和本质上去理解为什么会出现万向节死锁。</div><ul class="notion-list notion-list-disc notion-block-ed609e82481842fdabf60706a16a5b9d"><li><b>数学</b></li></ul><div class="notion-text notion-block-887780b9841a4154a4e2223a87988611">假设先沿着x轴旋转<!-- -->，然后沿着y旋转90度，最后绕z轴旋转<!-- -->，其欧拉角用旋转矩阵表达为：</div><div class="notion-text notion-block-9605a54b230c4d95bd9024e6fdeca040">这里比较直观的发现，最后的结果不包括<!-- -->了，这说明我旋转的情况和z轴无关，我仅仅通过x和y就能得到这样的结果。</div><ul class="notion-list notion-list-disc notion-block-a49eee04184f483cb9f300c5adc35c8d"><li><b>本质</b></li></ul><div class="notion-text notion-block-e41347daf81d45d98b13c6cbf8bb1c14">欧拉角一个重要的概念就是，他是一个完整的变换。也就是每次变换，都要经过<!-- -->的乘法操作。什么意思呢？假如初始状态顶点坐标为<!-- -->，三个欧拉角为<!-- -->，我们要旋转到<!-- -->，那么就需要一个个操作，操作次序也就是：</div><div class="notion-text notion-block-163a0beeee5644cdacb62dfe7c972da5">可以发现被变换对象一直都是<!-- -->，说明不是在原有的基础位姿上变换的！</div><div class="notion-text notion-block-dc9566106ffa4e4d8bb4d53412c4134d">然后旋转到<!-- -->，也是同样的道理：</div><div class="notion-text notion-block-ecd6d95a8f6f428791228d2a43387a94">然后我们会发现每一个操作，都要先重新绕x轴旋转一次。虽然很冗余，但这是欧拉角旋转的定义。并且这也间接的告诉我们接下来的关键问题。</div><div class="notion-text notion-block-3f5312f3f29b4ccbbab38fd5146e3ae1">将<!-- -->旋转到<!-- -->，操作次序：</div><div class="notion-text notion-block-7fa16f097ac34da1aa208d360bbeea13">看出来了？其实不是在你原有的欧拉角基础<!-- -->变换后的位置计算旋转，他要重新通过你最初始的姿态计算一遍。这个时候我们发现，假设<!-- -->，我们是在y调整之前，先调整的x旋转<!-- -->。也就是当y的角度还没到90度的时候，先调整的x。这和我们预期不符合，最终姿态看样子像是绕着z轴旋转了（因为经过y轴旋转90度之后的z轴和原来的x轴重合了）。这就是万向节死锁。</div><blockquote class="notion-quote notion-block-31fac56bb5674d3b82af663e1e0e712f"><div>操作次序只是为了方便理解，让你知道欧拉角旋转始终是从初始姿态计算的，实际上程序直接计算最后一步。</div></blockquote><div class="notion-text notion-block-294fb2c801ac40038848a64b1ee666aa">下面是两个简单的解释：</div><blockquote class="notion-quote notion-block-ddd2833a68c64c1fa30b2ea8e45f8903"><div>简单来说，你以为旋转的结果是：X（10）Y（90）X（10）</div><div class="notion-text notion-block-f5eb2e32d30046cfabe860b7565fab70">实际上的游戏引擎计算的结果却是：</div><div class="notion-text notion-block-c7c3f68962364b30bb31c9e4b9937000">X（10）X（10）Y（90）</div><div class="notion-text notion-block-2e542dcc233548e584c8612726a4d83b">或者：</div><div class="notion-text notion-block-3ce3eaa5843e4903adeca39404473362">X（20）Y（10）</div><div class="notion-text notion-block-479f252819a14b86896ee58f3e3451f9">（这里的XYZ不是R_XR_YR_Z，只是表达一下直觉上的感受）</div></blockquote><blockquote class="notion-quote notion-block-092a39fa904e4697b091eef7bf617ae2"><div>你想要的顺序:X1→Y→Z→X2
实际顺序:X1→X2→Y→Z
欧拉角本身不是问题，用欧拉角这个状态表示方式去表示了过程才导致了问题</div></blockquote><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-7f83e577cb4f4d75832f7bd66188400c" data-id="7f83e577cb4f4d75832f7bd66188400c"><span><div id="7f83e577cb4f4d75832f7bd66188400c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#7f83e577cb4f4d75832f7bd66188400c" title="动态欧拉角"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">动态欧拉角</span></span></h3><div class="notion-text notion-block-355c4b4214ab44439f9d000cbfe8e13d">动态欧拉角是根据自身物体的坐标轴为基准实现的旋转。可以用陀螺仪表示：</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-72855a80990f4845b0f8a037837ed902"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:200px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4be83dcd-960d-4522-a017-1dbc5e80b360%2F8ed2cdc6-fc43-4b07-baa0-323ce565fd33%2FUntitled.png?table=block&amp;id=72855a80-990f-4845-b0f8-a037837ed902&amp;t=72855a80-990f-4845-b0f8-a037837ed902&amp;width=200&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-474cd58be1414ab89d7aa6153d9b5b1a">陀螺仪的三个环表示三个轴，他们不是始终固定的，根据物体的姿态调整，这就意味着存在两个环可能会重叠（平行）。另外外环会带动内环旋转，这与旋转次序是类似的。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-d62e90b4b63d4bf8b38be2f1daee136b"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:384px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F7ff11dbf-dca3-4426-923f-422aa25c71a4%2FUntitled.png?table=block&amp;id=d62e90b4-b63d-4bf8-b38b-e2f1daee136b&amp;t=d62e90b4-b63d-4bf8-b38b-e2f1daee136b&amp;width=384&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-c8336a6c20ab432f889962aff5c1f587">在随着物体转动的坐标系下描述该问题非常方便。正如上面的石雕所示，我们取y,x,z的顺序依次绕轴旋转：</div><ul class="notion-list notion-list-disc notion-block-c394cba98648439f948e4fd9c949c5a6"><li>首先是绕y轴旋转任意角度，可以认为是原地转圈</li></ul><ul class="notion-list notion-list-disc notion-block-bc11e8e2f8e44a7db6a6592e7c0e339d"><li>接着绕着x轴旋转 90 度或者 -90 度，变成躺平或者俯瞰的姿势</li></ul><ul class="notion-list notion-list-disc notion-block-ed05bb34beb44db8a681f11da482535b"><li>这时候z轴就和最初的y轴重合了</li></ul><div class="notion-text notion-block-190da50a9f8a4aa6bb385bd79159e089">我们称丢失了一个自由度。这种视角看物体的旋转十分便于我们想象，但是比较难用数学方式表达，因为旋转轴是变化的。</div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3548c667d00141329594d2bf6dc54529" data-id="3548c667d00141329594d2bf6dc54529"><span><div id="3548c667d00141329594d2bf6dc54529" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3548c667d00141329594d2bf6dc54529" title="动态欧拉角与静态欧拉角互相转换（代数意义上）"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">动态欧拉角与静态欧拉角互相转换（代数意义上）</span></span></h3><div class="notion-text notion-block-da0be643d9c74f6db22e02263a7d9ef2">接下来的问题，如何转换动态欧拉角的旋转公式？可以根据静态欧拉角转换出来。</div><div class="notion-text notion-block-84c9e1105d3341c187144e833229b4cb">设动态欧拉角绕自身旋转为<!-- -->，假设是按照x→y→z旋转的，那么就有：</div><div class="notion-text notion-block-b8fc0c17de2a48ce83e092ca958db0b9">即绕自身x转动，等价于绕世界x轴转动；绕y轴转动，得先撤销之前x的转动，然后绕世界y轴变换，再应用之前x的转动；绕z轴转动也是同理，先撤销y然后撤销x，应用绕世界z轴变换，再应用xy。</div><div class="notion-text notion-block-bd6e04914d9a4b49aed98b205b093a1a">然后就能得到：</div><div class="notion-text notion-block-b7ba8de4e27f461699c7a33dc00405ce">所以，动态欧拉角变换和静态欧拉角变换是相互反过来的！也就是自身旋转xyz，相当于绕世界转zyx。</div><div class="notion-text notion-block-16b94d93f5b54e9bb6ec53f61160d073">因为静态欧拉角有万向节死锁，因为等式成立，所以动态欧拉角也有万向节死锁问题。</div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-90eefa25315045cab12d4e37a12fc32e" data-id="90eefa25315045cab12d4e37a12fc32e"><span><div id="90eefa25315045cab12d4e37a12fc32e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#90eefa25315045cab12d4e37a12fc32e" title="绕任意轴旋转矩阵（Rodrigues旋转表达 - 罗德里格旋转）"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">绕任意轴旋转矩阵（Rodrigues旋转表达 - 罗德里格旋转）</span></span></h2><div class="notion-text notion-block-adb8c969f24a448f9d419654dcff2bd3">轴的方向向量为<!-- -->，满足<!-- -->（单位向量），绕旋转轴旋转的向量为<!-- -->，旋转后的向量为<!-- -->，逆时针（绕旋转轴）的旋转角度为<!-- -->。由旋转的模长不变性知道<!-- -->。</div><div class="notion-text notion-block-01e482722d484b5195d9468df99085ad">将<!-- -->分解为<!-- -->和<!-- -->方向（垂直于<!-- -->和平行于<!-- -->），不难得到如下关系：</div><div class="notion-text notion-block-ae90b805b46142518d6bf4102ef04d97">构建一个新的标架<!-- -->，将该问题转换为在标架的旋转问题。我们假设空间是<span class="notion-inline-underscore"><b>右手坐标系</b></span>，那么规定并计算可得到标架<!-- -->：</div><div class="notion-text notion-block-ef8534a294cd4ea28f55fef0229cf7fa">考虑到：</div><div class="notion-text notion-block-3631eae22983425f9bd36109513b6415">绕旋转轴逆时针旋转得到的向量<!-- -->，将其分别分解为<!-- -->和<!-- -->（其中<!-- -->在<!-- -->平面，有<!-- -->；<!-- -->在<!-- -->上，有<!-- -->）。</div><div class="notion-text notion-block-02eb9652a567462f82a2cde6b34541aa">由几何关系，可以得到：</div><div class="notion-text notion-block-e6da9664d14e4c59b3a6550ab10ee6b4">代入，可以得到旋转后向量的垂直分量表达式：</div><div class="notion-text notion-block-e915a2579fc44d6d97a2275ba6b61188">因此旋转后的向量：</div><div class="notion-text notion-block-c9c8fbddc54344df9a1447cd5807b22a">整理得到：</div><div class="notion-text notion-block-9b6be4522a5249db9e87e8d82e01a562">这是Rodrigues旋转的向量表示。为了得到Rodrigues旋转的矩阵表示，我们做如下的操作。</div><div class="notion-text notion-block-f342f692dfcb44b290c91cf4be6f7697">令<!-- -->，为了求解矩阵元，我们可以采用特殊值的方法，令<!-- -->，且：</div><div class="notion-text notion-block-1f628cc30e004a77878683a4a0027005">先计算得到：</div><div class="notion-text notion-block-6be7fe6b6ee9471ba8ab9a9b90f26bdc">于是：</div><div class="notion-text notion-block-deca874f9d77435b9f53048b848122e9">同理，令<!-- -->和<!-- -->，能够得到最终的旋转矩阵：</div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-f3dc3146417f43e58867f7dbcc04fc13" data-id="f3dc3146417f43e58867f7dbcc04fc13"><span><div id="f3dc3146417f43e58867f7dbcc04fc13" class="notion-header-anchor"></div><a class="notion-hash-link" href="#f3dc3146417f43e58867f7dbcc04fc13" title="四元数"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">四元数</span></span></h2><div class="notion-text notion-block-ad57b346817f46d58e9054652464a802">四元数由两部分组成：一个向量以及一个旋转角度。几何意义是表示以这个向量为轴所旋转的角度度数，如下图所示，一个四元数由向量v和标量s组成，表示以向量v为轴，旋转s角度；另外一套符号系统则是用θ表示旋转角度和u来表示旋转轴。这两个表示都是等价的：</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-d93759af40604e3b9769669a20e3a974"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4be83dcd-960d-4522-a017-1dbc5e80b360%2Fce20f3cd-496f-4d25-bbf8-8b560a01ffbb%2FUntitled.png?table=block&amp;id=d93759af-4060-4e3b-9769-669a20e3a974&amp;t=d93759af-4060-4e3b-9769-669a20e3a974&amp;width=1098&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-a1008ab537854f228d6e8ccc8b75b616">如果我们将向量u/v的xyz三个分量拆开来写，就可以得到四个标量：这就是四元数的名字的由来：</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-d9ba4eedbe944932aa2c0fc8e97acb53"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4be83dcd-960d-4522-a017-1dbc5e80b360%2Fe6d8b37c-6b5c-4e3c-a773-e23125cd92cd%2FUntitled.png?table=block&amp;id=d9ba4eed-be94-4932-aa2c-0fc8e97acb53&amp;t=d9ba4eed-be94-4932-aa2c-0fc8e97acb53&amp;width=1030&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-f74f7602947c4824aa6812b99eb48e99">有些地方喜欢将四元数写成：
</div><div class="notion-text notion-block-7bcc21b30e7f4a0fb1a54a8967cb4194">本质上都是一样的，ijk在这里就是用来表示旋转的轴。</div><div class="notion-text notion-block-3ededbb36a614f3a9759b0963916eef6">四元数加法很少用，只有在后面的插值才会有一定的使用。</div><div class="notion-text notion-block-42633ce586884e9bbe74de9d3b1e0d7b">四元数乘法代表了旋转顺序，按照顺序旋转进行<b>前乘</b>，例如如果先进行q1，再进行q2，那么总的旋转q就是：</div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-e31e9edca691464eb2bf334a141bcdc4" data-id="e31e9edca691464eb2bf334a141bcdc4"><span><div id="e31e9edca691464eb2bf334a141bcdc4" class="notion-header-anchor"></div><a class="notion-hash-link" href="#e31e9edca691464eb2bf334a141bcdc4" title="为什么四元数可以解决万向节死锁"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">为什么四元数可以解决万向节死锁</span></span></h3><div class="notion-text notion-block-081de9d8b14742f2b8bbdca062e4346c">欧拉旋转的本质是将绕任意轴旋转最终分解为绕x，y，z轴的旋转，才会导致万向节死锁。而用四元数旋转可直接表示为绕任意轴旋转。通过四元数的表示方法就可以看出</div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-1ae321ad5626479dbdadf59d2cc78fa2" data-id="1ae321ad5626479dbdadf59d2cc78fa2"><span><div id="1ae321ad5626479dbdadf59d2cc78fa2" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1ae321ad5626479dbdadf59d2cc78fa2" title="四元数插值"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>四元数插值</b></span></span></h2><div class="notion-text notion-block-25fe107151cc41ec80bb2a5c8d2b70c2">四元数插值的方式相对比较特殊，我们不能直接简单的线性插值，按照比例将两个单位四元数加在一起：</div><div class="notion-text notion-block-ca448c236fe74be7893c53b0deb422e4">这样的结果就是导致q(t)的长度不再是1，结果会在这条虚线上移动：</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-dbbaecd1da37420b9d3e27321f13b407"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:288px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4be83dcd-960d-4522-a017-1dbc5e80b360%2F13ea63ab-1d70-420d-8860-667e617bce74%2FUntitled.png?table=block&amp;id=dbbaecd1-da37-420b-9d3e-27321f13b407&amp;t=dbbaecd1-da37-420b-9d3e-27321f13b407&amp;width=288&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-a9915e683e3a4d70a723bd946cfbbc29">哪怕我们重新再把它的长度变回1，这个运动也不是随着角度而平滑运动的。所以我们需要用另一个方式进行插值，我们设下面的公式：</div><div class="notion-text notion-block-1470e6d432f241629dad071cb3665c4c">我们现在就是要接出来<!-- -->和<!-- -->，此时我们将<!-- -->沿着两个向量的方向进行分解，设<!-- -->是两个四元数之间的夹角：</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-4118ba1cd3484283b6bf87849254038b"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:432px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4be83dcd-960d-4522-a017-1dbc5e80b360%2F824d862f-64fc-40d4-bf06-a07366eb509a%2FUntitled.png?table=block&amp;id=4118ba1c-d348-4283-b6bf-87849254038b&amp;t=4118ba1c-d348-4283-b6bf-87849254038b&amp;width=432&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-8de0d1bd2ca148d18196f46206f5fbc7">根据相似三角形：</div><div class="notion-text notion-block-e7cb5da103314a13ad109fc5cbdbf3cb">由于所有四元数都是单位四元数，长度都是1，所以：</div><div class="notion-text notion-block-fa6ec832bc5f470dbf74dfa40031293f">也就是说四元数完整插值的公式是：</div><div class="notion-blank notion-block-7d0cc0f54b674cb5a837033e5bb1a853"> </div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Ambient Occlusion]]></title>
            <link>https://blog.inverseda.top/article/ao</link>
            <guid>https://blog.inverseda.top/article/ao</guid>
            <pubDate>Mon, 05 Feb 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[环境光遮蔽（Ambient Occlusion）是一种加深场景中阴影的技术，早期是使用光线追踪的方法来实现的，近年来孤岛危机的开发商优化了这个算法，使得实时AO有了可能。]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-b32bac6df7744b41a748e07f5df2d1b0"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-ef98e096d152485bb79f3a778e60f8e7" data-id="ef98e096d152485bb79f3a778e60f8e7"><span><div id="ef98e096d152485bb79f3a778e60f8e7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#ef98e096d152485bb79f3a778e60f8e7" title="AO定义"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">AO定义</span></span></h2><div class="notion-text notion-block-412e8f57d5da4366b239a3a21fc470ab">AO全称Ambient Occlusion，即环境光遮蔽。用来加深场景的遮蔽效果，也就是加深阴影的效果。AO的实现可以更加真实的反应模拟世界中的能量守恒，被广泛用到游戏中。</div><div class="notion-text notion-block-d1605e3312884ed0a3ffe50b672c8c95">经典的AO定义如下：</div><div class="notion-text notion-block-93c10647a5414634a568f503e0eec2a3">这个公式基于辐射度量学，满足能量守恒，用这个公式计算的AO在效果上是最佳的。</div><div class="notion-text notion-block-407c3aa9de3043b98a12cc13d29048c9">是位于表面的某点，<!-- -->是<!-- -->点的法向量，<!-- -->是<!-- -->在半球面内的立体角，<!-- -->是<!-- -->点的可见度函数：</div><div class="notion-text notion-block-7b7257c4e6fb43d58c80f67d7b4f45cb">因为<!-- -->和<!-- -->都是单位向量，令<!-- -->，这个积分可以化简为：</div><div class="notion-text notion-block-ef3d6c0266b144e09f05b4b8ac8795d9">因此，<!-- -->的含义就是点<!-- -->在半球面<!-- -->内的遮蔽程度，可以证明<!-- -->：</div><div class="notion-text notion-block-c765a5f8cde44d69ad9fcac0156d5a6c">其中<!-- -->。</div><div class="notion-text notion-block-2b93c693de9d4a489b456d0fedecc4a1">因此，<!-- -->越接近1，那么<!-- -->的遮蔽程度越大。</div><div class="notion-text notion-block-d9ef3b2d4408445fb6d70be524aed7b3">传统的AO计算方法采用光线追踪算法。光线追踪算法的好处就是效果很好，因为是直接计算积分，满足能量守恒。</div><div class="notion-text notion-block-8724880b222d4225921c74ce698029bb">但是这种方法不适合游戏中，因为太慢了，所以就有了下面的计算近似AO的算法（强调一下，是近似AO）。</div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-883802aecfa7470ca30e2ec08ea3e7e0" data-id="883802aecfa7470ca30e2ec08ea3e7e0"><span><div id="883802aecfa7470ca30e2ec08ea3e7e0" class="notion-header-anchor"></div><a class="notion-hash-link" href="#883802aecfa7470ca30e2ec08ea3e7e0" title="SSAO"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">SSAO</span></span></h2><div class="notion-text notion-block-47390d10777c4af081f57d937f9c92fb">SSAO是一种基于延迟渲染，在屏幕空间下计算的AO算法。这个AO算法本质上就是在屏幕空间下进行类似积分的运算，但是还是有一些差别。</div><div class="notion-text notion-block-f6346704b57d42668a45011b70bb99d1">原理当然需要用到G-Buffer，在获得四张贴图——位置（可选）、法线、环境光、深度之后，在屏幕空间中，进行SSAO的计算。</div><div class="notion-text notion-block-1b75dce8af824b1d8f51232198546a77">首先是获得AO贴图，AO贴图是一种灰度图，如下：</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-c7f9810c8c1a4af5a73c75881fda10db"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:445px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2Ff78972f2-c9c3-49aa-8a67-24c17749c9e5%2FUntitled.png?table=block&amp;id=c7f9810c-8c1a-4af5-a73c-75881fda10db&amp;t=c7f9810c-8c1a-4af5-a73c-75881fda10db&amp;width=445&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-eb0124fb893145ac9861864b68bc9cd5">可以看出，有强烈的遮蔽信息。所以我们需要先生成这样的AO贴图。这就是所有AO算法需要实现的一点。但是传统的光线追踪需要大量的三角形求交，所以不适合在游戏中应用。这就为什么SSAO出现了，SSAO在屏幕空间中进行遮蔽计算。</div><div class="notion-text notion-block-cf63f0650ec146928fa0c821c68dbb36">如何获得AO呢？在屏幕空间中，首先遍历像素点<!-- -->，在像素点所在的世界空间坐标的法线方向半球面内随机的选取采样点，然后对这些采样点进行深度测试。也就是判断这些采样点是否被遮蔽，如果被遮蔽了，就计数加1. 最后算出被遮蔽的采样点和总采样点的比值，这个比值是永远小于1的。然后存入到贴图中。这样就能得到AO贴图了。</div><div class="notion-text notion-block-ee50bde972704706986c8dbed4ea702a">在后处理中，我们可以对这个AO贴图采样，得到的数值，作为Phong光照中ambient分量的参数：</div><div class="notion-text notion-block-3831cbc36b3d4440afc195c6b4f5685c"><b>怎么随机采样？</b></div><div class="notion-text notion-block-91f05801fe764261ac25a8659c0e5b36">定义一个核函数，矩阵大小可以是8*8（假设），每个元素都是一个在切线空间的三维向量，表示的是xyz三个方向的随机采样点：</div><div class="notion-text notion-block-20ca8a42383546fc833022f8400bbc62">取值范围为[-1, 1], [-1, 1], [0, 1]，为什么要这样？因为我们是在屏幕空间里计算，而z轴在屏幕空间的取值范围就是0到1，其他的事-1到1.</div><div class="notion-text notion-block-20c67a751c7f42cf87c733c9bc784e29">为什么要定义在切线空间，试想一下，如果不依赖这样的核函数，那么我们对每个得到的顶点，都要在法线方向上进行核函数的生成，然后得到随机的采样点，性能差而且效果也和原本的差不多。所以最好的方法还是定义一个固定的随机核函数，然后对每个采样后的顶点进行切线空间到观察空间的变换即可，然后就能直接得到随机的采样点了。下面是计算AO的过程：</div><div class="notion-text notion-block-f8725d35631d479684a2d29a0b7bd486">综上所述，SSAO采用了如下的近似：</div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[引擎开发日志1 - Vulkan封装]]></title>
            <link>https://blog.inverseda.top/article/engine-vulkan-core</link>
            <guid>https://blog.inverseda.top/article/engine-vulkan-core</guid>
            <pubDate>Fri, 08 Mar 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[引擎首先最重要的是图形API的交互，为了让自己对GPU编程有进一步的了解，本人选择了相对较难的Vulkan作为引擎的API。同时也是锻炼自己的设计模式和封装能力。对于实例的创建和渲染管线的搭建，需要的变量由Context（Vk上下文）来管理，他是一个单例。而其他的都有各自的Mgr。]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-4fb72a6262ef45a59cff8c89c1a3b33d"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-64f94f08f54e4dada3a48e84855431f5" data-id="64f94f08f54e4dada3a48e84855431f5"><span><div id="64f94f08f54e4dada3a48e84855431f5" class="notion-header-anchor"></div><a class="notion-hash-link" href="#64f94f08f54e4dada3a48e84855431f5" title="技术栈"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">技术栈</span></span></h2><ul class="notion-list notion-list-disc notion-block-e25f26105da943be9e9322e05203d7e8"><li>底层图形API：Vulkan</li></ul><ul class="notion-list notion-list-disc notion-block-0e6d45bb573042288045aa35302285f6"><li>引擎语言：C++</li></ul><ul class="notion-list notion-list-disc notion-block-ecfcce37caa844be840a1640d118455b"><li>脚本语言：暂定Lua</li></ul><ul class="notion-list notion-list-disc notion-block-c6e9308b187e43c4a98a824f85531367"><li>引擎的设计模式：主体采用ECS+MVC</li></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-3474d27a8f2d4c5a87827ca07a1865cf" data-id="3474d27a8f2d4c5a87827ca07a1865cf"><span><div id="3474d27a8f2d4c5a87827ca07a1865cf" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3474d27a8f2d4c5a87827ca07a1865cf" title="Vulkan Base"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Vulkan Base</span></span></h2><div class="notion-to-do notion-block-59ac8cbd3ab94a52b31bd51375dbdeef"><div class="notion-to-do-item"><span class="notion-property notion-property-checkbox"><div class="notion-property-checkbox-checked"><svg viewBox="0 0 14 14"><path d="M5.5 12L14 3.5 12.5 2l-7 7-4-4.003L0 6.499z"></path></svg></div></span><div class="notion-to-do-body notion-to-do-checked">Context上下文</div></div><div class="notion-to-do-children"></div></div><div class="notion-to-do notion-block-7c7591e49d364ced9c81379a1bc606b9"><div class="notion-to-do-item"><span class="notion-property notion-property-checkbox"><div class="notion-property-checkbox-checked"><svg viewBox="0 0 14 14"><path d="M5.5 12L14 3.5 12.5 2l-7 7-4-4.003L0 6.499z"></path></svg></div></span><div class="notion-to-do-body notion-to-do-checked">Swapchain交换链</div></div><div class="notion-to-do-children"></div></div><div class="notion-to-do notion-block-3b3332bbf50645a0b19c80f053cc4741"><div class="notion-to-do-item"><span class="notion-property notion-property-checkbox"><div class="notion-property-checkbox-checked"><svg viewBox="0 0 14 14"><path d="M5.5 12L14 3.5 12.5 2l-7 7-4-4.003L0 6.499z"></path></svg></div></span><div class="notion-to-do-body notion-to-do-checked">RenderProcess渲染阶段的Pipline、Layout封装</div></div><div class="notion-to-do-children"></div></div><div class="notion-to-do notion-block-1128c3f19d0e4b01960c6937684548fd"><div class="notion-to-do-item"><span class="notion-property notion-property-checkbox"><div class="notion-property-checkbox-checked"><svg viewBox="0 0 14 14"><path d="M5.5 12L14 3.5 12.5 2l-7 7-4-4.003L0 6.499z"></path></svg></div></span><div class="notion-to-do-body notion-to-do-checked">Renderer渲染器</div></div><div class="notion-to-do-children"></div></div><div class="notion-to-do notion-block-cdd168b69cff45429c07ede58600f776"><div class="notion-to-do-item"><span class="notion-property notion-property-checkbox"><div class="notion-property-checkbox-checked"><svg viewBox="0 0 14 14"><path d="M5.5 12L14 3.5 12.5 2l-7 7-4-4.003L0 6.499z"></path></svg></div></span><div class="notion-to-do-body notion-to-do-checked">Shader着色器</div></div><div class="notion-to-do-children"></div></div><div class="notion-to-do notion-block-2aca313f35724184af5b6e5bb3efb206"><div class="notion-to-do-item"><span class="notion-property notion-property-checkbox"><div class="notion-property-checkbox-checked"><svg viewBox="0 0 14 14"><path d="M5.5 12L14 3.5 12.5 2l-7 7-4-4.003L0 6.499z"></path></svg></div></span><div class="notion-to-do-body notion-to-do-checked">CommandMgr命令管理器</div></div><div class="notion-to-do-children"></div></div><div class="notion-to-do notion-block-9f2892795e624303ab3e880d05ffa2a7"><div class="notion-to-do-item"><span class="notion-property notion-property-checkbox"><div class="notion-property-checkbox-checked"><svg viewBox="0 0 14 14"><path d="M5.5 12L14 3.5 12.5 2l-7 7-4-4.003L0 6.499z"></path></svg></div></span><div class="notion-to-do-body notion-to-do-checked">Vec2、Vec4、Mat4数学库（暂定先实现这些）</div></div><div class="notion-to-do-children"></div></div><div class="notion-to-do notion-block-4cffdb30e07d4502b40b261c53338f32"><div class="notion-to-do-item"><span class="notion-property notion-property-checkbox"><div class="notion-property-checkbox-checked"><svg viewBox="0 0 14 14"><path d="M5.5 12L14 3.5 12.5 2l-7 7-4-4.003L0 6.499z"></path></svg></div></span><div class="notion-to-do-body notion-to-do-checked">Texture纹理</div></div><div class="notion-to-do-children"></div></div><div class="notion-to-do notion-block-3cdffe5158834370b5839282e8c50408"><div class="notion-to-do-item"><span class="notion-property notion-property-checkbox"><div class="notion-property-checkbox-checked"><svg viewBox="0 0 14 14"><path d="M5.5 12L14 3.5 12.5 2l-7 7-4-4.003L0 6.499z"></path></svg></div></span><div class="notion-to-do-body notion-to-do-checked">DescriptorMgr描述符</div></div><div class="notion-to-do-children"></div></div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-df6f3851f59a4937a8cf086efcf3a698" data-id="df6f3851f59a4937a8cf086efcf3a698"><span><div id="df6f3851f59a4937a8cf086efcf3a698" class="notion-header-anchor"></div><a class="notion-hash-link" href="#df6f3851f59a4937a8cf086efcf3a698" title="Manager"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Manager</span></span></h2><div class="notion-to-do notion-block-cf3a39405ad744998e513cedd7b079de"><div class="notion-to-do-item"><span class="notion-property notion-property-checkbox"><div class="notion-property-checkbox-checked"><svg viewBox="0 0 14 14"><path d="M5.5 12L14 3.5 12.5 2l-7 7-4-4.003L0 6.499z"></path></svg></div></span><div class="notion-to-do-body notion-to-do-checked">ShaderMgr：负责管理Shaders，目前暂时采用哈希表映射</div></div><div class="notion-to-do-children"></div></div><div class="notion-to-do notion-block-b54f558d325f4af8b373764293a7f8e6"><div class="notion-to-do-item"><span class="notion-property notion-property-checkbox"><div class="notion-property-checkbox-checked"><svg viewBox="0 0 14 14"><path d="M5.5 12L14 3.5 12.5 2l-7 7-4-4.003L0 6.499z"></path></svg></div></span><div class="notion-to-do-body notion-to-do-checked">TextureMgr：在原有的TextureMgr基础上增加材质的管理</div></div><div class="notion-to-do-children"></div></div><div class="notion-to-do notion-block-f81d4eb1931b4ddbad7cf7e2c38c666d"><div class="notion-to-do-item"><span class="notion-property notion-property-checkbox"><div class="notion-property-checkbox-checked"><svg viewBox="0 0 14 14"><path d="M5.5 12L14 3.5 12.5 2l-7 7-4-4.003L0 6.499z"></path></svg></div></span><div class="notion-to-do-body notion-to-do-checked">ModelMgr：管理模型</div></div><div class="notion-to-do-children"></div></div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-0eea4687dfc0488c999e898646bb5f07" data-id="0eea4687dfc0488c999e898646bb5f07"><span><div id="0eea4687dfc0488c999e898646bb5f07" class="notion-header-anchor"></div><a class="notion-hash-link" href="#0eea4687dfc0488c999e898646bb5f07" title="Descriptor Problem"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Descriptor Problem</span></span></h2><div class="notion-text notion-block-2bccd5f15996435096d623a37e9b06f2">目前封装存在的最大的问题是不够独立，新的模块需要频繁更改封装好的Vulkan库的代码，需要进一步将公用接口进行隔离。</div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-63bd1b4711474532bc7d94d0b98d8120" data-id="63bd1b4711474532bc7d94d0b98d8120"><span><div id="63bd1b4711474532bc7d94d0b98d8120" class="notion-header-anchor"></div><a class="notion-hash-link" href="#63bd1b4711474532bc7d94d0b98d8120" title="引入"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">引入</span></span></h3><div class="notion-text notion-block-b25a1560914f4d499fc0d2576143a86c">假设两个Shader，不考虑frag和vert，那么可能会出现以下共用uniform的情况：</div><div class="notion-row notion-block-98c9ffcb30d14b5d955b7ebe2af8bf30"><div class="notion-column notion-block-a5ed1c3b862a489c9de71787b50690e5" style="width:calc((100% - (1 * min(32px, 4vw))) * 0.5)"><div class="notion-blank notion-block-736715b0ce6f494f9f3dc30bad0616a8"> </div></div><div class="notion-spacer"></div><div class="notion-column notion-block-6f4be585a7fa460c9f12a1c0e877ba9b" style="width:calc((100% - (1 * min(32px, 4vw))) * 0.5)"><div class="notion-blank notion-block-eebfe52eeae24301adaeca0550630762"> </div></div><div class="notion-spacer"></div></div><div class="notion-text notion-block-0c7f5ecd98884011a4141fc6a81f29d9">我们会发现，view、projection和worldTime是公用的全局变量，可能多个Shader都会用到它，所以他们的Descriptor应该是只有一个的，而不能每个Shader都拥有一个相同Descriptor的拷贝，不然当项目大了起来对内存来说是致命的。</div><div class="notion-text notion-block-26e494869e3d4c718f9536c7a3058009">我们需要引入一个管理这些uniform相关的数据结构。</div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-fa35351e9eaa4b8ab69be52680030eb6" data-id="fa35351e9eaa4b8ab69be52680030eb6"><span><div id="fa35351e9eaa4b8ab69be52680030eb6" class="notion-header-anchor"></div><a class="notion-hash-link" href="#fa35351e9eaa4b8ab69be52680030eb6" title="原有的流程"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">原有的流程</span></span></h3><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-ffc196c5c9f14ceda16d53bed351c953" data-id="ffc196c5c9f14ceda16d53bed351c953"><span><div id="ffc196c5c9f14ceda16d53bed351c953" class="notion-header-anchor"></div><a class="notion-hash-link" href="#ffc196c5c9f14ceda16d53bed351c953" title="Context创建Shader模块"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Context创建Shader模块</span></span></h4><div class="notion-text notion-block-05f4cce9e5ce4911aca29f3ed92ae781">这个示例中，首先获取了ShaderMgr，然后创建名字为default的shader，然后设置DescriptorSetLayoutBinding，分别为MVP矩阵和texture：</div><div class="notion-text notion-block-73eb74941fab4b74b7bfddbfcf76b7a7">其中ShaderMgr关于SetDescriptorSetLayoutBinding和CreateDescriptorSetLayout的函数如下：</div><div class="notion-text notion-block-eda8e9bd25cc466d83f34aae7dfdf76f">descriptorSetLayoutBindings是一个键值对，需要提供这个描述符的绑定点名称和所属于的集合。</div><div class="notion-text notion-block-c5ca227adb55483e8f2536b3eec3c0b5">descriptorSetLayouts是创建后的layout，通过集合名称确定。
</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-e9819cc9b82f45e0a0ef7cefd63723b5"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4be83dcd-960d-4522-a017-1dbc5e80b360%2Fd795bd7c-0ab2-4e6d-bf4d-4c1b9db903ed%2FUntitled.png?table=block&amp;id=e9819cc9-b82f-45e0-a0ef-7cefd63723b5&amp;t=e9819cc9-b82f-45e0-a0ef-7cefd63723b5&amp;width=708&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-3e4c1b399b9d4afcb3b0330779bf8706"> </div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-25a460fe31394e7bae5624983eb68a39" data-id="25a460fe31394e7bae5624983eb68a39"><span><div id="25a460fe31394e7bae5624983eb68a39" class="notion-header-anchor"></div><a class="notion-hash-link" href="#25a460fe31394e7bae5624983eb68a39" title="RenderPass确定Layout"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">RenderPass确定Layout</span></span></h4><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-735b45fce4064f0281535e98fc9a1fab" data-id="735b45fce4064f0281535e98fc9a1fab"><span><div id="735b45fce4064f0281535e98fc9a1fab" class="notion-header-anchor"></div><a class="notion-hash-link" href="#735b45fce4064f0281535e98fc9a1fab" title="Renderer阶段获取更新set"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Renderer阶段获取更新set</span></span></h4><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-76e944f52caa4a05a35fcc9fe1bfb13e" data-id="76e944f52caa4a05a35fcc9fe1bfb13e"><span><div id="76e944f52caa4a05a35fcc9fe1bfb13e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#76e944f52caa4a05a35fcc9fe1bfb13e" title="理解Descriptor"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">理解Descriptor</span></span></h3><div class="notion-text notion-block-567df62d42bc4ebc87bc8d530387ebab">如下图所示：</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-b8defae1d672469ea3818581c55ead29"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4be83dcd-960d-4522-a017-1dbc5e80b360%2Ffd07034a-ed51-45c0-bab2-d35115f5abda%2FUntitled.png?table=block&amp;id=b8defae1-d672-469e-a381-8581c55ead29&amp;t=b8defae1-d672-469e-a381-8581c55ead29&amp;width=708&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-8c6f2e3ce78c4d5ba024ad2de09bab5b">不像OpenGL，Vulkan不能对单独的Uniform或者其他被描述的变量进行Buffer。而是采用集合的设计，将要在Shader使用的Uniform变量的布局被SetLayout指定，通过<code class="notion-inline-code">vk::DescriptorPool</code> 分配出<code class="notion-inline-code">vk::DescriptorSet</code> ，再由这个集合Buffer。这样做的效率比OpenGL高很多。</div><div class="notion-text notion-block-c44cea88ed4b4c0aa1b3f77d06428cb0">还是原来的问题，考虑公共UBO，比如<code class="notion-inline-code">view</code> 和<code class="notion-inline-code">projection</code> ，他们在渲染的过程中，只需要绑定一次即可。如果在OpenGL，每切换一个绘制对象就要重新绑定。所以很浪费效率。</div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-099e57dc85bd4e95adc65531d3fc64c3" data-id="099e57dc85bd4e95adc65531d3fc64c3"><span><div id="099e57dc85bd4e95adc65531d3fc64c3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#099e57dc85bd4e95adc65531d3fc64c3" title="Solution"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Solution</span></span></h3><div class="notion-text notion-block-7d5c0a44735f43e2a497771ddd79d9e6">解决方案是分别封装DescriptorPool，DescriptorSetLayout，DescriptorWriter，每个类都会有各自的Builder。</div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-940fda0d52db4399afcb9dad9c1becc6" data-id="940fda0d52db4399afcb9dad9c1becc6"><span><div id="940fda0d52db4399afcb9dad9c1becc6" class="notion-header-anchor"></div><a class="notion-hash-link" href="#940fda0d52db4399afcb9dad9c1becc6" title="DescriptorSetLayout"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">DescriptorSetLayout</span></span></h4><div class="notion-text notion-block-251522557aa741c3a4b5427b41aa12d0">该类提供创建<code class="notion-inline-code">vk::DescriptorSetLayout</code> 的相应接口，能够接受多个多个binding。使用的方法如下：</div><div class="notion-text notion-block-94957d33178f4b72b3cf66a0e2fa73e6">这说明创建了一个全局setlayout，描述了一个binding = 0的uniform对象：</div><div class="notion-text notion-block-d9bf9cef7b0c492eb48f3ff349ba2472">可以设置多个binding，只需要：</div><div class="notion-text notion-block-79c50db0ca3d451bb77f00bb3e9bbae5">描述了：</div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-eb07fa20ca8c4027a23efbd34b09c7d8" data-id="eb07fa20ca8c4027a23efbd34b09c7d8"><span><div id="eb07fa20ca8c4027a23efbd34b09c7d8" class="notion-header-anchor"></div><a class="notion-hash-link" href="#eb07fa20ca8c4027a23efbd34b09c7d8" title="DescriptorPool"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">DescriptorPool</span></span></h3><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-cb3eb7a0a4fa407989213af905744ff5" data-id="cb3eb7a0a4fa407989213af905744ff5"><span><div id="cb3eb7a0a4fa407989213af905744ff5" class="notion-header-anchor"></div><a class="notion-hash-link" href="#cb3eb7a0a4fa407989213af905744ff5" title="DescriptorWriter"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">DescriptorWriter</span></span></h3><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-715bec0becc5496c99486e71799d455a" data-id="715bec0becc5496c99486e71799d455a"><span><div id="715bec0becc5496c99486e71799d455a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#715bec0becc5496c99486e71799d455a" title="FrameInfo Problem"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">FrameInfo Problem</span></span></h2><div class="notion-text notion-block-576192d77ddf413b9a7ac14f50333c26">现在存在一个很大的问题就是FrameInfo的封装可以说是基本没有：</div><div class="notion-text notion-block-57b86017e79049d9aed1721f6c48b332">可以看到，不同的RenderSystem，可能会用不同的FrameInfo，我们这样使用会让代码非常的丑，而且很冗余。</div><div class="notion-text notion-block-3a553d0bf5e84996a59ac50292a290f4">目前能想到的解决方案之一就是修改FrameInfo的结构体：</div><div class="notion-text notion-block-5f3136bcf05147c891e61d9438a16637">将原来的的set改成了map，就方便集成descriptorSet了。</div><div class="notion-text notion-block-fa81a0208f45473da2ccb1af9b6edc4f">不过大概率之后会改，因为总会遇到很复杂的情况。</div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-ecf782c511d34c6db673be2727f9a9e8" data-id="ecf782c511d34c6db673be2727f9a9e8"><span><div id="ecf782c511d34c6db673be2727f9a9e8" class="notion-header-anchor"></div><a class="notion-hash-link" href="#ecf782c511d34c6db673be2727f9a9e8" title="UBO"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">UBO</span></span></h2><div class="notion-text notion-block-35f2f6e325704f84b88aed679d5d788a">在vulkan中uniform不能单独buffer到device，需要由descriptor set描述，而descirptor set需要由descriptor pool分配。</div><div class="notion-text notion-block-13b49cee5510446eb2b658fea067d5d5">基于这个理念，结合之前封装的Descriptor组件，可以封装出一个这样的UBO模板类：</div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[记录第一次做肠镜检查]]></title>
            <link>https://blog.inverseda.top/article/changjing</link>
            <guid>https://blog.inverseda.top/article/changjing</guid>
            <pubDate>Thu, 14 Mar 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[为什么突然要做肠镜？前两天，述姐跟我聊天的时候聊到护肤，她说其实肠胃的健康程度影响皮肤也很深。我就突然想到自从去年开始我的右下腹部（应该是十二指肠那边）很胀，经常肠鸣有气体，当时耳朵的手术刚做完，就不想再去做检查了（对医院有些ptsd）。但已经一年了，并且志雄也说要检查，所以想想还是去做一下。于是第二天述姐陪我做了检查……]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-900d1ea1697f4fc9988d73ad3ee01e61"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-callout notion-gray_background_co notion-block-7eeedcda12324e7b9f5bc631e3ec6b77"><div class="notion-page-icon-inline notion-page-icon-span"><span class="notion-page-icon" role="img" aria-label="❔">❔</span></div><div class="notion-callout-text">为什么突然要做肠镜？3月9号的时候，述姐跟我聊天的时候聊到护肤，她说其实肠胃的健康程度影响皮肤也很深。我就突然想到自从去年开始我的右下腹部（应该是十二指肠那边）很胀，经常肠鸣有气体，当时耳朵的手术刚做完，就不想再去做检查了（对医院有些ptsd）。但已经一年了，并且志雄也说要检查，所以想想还是去做一下。于是第二天述姐陪我做了检查……</div></div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-52d64211e4d8451a9a34a531b78da054" data-id="52d64211e4d8451a9a34a531b78da054"><span><div id="52d64211e4d8451a9a34a531b78da054" class="notion-header-anchor"></div><a class="notion-hash-link" href="#52d64211e4d8451a9a34a531b78da054" title="3.10去医院检查"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3.10去医院检查</span></span></h2><div class="notion-text notion-block-fdde0f1ba5ce4869aff4192142161fac">挂了下午三点半消化内科的号，准时到达消化内科：</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-8cf5afa5584041c48b7b80976458d684"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4be83dcd-960d-4522-a017-1dbc5e80b360%2F60f976dc-285f-4176-9729-2532e049a0d3%2FIMG_6671.jpeg?table=block&amp;id=8cf5afa5-5840-41c4-8b7b-80976458d684&amp;t=8cf5afa5-5840-41c4-8b7b-80976458d684&amp;width=1920&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-8ca3840a15a84ec1ad0761ce3ca711f4">然后是一个很温柔的小姐姐给我做检查，问了我发病时间，体重有没有减轻，有没有便血，然后就开始摸我的腹部，检查我是不是有不舒服有疼痛感。</div><div class="notion-text notion-block-7ff780ce4d9647bb94625469b789f5ea">然后就安排我第三天进行无痛肠镜：</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-942eb0b84a2f426a91a5cd6989d22647"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4be83dcd-960d-4522-a017-1dbc5e80b360%2F255def39-c0cb-4f5a-bc24-b404fdd67fdd%2FIMG_6672.jpeg?table=block&amp;id=942eb0b8-4a2f-426a-91a5-cd6989d22647&amp;t=942eb0b8-4a2f-426a-91a5-cd6989d22647&amp;width=1080&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-c9fcec05914a46cdbbbeba10054029ec">看得我心肌梗塞了，晚上得喝1L泻药，然后早上五点还得起来喝2L泻药+西甲硅油……</div><div class="notion-text notion-block-4bd614a882d24c08bb693a756147e673">拿到单子之后就是依次进行：</div><div class="notion-text notion-block-3e3829eb2a684672ba9aa4283faccb35">检查心电图→给麻醉师鉴定是否能麻醉→取药</div><div class="notion-text notion-block-ee55e312dc564d968903e31cec40923c">这个时候其实需要挂麻醉与围术期科，但是因为麻醉师很忙，挂不到号，就只能第二天早上8点过来鉴定。</div><div class="notion-text notion-block-0ca62075f36b49b188904734155d7447">所以直接取药了，拿了三包和爽和一瓶西甲硅油乳剂。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-ef6618969fc94a87af6b70da0cfe9796"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4be83dcd-960d-4522-a017-1dbc5e80b360%2F35033e6c-f747-4581-9a98-9948a7b3ed84%2FIMG_6673.jpeg?table=block&amp;id=ef661896-9fc9-4a87-af6b-70da0cfe9796&amp;t=ef661896-9fc9-4a87-af6b-70da0cfe9796&amp;width=1080&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-acb263f48b214b7d86f6720ac902a4e3">出了医院那一刻，就不能吃很多东西了。首先只能吃颜色浅的食物，其次只能吃消化好的食物。于是我只能眼睁睁的看着述姐吃好的呜呜呜：</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-49d75cf461d8427e81baf27ad8cd02ed"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4be83dcd-960d-4522-a017-1dbc5e80b360%2F6cc5485b-7d90-4415-8f5e-8fac3b27cdc7%2FIMG_6674.jpeg?table=block&amp;id=49d75cf4-61d8-427e-81ba-f27ad8cd02ed&amp;t=49d75cf4-61d8-427e-81ba-f27ad8cd02ed&amp;width=4032&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-6f9053318c88497ea12ea70458150cfa">我只能吃粥，而且要把皮蛋挑出去……述姐吃的肠粉可香了</div><div class="notion-text notion-block-fc4e5db51c75421f852e0f4fe50845c0">还买了苹果和香蕉，这些可以吃：</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-adc80e149fa341478f464881e715fa1b"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4be83dcd-960d-4522-a017-1dbc5e80b360%2Fa83ab032-b63d-45d6-8edc-9927cb2279b1%2FIMG_6675.jpeg?table=block&amp;id=adc80e14-9fa3-4147-8f46-4881e715fa1b&amp;t=adc80e14-9fa3-4147-8f46-4881e715fa1b&amp;width=4032&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-b9177fc7e4f1426cbf00fb58e7ffbceb">之后回到宿舍了</div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-67ba502045fe49c3838d4870fba69ed2" data-id="67ba502045fe49c3838d4870fba69ed2"><span><div id="67ba502045fe49c3838d4870fba69ed2" class="notion-header-anchor"></div><a class="notion-hash-link" href="#67ba502045fe49c3838d4870fba69ed2" title="吃泻药"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">吃泻药</span></span></h3><div class="notion-text notion-block-f0a60fa5bc6c48ed91443e60bd56d655">做肠镜的全程，就这个最恶心最痛苦。因为这个和爽，非常难喝！而且还要1L，这是人能喝完的吗？</div><div class="notion-text notion-block-0dcc211588404a0e83fb228a493edc92">怎么形容这个和爽的味道呢？就是咸的菠萝味，但很奇怪很恶心。只能说喝过的人都懂。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-4c19ec7bee1d4edfbd54fa5eed18d463"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4be83dcd-960d-4522-a017-1dbc5e80b360%2F6c33f7d0-53d8-4065-9fa8-1b7aac35ec7e%2FIMG_6684.jpeg?table=block&amp;id=4c19ec7b-ee1d-4edf-bd54-fa5eed18d463&amp;t=4c19ec7b-ee1d-4edf-bd54-fa5eed18d463&amp;width=3024&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-efe5b33270ca440db213494303e8d45d">我好不容易喝完（先记住这个），一段时间居然没反应，于是我躺在床上耍手机了。</div><div class="notion-text notion-block-1c5027809ffe449b82c449b736e70741">然后没想到突然来感觉了，真的是差点就拉到床上了……我直接飞奔到厕所蹿稀。不得不说这个和爽是真的猛，把我的成年老💩都拉出来了。</div><div class="notion-text notion-block-36aed6c85c8b43759799cc6bb81c3e16">之后和舍友聊了很久的天，八卦了贼多人，然后就睡觉了。</div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-a185aec0be34471fa9f0c173371c3656" data-id="a185aec0be34471fa9f0c173371c3656"><span><div id="a185aec0be34471fa9f0c173371c3656" class="notion-header-anchor"></div><a class="notion-hash-link" href="#a185aec0be34471fa9f0c173371c3656" title="3.11做肠镜"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">3.11做肠镜</span></span></h2><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-b0236b74b5404eeda5451ff5dff1be48" data-id="b0236b74b5404eeda5451ff5dff1be48"><span><div id="b0236b74b5404eeda5451ff5dff1be48" class="notion-header-anchor"></div><a class="notion-hash-link" href="#b0236b74b5404eeda5451ff5dff1be48" title="早上五点"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">早上五点</span></span></h3><div class="notion-text notion-block-e3974e977dc34e598920bad5bd91629f">早上五点起来，继续把剩下的喝完。我在外面的走廊边散步边艰难的喝。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-d05f846ebc7f4bd6b29d6df354347129"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4be83dcd-960d-4522-a017-1dbc5e80b360%2F087bad1e-2b0e-46b8-96b3-679d9b340888%2FIMG_6700.jpeg?table=block&amp;id=d05f846e-bc7f-4bd6-b29d-6df354347129&amp;t=d05f846e-bc7f-4bd6-b29d-6df354347129&amp;width=3024&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-669e3552e23e4d10bdeb5314554742d8">喝到后面实在是受不了快吐了，然后就去xhs上看看集美们的方法，没想到有两种：</div><ol start="1" class="notion-list notion-list-numbered notion-block-a652290796a645d69317426ead93d327"><li>用脉动兑</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-0f34f762e38d4c0781d459bec71f2c7e"><li>买根棒棒糖，喝一口甜一口</li></ol><div class="notion-text notion-block-d7b68d93f8134172b986612bdc4b4491">我两个都试了，第一个不太好，我还是觉得恶心。但是第二个很好，这样的喝法我确实不会觉得恶心了。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-7fafda581f1d41fe9324e82349e6bbe1"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4be83dcd-960d-4522-a017-1dbc5e80b360%2F2d3c67c9-e13d-4db4-9c7d-e888cad6db27%2FIMG_6701.jpeg?table=block&amp;id=7fafda58-1f1d-41fe-9324-e82349e6bbe1&amp;t=7fafda58-1f1d-41fe-9324-e82349e6bbe1&amp;width=3024&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-77bf66a629f34433afa745a3e67ab0cc">还得是集美。</div><div class="notion-text notion-block-7089cd9e450c4425a7b84b1934c99961">最后一包泻药还得加上西甲硅油乳剂：</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-fce4b405fccf4d61bad338e0048002e3"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4be83dcd-960d-4522-a017-1dbc5e80b360%2Ff26ce8be-c2db-4a4d-9d49-bc6b94ab3331%2FIMG_6702.jpeg?table=block&amp;id=fce4b405-fccf-4d61-bad3-38e0048002e3&amp;t=fce4b405-fccf-4d61-bad3-38e0048002e3&amp;width=3024&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-eb367767cb83434193d0843baeb61067">之后就又是愉快的蹿稀时间，此时已经拉不出内容物了，全是水。说明此时肠道应该是满足了检查的要求，很干净。</div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-2d03b7641cde402d96c7daa329a278ff" data-id="2d03b7641cde402d96c7daa329a278ff"><span><div id="2d03b7641cde402d96c7daa329a278ff" class="notion-header-anchor"></div><a class="notion-hash-link" href="#2d03b7641cde402d96c7daa329a278ff" title="麻醉鉴定"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">麻醉鉴定</span></span></h3><div class="notion-text notion-block-930aeead1a7b41e4b273f37d4a49d823">因为涉及到全麻，所以要有人陪伴，很感谢述姐能在那么早的时候陪我去医院……感动呜呜叫。</div><div class="notion-text notion-block-9eab7c08cafa4834b33b30d0f47591f2">七点半我们就出发去医院了，首先是麻醉鉴定。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-751d23bcf96c426cac3fce7c1c678279"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4be83dcd-960d-4522-a017-1dbc5e80b360%2F2db06931-2c88-4289-be5b-4063024573fc%2FIMG_6703.jpeg?table=block&amp;id=751d23bc-f96c-426c-ac3f-ce7c1c678279&amp;t=751d23bc-f96c-426c-ac3f-ce7c1c678279&amp;width=3024&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-3ac0dbb052c14321b2b824014ece2713">麻醉医生问了我也没有什么疾病史，就差不多鉴定完毕了，可以做麻醉。</div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-f930c25f1fda423d8ae19c1da9bb8bdc" data-id="f930c25f1fda423d8ae19c1da9bb8bdc"><span><div id="f930c25f1fda423d8ae19c1da9bb8bdc" class="notion-header-anchor"></div><a class="notion-hash-link" href="#f930c25f1fda423d8ae19c1da9bb8bdc" title="开始做肠镜"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">开始做肠镜</span></span></h3><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-d874b426c18845c7a60b15fa0a406fc5"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4be83dcd-960d-4522-a017-1dbc5e80b360%2F133d9892-0f87-41e9-b44d-304a51bbadad%2FIMG_6704.jpeg?table=block&amp;id=d874b426-c188-45c7-a60b-15fa0a406fc5&amp;t=d874b426-c188-45c7-a60b-15fa0a406fc5&amp;width=4032&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-a52238591a89410683aad7a8790f7967">先换上了专用的裤子，然后在门口等了一段时间。</div><div class="notion-text notion-block-ab63ef9014b7421da633dfc4f19f69f9">叫到了我之后，直接去了3号门口，医生问我是不是第一次做，还有疾病史什么的。随后拿了一张床，让我躺上去。</div><div class="notion-text notion-block-4529a2801a704af6a8259236dde9ab97">接下来就很恐怖了，医生首先让我侧着躺好（一定要侧着），然后拿出了氧气罐让我吸，此时我感觉像是要做大手术一样，很慌。接下来，医生拿了一个装满白色麻药的针筒（还挺大的）。慢慢地推入我的身体。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-ccd61850cbbc4828a674a132cf1504be"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4be83dcd-960d-4522-a017-1dbc5e80b360%2Fdcc04fad-9fd7-4a0b-9d3d-d1a9a5e26712%2FIMG_6705.jpeg?table=block&amp;id=ccd61850-cbbc-4828-a674-a132cf1504be&amp;t=ccd61850-cbbc-4828-a674-a132cf1504be&amp;width=1080&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-2ac53482334d4c7684e1a4900feba464">突然！我就没知觉了！woc，我还以为是有个渐渐没知觉的过程，没想到一下子我就没意识了。好神奇。接着我梦到了我在写代码（梦里还在打工呜呜呜），而且很真实，让我以为不是在梦里。</div><div class="notion-text notion-block-37143fa152254e3088a4f2d972fc5673">过了一会我就突然醒了，醒的时候述姐已经在我旁边了。然后我才意识到：噢我刚才在做肠镜。</div><div class="notion-text notion-block-94353bec5bce48ac832cc43f4fee520e">刚醒的时候，腿都是软的，不能正常走路得扶着。再次感谢述姐！</div><div class="notion-text notion-block-db4f7a16b8bf48af9577e41fe3f98653">然后述姐帮我拿报告，检测结果是没有问题的：</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-8d35be660b784ac5a6a28dc1ab3d7819"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4be83dcd-960d-4522-a017-1dbc5e80b360%2F7b986e0e-6e06-4dc9-b682-e854a159877c%2FIMG_6706.jpeg?table=block&amp;id=8d35be66-0b78-4ac5-a6a2-8dc1ab3d7819&amp;t=8d35be66-0b78-4ac5-a6a2-8dc1ab3d7819&amp;width=1920&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-4a0c728df49d4568b8bd66ff74928113">只能说幸好，那估计是肠道菌落紊乱的问题，医生给我开了几个养肠子的药就离开医院了。</div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-500e066aee3f4d459f9556126981faa8" data-id="500e066aee3f4d459f9556126981faa8"><span><div id="500e066aee3f4d459f9556126981faa8" class="notion-header-anchor"></div><a class="notion-hash-link" href="#500e066aee3f4d459f9556126981faa8" title="爽吃"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">爽吃</span></span></h3><div class="notion-text notion-block-7189d948857648398a0d1d903b4e632f">我们直接去学府路爽吃螺蛳粉！</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-feab229ae33341a7b8130588eaf7a4e2"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4be83dcd-960d-4522-a017-1dbc5e80b360%2Fd1191859-0266-4975-b6c1-d0a1eae426ba%2FIMG_6708.jpeg?table=block&amp;id=feab229a-e333-41a7-b813-0588eaf7a4e2&amp;t=feab229a-e333-41a7-b813-0588eaf7a4e2&amp;width=3024&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-3b46b5132afe49998cb97c8ee6e72d42">（别学我，刚做完不能吃辣的，我已经受教训了，拉屎又疼又辣）</div><div class="notion-blank notion-block-40962878cb8a47038666746532d0888c"> </div><div class="notion-text notion-block-ce49e2bbeccb4ca080af040c6a425086">这就是我本人的第一次肠镜之旅了，总的来说很神奇。</div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[简谈GPU性能]]></title>
            <link>https://blog.inverseda.top/article/sim-gpu</link>
            <guid>https://blog.inverseda.top/article/sim-gpu</guid>
            <pubDate>Thu, 01 Feb 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[简单讲下CPU和GPU的差别。参考了AMD和NVIDIA的某次会议内容。]]></description>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-d40f741feb27485cae7011ca4c62c7e0"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><figure class="notion-asset-wrapper notion-asset-wrapper-pdf notion-block-1a366ae503804a1280d16fa007b131fe"><div style="position:relative;display:block;justify-content:center;align-self:center;width:708px;max-width:100%;flex-direction:column;height:320px;overflow:auto;background:rgb(226, 226, 226);padding:8px 16px"></div></figure><div class="notion-row"><a target="_blank" rel="noopener noreferrer" class="notion-bookmark notion-block-3dcefb1f7d874847a1225d73890c1f9f" href="https://developer.nvidia.com/gpugems/gpugems2/part-iv-general-purpose-computation-gpus-primer/chapter-34-gpu-flow-control-idioms"><div><div class="notion-bookmark-title">Chapter 34. GPU Flow-Control Idioms</div><div class="notion-bookmark-description">GPU Gems 2 is now available, right here, online. You can purchase a beautifully printed version of this book, and others in the series, at a 30% discount courtesy of InformIT and Addison-Wesley.</div><div class="notion-bookmark-link"><div class="notion-bookmark-link-icon"><img src="https://www.notion.so/image/https%3A%2F%2Fdirms4qsy6412.cloudfront.net%2Fnv%2Fassets%2Ffavicon-81bff16cada05fcff11e5711f7e6212bdc2e0a32ee57cd640a8cf66c87a6cbe6.ico?table=block&amp;id=3dcefb1f-7d87-4847-a122-5d73890c1f9f&amp;t=3dcefb1f-7d87-4847-a122-5d73890c1f9f" alt="Chapter 34. GPU Flow-Control Idioms" loading="lazy" decoding="async"/></div><div class="notion-bookmark-link-text">https://developer.nvidia.com/gpugems/gpugems2/part-iv-general-purpose-computation-gpus-primer/chapter-34-gpu-flow-control-idioms</div></div></div><div class="notion-bookmark-image"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fdeveloper.download.nvidia.com%2Fimages%2Fog-default.jpg?table=block&amp;id=3dcefb1f-7d87-4847-a122-5d73890c1f9f&amp;t=3dcefb1f-7d87-4847-a122-5d73890c1f9f" alt="Chapter 34. GPU Flow-Control Idioms" loading="lazy" decoding="async"/></div></a></div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-cbf36c9c1c1143fa937eb27d0728d13f" data-id="cbf36c9c1c1143fa937eb27d0728d13f"><span><div id="cbf36c9c1c1143fa937eb27d0728d13f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#cbf36c9c1c1143fa937eb27d0728d13f" title="CPU vs GPU"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">CPU vs GPU</span></span></h2><div class="notion-text notion-block-91eb29ef2d0047c989869375a1633896">CPU和GPU的最大差别就是，GPU比CPU多了很多ALU以及核心，并删掉了一些东西。从单核角度来看，GPU像是简单版的CPU，但GPU的核心非常多，这就导致了GPU在处理并行计算的时候是比CPU强很多的。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-4d9686efb82846de954f2bafb6b4634f"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4be83dcd-960d-4522-a017-1dbc5e80b360%2F5a24d8f1-b119-4442-8907-109d2e15bd08%2FUntitled.webp?table=block&amp;id=4d9686ef-b828-46de-954f-2bafb6b4634f&amp;t=4d9686ef-b828-46de-954f-2bafb6b4634f&amp;width=800&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-e78d977b00984864b9bb403d543732af">我们将上面的CPU“改造”成GPU：</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-f4919a726a49405caaa87d3fff8ea17e"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:192px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4be83dcd-960d-4522-a017-1dbc5e80b360%2F38928e58-4e91-48d5-8f2d-799b20b8867c%2FUntitled.png?table=block&amp;id=f4919a72-6a49-405c-aaa8-7d3fff8ea17e&amp;t=f4919a72-6a49-405c-aaa8-7d3fff8ea17e&amp;width=192&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-ce03edb3c231408c953a71a4175cf8dd">为什么要这样改造？</div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-2b1571e223eb49c5b2a2de8cb9536277" data-id="2b1571e223eb49c5b2a2de8cb9536277"><span><div id="2b1571e223eb49c5b2a2de8cb9536277" class="notion-header-anchor"></div><a class="notion-hash-link" href="#2b1571e223eb49c5b2a2de8cb9536277" title="Idea 1 - 移除不必要的部分"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Idea 1 - <b>移除不必要的部分</b></span></span></h2><div class="notion-text notion-block-68ed8626fbcf4b68b26b1ff5e665fbb3">我们可以看到，GPU仅仅只保留了解码单元（Fetch/Decode）、数学逻辑运算单元（ALU）、执行上下文（Execution Context）三个部分，这样可以加速GPU核心执行一条指令的速度。由于GPU核心的架构更加简单，所以在同样大小的物理面积上，可以塞下更多的GPU核心。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-ce41637dfea24eb4bd1c0f2724736cd6"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4be83dcd-960d-4522-a017-1dbc5e80b360%2Fb193099b-9336-4a58-a038-d7dfc2f89555%2FUntitled.webp?table=block&amp;id=ce41637d-fea2-4eb4-bd1c-0f2724736cd6&amp;t=ce41637d-fea2-4eb4-bd1c-0f2724736cd6&amp;width=800&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-c80bb3eed20a44e8ad3f6d51996edfb7" data-id="c80bb3eed20a44e8ad3f6d51996edfb7"><span><div id="c80bb3eed20a44e8ad3f6d51996edfb7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#c80bb3eed20a44e8ad3f6d51996edfb7" title="Idea 2 - 在许多的ALU之间来分摊一条指令的开销（SIMD）"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>Idea 2 - 在许多的ALU之间来分摊一条指令的开销（SIMD）</b></span></span></h2><div class="notion-text notion-block-e4ab5e9c3cb3420e9307ba090896aefa">另一个可以加速程序运行的方式就是在多个ALU之间来分摊一条指令的开销，这样的技术也被称为<b>SIMD</b>（Single Instruction Multiple Data）</div><blockquote class="notion-quote notion-block-a60112669ee744308d3ad0b670b3763d"><div>SIMD(Single Instruction Multiple Data)即单指令流多数据流，是一种采用一个控制器来控制多个处理器，同时对一组数据（又称“数据向量”）中的每一个分别执行相同的操作从而实现空间上的并行性的技术。简单来说就是一个指令能够同时处理多个数据。</div></blockquote><div class="notion-text notion-block-5127934862a14f82935817577ca55c71">所以现在，我们的GPU核心被设计成了如下的状态：</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-7be19efdd58b4535ac999c619143c009"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4be83dcd-960d-4522-a017-1dbc5e80b360%2F2cc99da7-6e92-4ac5-b2c1-e81280a5643f%2FUntitled.webp?table=block&amp;id=7be19efd-d58b-4535-ac99-9c619143c009&amp;t=7be19efd-d58b-4535-ac99-9c619143c009&amp;width=800&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-485899c7a4e14db292875c041db250ae">我们可以看到，在一个GPU核心中，不止一个ALU单元了。以上图所示，假设我们的GPU具有16个核心，每个核心中具有8个ALU单元，那么我们可以一次同时处理128个片元。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-18a6fede1d4c47098fec92dd562e57ca"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4be83dcd-960d-4522-a017-1dbc5e80b360%2Ff3c82f66-c988-48ae-83d6-5554863b09dd%2FUntitled.webp?table=block&amp;id=18a6fede-1d4c-4709-8fec-92dd562e57ca&amp;t=18a6fede-1d4c-4709-8fec-92dd562e57ca&amp;width=800&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-9be40cb34d1a4bca89fd433109c828ca" data-id="9be40cb34d1a4bca89fd433109c828ca"><span><div id="9be40cb34d1a4bca89fd433109c828ca" class="notion-header-anchor"></div><a class="notion-hash-link" href="#9be40cb34d1a4bca89fd433109c828ca" title="GPU的分支问题"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">GPU的分支问题</span></span></h2><div class="notion-text notion-block-fc9f6fb44f46414b82802af4d49922d1">在Shader和CUDA中，我们有一条约束规定：</div><div class="notion-text notion-block-10f25d93906e4639aa5bdab366de6643">尽量不要用if-else语句，尽量使用宏来代替它。</div><div class="notion-text notion-block-cf8e5be89a8046ce82e12042720229e8">这是为什么呢？</div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-d3d52e3ced004750bb01d48efb07bec1" data-id="d3d52e3ced004750bb01d48efb07bec1"><span><div id="d3d52e3ced004750bb01d48efb07bec1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#d3d52e3ced004750bb01d48efb07bec1" title="Divergence问题"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Divergence问题</span></span></h3><div class="notion-text notion-block-fe0d9b452daa4bde9391ec1d85720080">比如Shader在执行下面的分支语句：</div><div class="notion-text notion-block-754ec4498b0546d9930973380f5232d9">但是由于在不同的ALU中执行，这里的x可能不一样，某些ALU中的x小于0，有些x却又大于0。所以就会出现如下图所示的情况，不同的ALU会执行不同的条件分支。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-109b0489bfdd46dc976a7e66f8b7794b"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4be83dcd-960d-4522-a017-1dbc5e80b360%2F345fd037-6cdc-40a8-947a-da0ff0b7fce0%2FUntitled.webp?table=block&amp;id=109b0489-bfdd-46dc-976a-7e66f8b7794b&amp;t=109b0489-bfdd-46dc-976a-7e66f8b7794b&amp;width=708&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-95765dd48270403cabced1419a7be8cd">这样的一种情况就会造成 &quot;Divergence&quot;，通俗的讲就是不能够充分的发挥SIMD的性能。</div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-189378e444fc444e9015717aca428bc5" data-id="189378e444fc444e9015717aca428bc5"><span><div id="189378e444fc444e9015717aca428bc5" class="notion-header-anchor"></div><a class="notion-hash-link" href="#189378e444fc444e9015717aca428bc5" title="Stall问题"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">Stall问题</span></span></h3><div class="notion-text notion-block-72a0cb1d55854219a768e1f1b4d3d40d">Stall是在《计算机系统3》中学到的知识，因为当时是Stall问题出现在CPU的流水线设计中，当当前指令依赖于上一条指令的结果，但上一条指令的运算时间相对较长的时候，就要空出Stall，直到上一条指令的运算结果完成。</div><div class="notion-text notion-block-402c156e5f7f41edb51d0174d8b7cbdc">在GPU也会出现这种情况，就比如这个Shader语句：</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-f384f48d01de474f920840d9f3f83689"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4be83dcd-960d-4522-a017-1dbc5e80b360%2F978a4f38-a72a-4aa1-b58f-419d78c4ba86%2FUntitled.webp?table=block&amp;id=f384f48d-01de-474f-9208-40d9f3f83689&amp;t=f384f48d-01de-474f-9208-40d9f3f83689&amp;width=462&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-678b2a026b884a14b27379c39142578c">需要对纹理进行采样才能得到kd，但是采样的话其实消耗的时间会相对长一些，这样下面的kd可能会出现Stall问题，即推迟当前指令的执行，当上一条结果出来后才继续。</div><div class="notion-text notion-block-3effb70518454d689fb5826e03e8da19">解决方案就是不同核心之间交错处理片元：</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-af770a7326b44cbd948afeda28f73a6c"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F4be83dcd-960d-4522-a017-1dbc5e80b360%2F76294775-2bf2-47ce-8559-78c2a0be97d7%2FUntitled.webp?table=block&amp;id=af770a73-26b4-4cbd-948a-feda28f73a6c&amp;t=af770a73-26b4-4cbd-948a-feda28f73a6c&amp;width=800&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-873b8424085b4574b9d27424198611de">简单的说：我们不用所有的核心来一次处理完所有的片元，而是用一个核心处理一组片元，这样交错的去处理。如上图所示，当一个核心发生stall时，我们采用另外的核心继续处理别的片元，这样我们可以保障当一个核心发生stall的时候，别的核心不处于空闲的状态。</div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-8eab6e48018d4834bc98eb0663d31439" data-id="8eab6e48018d4834bc98eb0663d31439"><span><div id="8eab6e48018d4834bc98eb0663d31439" class="notion-header-anchor"></div><a class="notion-hash-link" href="#8eab6e48018d4834bc98eb0663d31439" title="总而言之，GPU相比于CPU"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">总而言之，GPU相比于CPU</span></span></h2><ol start="1" class="notion-list notion-list-numbered notion-block-da58879adabc4035ba23121eaccfb06a"><li>对核心架构进行瘦身，移除了不必要的结构，这样可以在同样大小的面积上塞入比CPU核心更多的核心数量</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-41d63cb8c5e44ab8a42ac8d53b990457"><li>在一个核心中塞入多个ALU单元，并使用SIMD技术对运行程序进行优化。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-9f7409ca196f4f898876475da7a1c1fd"><li>通过交错处理片元的方式来减少程序的stall</li></ol><div class="notion-blank notion-block-45c1a1fa95d94a979d05db4e96c578d2"> </div></main></div>]]></content:encoded>
        </item>
    </channel>
</rss>