游戲圖形學(xué)入門(mén)知識(shí)整理

分享和整理一些覺(jué)得不錯(cuò)的教程和理解

在此感謝各位老師!

教程:
線性代數(shù)基礎(chǔ):https://www.bilibili.com/video/BV1ib411t7YR?p=1
GAMES101-現(xiàn)代計(jì)算機(jī)圖形學(xué)入門(mén)-閆令琪:https://www.bilibili.com/video/BV1X7411F744
GAMES202-高質(zhì)量實(shí)時(shí)渲染-閆令琪:https://www.bilibili.com/video/BV1YK4y1T7yY
華中科技大學(xué)-計(jì)算機(jī)圖形學(xué)-萬(wàn)琳:https://www.bilibili.com/video/BV1Zj411f7S3?p=13&spm_id_from=pageDriver
論壇:
計(jì)算機(jī)圖形學(xué)與混合現(xiàn)實(shí)研討會(huì)
博客:
馮樂(lè)樂(lè)(Shader入門(mén)精要)http://candycat1992.github.io/

GPU渲染管線的工作過(guò)程

image.png

幾何階段

空間變換:模型空間(左手)→世界空間(左手)→觀察空間(右手)
image.png
投影準(zhǔn)備:觀察空間→觀察空間(投影變換)→觀察空間(裁剪空間)

經(jīng)過(guò)以上變換,此時(shí)物體處在裁剪空間,
★下圖需要注意,每個(gè)教材的解釋略有不同,下圖直接就齊次除法變成規(guī)范化的了
實(shí)際上這里只是為真正是投影(齊次除法)做準(zhǔn)備,此時(shí)裁剪面依然是梯形四棱錐形態(tài)
目的:
1.為后面真正投影做準(zhǔn)備,賦予W特殊意義。
2.對(duì)X,Y,Z縮放,W作為范圍值,便于裁剪。
裁剪空間之前,W=0表示矢量方向,W=1表示點(diǎn),投影變換之后,W的意義改變了,如下
投影變換對(duì)X,Y,Z分量進(jìn)行縮放,W分量變成-z,如X,Y,Z在W范圍內(nèi)[-w,w],說(shuō)明該頂點(diǎn)在裁剪空間內(nèi)
Unity下,觀察空間為右手坐標(biāo)系,列矩陣右乘,投影變換后Z分量范圍為[-w,w]
DirectX,投影變換后Z為[0,w]
進(jìn)入裁剪空間后,右手坐標(biāo)系,轉(zhuǎn)為左手坐標(biāo)系,離攝像機(jī)越遠(yuǎn)Z值越大


image.png
屏幕映射:規(guī)范化的觀察空間(裁剪)→屏幕空間(真正的投影)

齊次除法=透視除法=歸一化的設(shè)備坐標(biāo)NDC(OpenGL)=W分量除以X,Y,Z分量
裁剪空間→NDC(經(jīng)過(guò)齊次除法后,變換到一個(gè)立方體內(nèi))
立方體X,Y,Z分量的范圍是[1,-1](OpenGL)
DirectX中Z分量是[0,1]
Unity=OpenGL
Unity中屏幕空間左下角是[0,0],右上角是[pixelWidth,pixelHeight]
由于當(dāng)前的X,Y都是[1,-1],所以屏幕映射就是一個(gè)縮放的過(guò)程
此時(shí)Z分量經(jīng)過(guò)齊次除法,也就是除W,得到的數(shù)值直接存進(jìn)了深度緩沖區(qū),這步是自動(dòng)的,當(dāng)然也可手動(dòng)
W分量的意義主要是充當(dāng)分母來(lái)得到NDC

image.png

以上就是從模型空間變換到屏幕坐標(biāo)的過(guò)程

光柵化階段

image.png
下面說(shuō)下關(guān)于屏幕坐標(biāo)的問(wèn)題

視口空間坐標(biāo)公式如下


image.png

上面公式的思想就是,首先對(duì)裁剪空間下的坐標(biāo)進(jìn)行齊次除法,得到范圍在[ ? 1, 1] 的 NDC,然后再將其映射到范圍在[ 0, 1] 的視口空間下的坐標(biāo)。
ComputScreenPos 用法


image.png

image.png

Unity中先在頂點(diǎn)著色器里將其映射到范圍[ 0, W] ,然后再片段著色器中自己手動(dòng)齊次除法變?yōu)閇 0, 1] 。

z和w值就是裁剪空間下的值。
詳情請(qǐng)看ComputScreenPos ,其定義位于UnityCG.cginc中

更新:2022/8/8
CPU部分:
Unity內(nèi)置管線 Build-in
調(diào)用Render()→
剔除:視錐剔除、遮擋剔除、層級(jí)剔除→
渲染順序:按距離、渲染隊(duì)列→
打包數(shù)據(jù)、參數(shù),調(diào)用Shader:SetPassCall(渲染狀態(tài),剔除,混合模式等),DrawCall(模型數(shù)據(jù))→
(頂點(diǎn)坐標(biāo),法線,UV,切線,頂點(diǎn)色,索引列表)
(世界變換矩陣,視角VP矩陣,fov)
(shader,材質(zhì)參數(shù),燈光信息)

GPU部分:(頂點(diǎn)處理→圖元裝配及光柵化→片元處理→輸出合并→Framebuffer)
Shader處理(GPU渲染管線)→
幀緩沖區(qū)→
后處理→
再次Shader處理(GPU渲染管線)→
最終結(jié)果顯示到屏幕

頂點(diǎn)Shader:(MVP)
模型空間→(Model Matrix)→世界空間→(View Space)→相機(jī)空間→(Projection Matrix)→裁剪空間
經(jīng)過(guò)投影矩陣變換(將三維物體投影到2D平面上)


image.png

硬件操作階段(圖元裝配及光柵化階段):
裁剪空間→(裁剪操作)→


image.png

(透視除法)→NDC標(biāo)準(zhǔn)化設(shè)備坐標(biāo)(Z值保留,就是光柵化后片元 深度值)→背面剔除


image.png

(視口轉(zhuǎn)換,將-1,1轉(zhuǎn)換到比如1920*1080的屏幕區(qū)間)→屏幕坐標(biāo)→
image.png

圖元裝配(將點(diǎn)連線成面)→光柵化(填充顏色像素)→片元

片元數(shù)據(jù)(color,depth)→Alpha測(cè)試→模板測(cè)試StencilTest→深度測(cè)試DepthTest→混合Blending→幀緩沖區(qū)(colorbuffer,depthbuffer,stencilbuffer)

什么視Early-Z?
————————————————
版權(quán)聲明:本文為CSDN博主「白筱風(fēng)」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/whitebreeze/article/details/118688150

image.png

在以下幾種情況中,Ealry-Z會(huì)不生效

開(kāi)啟Alpha Test 或 clip/discard 等手動(dòng)丟棄片元操作
手動(dòng)修改GPU插值得到的深度
開(kāi)啟Alpha Blend
關(guān)閉深度測(cè)試Depth Test
注:前兩點(diǎn)情況原理類似,由于手動(dòng)進(jìn)行了片元的丟棄,會(huì)導(dǎo)致深度測(cè)試篩選出的片元也可能會(huì)被舍棄;第三點(diǎn)是由于開(kāi)啟了Alpha Blend一般會(huì)關(guān)閉深度寫(xiě)入,所以也不會(huì)生效;第四點(diǎn)關(guān)閉深度測(cè)試自然不會(huì)生效


image.png

image.png

有大量OverDraw的場(chǎng)景中使用Z-prepass可以很好的減小消耗
如渲染頭發(fā):
第一個(gè)pass用于生成Z Buffer:開(kāi)啟透明度測(cè)試僅通過(guò)不透明的測(cè)試,并關(guān)閉背面剔除,開(kāi)啟深度寫(xiě)入,關(guān)閉顏色緩沖區(qū)寫(xiě)入,只返回透明度值
之后的3個(gè)PASS與之前類似:第一個(gè)是渲染不透明物體,并剔除背面,設(shè)置深度測(cè)試為等于,關(guān)閉深度寫(xiě)入
第二個(gè)渲染背面,剔除正面,并關(guān)閉深度寫(xiě)入,深度測(cè)試為小于
第三個(gè)渲染正面,剔除背面,并開(kāi)啟深度寫(xiě)入,深度測(cè)試同上
DepthPrePass示范:

Pass {
            Tags{"LightMode"="DepthPrePass"}
            ZWrite On
            ColorMask 0
            Cull Off
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
            struct Attributes
            {
                float4 vertex : POSITION;
                float4 texcoord : TEXCOORD0;
                float4 color : COLOR;
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };

            struct Varyings
            {
                float4 pos : SV_POSITION;
                float2 uv:TEXCOORD0;
                UNITY_VERTEX_INPUT_INSTANCE_ID
                UNITY_VERTEX_OUTPUT_STEREO
            };
            Varyings vert (Attributes input)
            {
                Varyings output = (Varyings)0;
                float3 worldPos = WaveVertex(input.vertex, input.texcoord.xy, input.color, _WaveSpeed, _GrassWaveIntensity);
                output.pos = TransformWorldToHClip(worldPos);
                output.uv = TRANSFORM_TEX(input.texcoord.xy, _MainTex);
                return output;
            }
            float4 frag (Varyings input) : SV_Target
            {
                float4 albedo = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, input.uv)*_Color;
                float4 col = albedo * _Color;
                clip(col.a - _Cutoff);
                return 0;
            }
            ENDHLSL
        }
常用數(shù)學(xué)知識(shí)

Sin:對(duì)邊比斜邊
Cos:鄰邊比斜邊
Tan:對(duì)邊比臨邊。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容