怡春院av_国产精品久久久久久亚洲毛片_精品国产乱码一区二区三区_亚洲一区欧美日韩_亚洲黄色激情视频_国产全黄a一级毛片91_亚洲免费在线播放

【游戲開發(fā)】Turing渲染著色器網(wǎng)格技術(shù)分析

2021-03-30
4845
0

圖靈體系結(jié)構(gòu)通過使用 網(wǎng)格著色器 引入了一種新的可編程幾何著色管道。新的著色器將計算編程模型引入到圖形管道中,因?yàn)閰f(xié)同使用線程在芯片上直接生成緊湊網(wǎng)格( meshlets ),供光柵化器使用。處理高幾何復(fù)雜度的應(yīng)用程序和游戲得益于兩階段方法的靈活性,該方法允許有效的剔除、詳細(xì)程度的技術(shù)以及程序生成。

本文介紹了新的管道,并給出了 GLSL 中用于 OpenGL 或 Vulkan 渲染的一些具體示例。新功能可以通過 OpenGL 和 Vulkan 中的擴(kuò)展以及使用 DirectX 12 旗艦版來訪問。

1網(wǎng)格著色管線
2網(wǎng)格和網(wǎng)格著色
3預(yù)計算網(wǎng)格
3.1數(shù)據(jù)結(jié)構(gòu)
3.2呈現(xiàn)資源和數(shù)據(jù)流
3.3使用任務(wù)著色器進(jìn)行簇消隱
4Conclusion
5References

目標(biāo)

現(xiàn)實(shí)世界是一個視覺豐富、幾何復(fù)雜的地方。尤其是室外場景可以由數(shù)十萬種元素(巖石、樹木、小植物等)組成。CAD 模型在復(fù)雜形狀的表面以及由許多小零件組成的機(jī)械上都存在類似的挑戰(zhàn)。在視覺效果中,大型結(jié)構(gòu),例如宇宙飛船,通常都用“ greebles ”來詳細(xì)說明。圖 1 顯示了幾個例子,其中,具有頂點(diǎn)、細(xì)分和幾何體著色器的圖形管道、實(shí)例化和間接多重繪制雖然非常有效,但當(dāng)全分辨率幾何體達(dá)到數(shù)億個三角形和數(shù)十萬個對象時,仍然會受到限制。

 

 

圖 1. 增加真實(shí)感的需要促進(jìn)了幾何復(fù)雜性的增加。

上面未顯示的其他用例包括在科學(xué)計算中發(fā)現(xiàn)的幾何圖形(粒子、字形、代理對象、點(diǎn)云)或程序形狀( ele CTR ic 工程布局、 vfx 粒子、帶狀和軌跡、路徑渲染)。

本文研究了 網(wǎng)格著色器 來加速重三角形網(wǎng)格的渲染。原始網(wǎng)格被分割成更小的 meshlets ,如圖2所示。理想情況下,每個網(wǎng)格都可以針對頂點(diǎn)重用進(jìn)行優(yōu)化。使用新的硬件相位和分割方案,可以并行繪制更多的幾何圖形,獲得更少的整體數(shù)據(jù)。

Figure 2. :  Large meshes can be decomposed into meshlets, which are rendered by mesh  shaders.

 
   

 

例如, CAD數(shù)據(jù)可以達(dá)到數(shù)千萬到數(shù)億個三角形。即使在遮擋過濾之后,也可能存在大量的三角形。在這種情況下,管道中的某些固定函數(shù)步驟可能會導(dǎo)致工作和內(nèi)存負(fù)載的浪費(fèi):

  • 通過硬件的原始分配器每次掃描 indexbuffer 來批量創(chuàng)建頂點(diǎn),即使拓?fù)浣Y(jié)構(gòu)沒有改變

  • 獲取不可見數(shù)據(jù)的頂點(diǎn)和屬性(背面、視錐體或亞像素剔除)

網(wǎng)格著色器 為開發(fā)人員提供了避免此類瓶頸的新可能性。(例如,在第 4 個緩存中,與第 4 個緩存相對應(yīng))的方法(例如,在第 4 個緩存中,直接讀取第 4 個三角形)。

網(wǎng)格著色器階梯為光柵化器生成三角形,但在內(nèi)部使用協(xié)作線程模型,而不是使用單線程程序模型,類似于計算著色器。管道中網(wǎng)格著色器前面是任務(wù)著色器。任務(wù)著色器的操作類似于細(xì)分的控制階段,因?yàn)樗軌騽討B(tài)生成工作。但是,與網(wǎng)格著色器一樣,它使用協(xié)作線程模型,而不是將面片作為輸入,將細(xì)分決策作為輸出,而是用戶定義其輸入和輸出。

這簡化了片上幾何體的創(chuàng)建,與之前嚴(yán)格且有限的細(xì)分和幾何體著色器相比,后者只需將線程用于特定任務(wù),如圖 3 所示。

 

 圖 3. 網(wǎng)格著色器表示處理幾何復(fù)雜性的下一步

網(wǎng)格著色管線

提出了一種新的兩級流水線替換方案,對傳統(tǒng)的頂點(diǎn)、細(xì)分、幾何等屬性獲取流水線進(jìn)行了補(bǔ)充。這是一條新管道: 組成

  • 任務(wù)著色器 :

    在工作組中工作的可編程單元允許每個單元發(fā)射(或不發(fā)射)網(wǎng)格著色器工作組

  • 網(wǎng)格著色器 :

    在工作組中運(yùn)行的一種可編程單元,允許每個工作組生成原語

 

mesh shader stage 在內(nèi)部使用上述協(xié)作線程模型為光柵化器生成三角形。任務(wù)著色器的操作類似于細(xì)分的外殼著色器階段,因?yàn)樗軌騽討B(tài)生成工作。但是,與網(wǎng)格著色器一樣,任務(wù)著色器也使用協(xié)作線程模式。它的輸入和輸出是用戶定義的,而不必將面片作為輸入,將細(xì)分決策作為輸出。

 

像素/片段著色器的接口不受影響。傳統(tǒng)的管道仍然可用,并且可以根據(jù)用例提供非常好的結(jié)果。圖4突出顯示了管道樣式的差異。

 

 

圖 4. 傳統(tǒng)與任務(wù)/網(wǎng)格幾何管道的區(qū)別

新的網(wǎng)格著色器管道為開發(fā)人員提供了許多好處:

  • 更高的可擴(kuò)展性 通過著色器單元來減少原語處理中的固定函數(shù)影響。

    現(xiàn)代 GPUs 的通用用途有助于更多種類的應(yīng)用程序添加更多內(nèi)核,并提高著色器的通用內(nèi)存和算術(shù)性能。

  • Bandwidth-reduction,因?yàn)轫旤c(diǎn)的重復(fù)數(shù)據(jù)消除(頂點(diǎn)重用)可以預(yù)先完成,并且可以在多個幀上重復(fù)使用。

    當(dāng)前的 API 模型意味著每次硬件都必須掃描索引緩沖區(qū)。

    較大的網(wǎng)格意味著更高的頂點(diǎn)重用率,也降低了帶寬要求。

    此外,開發(fā)人員可以提出自己的壓縮或過程生成方案。


    通過任務(wù)著色器 進(jìn)行可選的擴(kuò)展/篩選允許跳過完全獲取更多數(shù)據(jù)。

  • Flexibility 定義網(wǎng)格拓?fù)浜蛣?chuàng)建圖形工作。

    以前的 細(xì)分著色器 僅限于固定的鑲嵌模式,而 幾何著色器 則存在線程效率低下、編程模型不友好的問題,每個線程都會創(chuàng)建三角形條帶。

網(wǎng)格著色遵循 計算著色器 的編程模型,使開發(fā)人員可以自由地將線程用于不同的用途,并在線程之間共享數(shù)據(jù)。當(dāng)光柵化被禁用時,這兩個階段還可以用于執(zhí)行具有一個級別擴(kuò)展的通用計算工作。

 

 

 圖 5. 網(wǎng)格著色器的行為類似于使用協(xié)作線程模型計算著色器。

這兩個 網(wǎng)格和任務(wù)著色器 都遵循 計算著色器 的編程模型,使用協(xié)作線程組來計算結(jié)果,并有 除工作組索引外沒有其他輸入 。它們在圖形管道上執(zhí)行;因此硬件直接管理在級之間傳遞并保存在芯片上的內(nèi)存。

將展示一個例子,說明如何使用它來進(jìn)行基本體剔除,因?yàn)榫€程稍后可以訪問工作組中的所有頂點(diǎn)。圖 6 說明了任務(wù)著色器處理早期剔除的能力。

圖 6. 盡管可選,任務(wù)著色器啟用早期剔除以提高吞吐量。

通過 任務(wù)著色器 進(jìn)行的可選擴(kuò)展允許對一組原語進(jìn)行早期篩選或預(yù)先做出 LOD 決策。該機(jī)制在 GPU 上縮放,因此取代了小網(wǎng)格的實(shí)例化或多重繪制間接。此配置類似于 細(xì)分控制著色器 設(shè)置細(xì)分補(bǔ)丁(~ task workgroup )的數(shù)量,然后影響創(chuàng)建的 細(xì)分評估 調(diào)用(~ mesh workgroups )的數(shù)量。

單個 任務(wù)工作組 可以發(fā)射的 工作網(wǎng)格組 數(shù)量是有限制的。第一代硬件支持最多 64K 個子級,可以生成 每個任務(wù)。在同一個繪制調(diào)用中,所有任務(wù)的網(wǎng)格子對象的總數(shù)沒有限制。同樣,如果不使用 任務(wù)著色器 ,則對 draw 調(diào)用生成的網(wǎng)格工作組的數(shù)量沒有限制。圖 7 說明了這是如何工作的。

圖 7. 網(wǎng)格著色器工作組流

任務(wù) T 的子任務(wù)保證在任務(wù) T-1 的子任務(wù)之后啟動。但是, task 和 mesh 工作組是完全流水線的,因此不需要等待以前的子任務(wù)或任務(wù)的完成。

任務(wù)著色器用于動態(tài)作業(yè)生成或過濾。靜態(tài)設(shè)置受益于單獨(dú)使用網(wǎng)格著色器。

光柵及其內(nèi)部元素的輸出順序相同。禁用光柵化后,可以使用任務(wù)著色器和網(wǎng)格著色器實(shí)現(xiàn)基本計算樹。

網(wǎng)格和網(wǎng)格著色

每個網(wǎng)格單元表示不同數(shù)量的頂點(diǎn)和基本體。這些原語的連接性沒有限制。但是,它必須保持在著色器代碼中指定的最大值以下。

建議最多使用 64 個頂點(diǎn)和 126 個基本體。126 中的“ 6 ”不是打字錯誤。第一代硬件以 128 字節(jié)的粒度分配原始索引,并且需要為基元計數(shù)預(yù)留 4 個字節(jié)。因此 3 * 126 4 最大化了 3 * 128 = 384 字節(jié)塊的大小。超過 126 個三角形將分配接下來的 128 個字節(jié)。84 和 40 是其他適用于三角形的最大值。

在每個 GLSL mesh-shader代碼中,每個工作組在圖形管道中為每個工作組分配固定數(shù)量的網(wǎng)格內(nèi)存。

最大尺寸和原始輸出定義如下:

每個網(wǎng)格單元的分配大小取決于編譯時大小信息以及著色器引用的輸出屬性。分配越小,可以在硬件上并行執(zhí)行的工作組越多。與 compute 一樣,工作組共享可以訪問的片上內(nèi)存的公共部分。因此,建議盡可能高效地使用所有輸出或共享內(nèi)存。對于當(dāng)前著色器,這已經(jīng)是正確的。但是,內(nèi)存占用可能會更高,因?yàn)樵试S比當(dāng)前編程中更多的頂點(diǎn)和基元。

// Set the number of threads per
workgroup(always one - dimensional).

// The
limitations may be different than in actual compute shaders.

layout(local_size_x = 32) in ;

// the primitive
type(points, lines or triangles)

layout(triangles) out;

// maximum
allocation size
for each meshlet

layout(max_vertices = 64, max_primitives = 126) out;

// the actual
amount of primitives the workgroup outputs( <= max_primitives)

out uint gl_PrimitiveCountNV;

// an index
buffer,
using list type indices(strips are not supported here)

out uint gl_PrimitiveIndicesNV[]; // [max_primitives * 3 for triangles]

 

圖靈支持另一個新的 GLSL 擴(kuò)展, NV_fragment_shader_barycentric ,它使片段著色器能夠獲取構(gòu)成一個基本體的三個頂點(diǎn)的原始數(shù)據(jù),并手動對其進(jìn)行插值。這種原始訪問意味著可以輸出“ uint ”頂點(diǎn)屬性,但是使用各種 pack / unpack 函數(shù)將浮點(diǎn)存儲為 fp16 、 unorm8 或 snorm8 。這可以大大減少法線、紋理坐標(biāo)和基本顏色值的逐頂點(diǎn)占用空間,并有利于標(biāo)準(zhǔn)和網(wǎng)格著色管道。

頂點(diǎn)和基本體的其他屬性定義如下:

out gl_MeshPerVertexNV {

    vec4 gl_Position;

    float gl_PointSize;

    floatgl_ClipDistance[];

    floatgl_CullDistance[];

}
gl_MeshVerticesNV[]; //
[max_vertices]

// define your
own vertex output blocks as usual

out Interpolant {

    vec2 uv;

}
OUT[]; //
[max_vertices]

// special
purpose per - primitive outputs

perprimitiveNV out gl_MeshPerPrimitiveNV {

    int gl_PrimitiveID;

    int gl_Layer;

    int gl_ViewportIndex;

    intgl_ViewportMask[]; // [1]
}
gl_MeshPrimitivesNV[]; //
[max_primitives]

 

一個目標(biāo)是擁有最小數(shù)量的網(wǎng)格,從而最大限度地提高網(wǎng)格中頂點(diǎn)的重用率,從而減少分配的浪費(fèi)。在生成 meshlet 數(shù)據(jù)之前,在 indexbuffer 上應(yīng)用頂點(diǎn)緩存優(yōu)化器是有益的。例如, Tom Forsyth 的線性速度優(yōu)化器 可用于此。優(yōu)化頂點(diǎn)位置和索引緩沖區(qū)也是有益的,因?yàn)槭褂?nbsp;網(wǎng)格著色器 時,原始三角形的順序?qū)⒈3植蛔儭AD 模型通常是用條帶“自然”生成的,因此可以具有良好的數(shù)據(jù)局部性。更改索引緩沖區(qū)可能會對此類數(shù)據(jù)的 meshlet 的簇剔除屬性產(chǎn)生負(fù)面影響。

 

預(yù)計算網(wǎng)格

例如,呈現(xiàn)靜態(tài)內(nèi)容,其中 索引緩沖區(qū) 在許多幀中沒有變化。因此,在將頂點(diǎn)/索引上載到設(shè)備內(nèi)存期間,生成網(wǎng)格數(shù)據(jù)的成本可以隱藏起來。當(dāng) vertex 數(shù)據(jù)也是靜態(tài)的(沒有逐頂點(diǎn)動畫;頂點(diǎn)位置沒有變化)時,還可以獲得額外的好處,允許預(yù)先計算對快速剔除整個網(wǎng)格單元有用的數(shù)據(jù)。

數(shù)據(jù)結(jié)構(gòu)

在以后的示例中,將提供一個 meshlet 構(gòu)建器,它包含一個基本實(shí)現(xiàn),該實(shí)現(xiàn)掃描所提供的索引,并在每次遇到大小限制(頂點(diǎn)或基元計數(shù))時創(chuàng)建一個新的 meshlet 。

對于輸入三角形網(wǎng)格,它將生成以下數(shù)據(jù):

struct MeshletDesc {

    uint32_t vertexCount; // number of vertices used

    uint32_t primCount; // number of
    primitives(triangles) used

    uint32_t vertexBegin; // offset into vertexIndices

    uint32_t primBegin; // offset into
    primitiveIndices

}

std: :vector < meshletdesc > meshletInfos;

std: :vector < uint8_t > primitiveIndices;

// use uint16_t
when shorts are sufficient

std: :vector < uint32_t > vertexIndices;

 

為什么有兩個索引緩沖區(qū)?

 

以下原始三角形索引緩沖區(qū)序列

 

// let''s look at the first two triangles
of a batch of many more triangleIndices = {
    4,
    5,
    6,
    8,
    4,
    6,
    ...
}

 

分為兩個新的索引緩沖區(qū)。

當(dāng)?shù)切嗡饕龝r,建立了一組唯一的頂點(diǎn)索引。此過程也稱為 頂點(diǎn)重復(fù)數(shù)據(jù)消除 。

vertexIndices = {
    4,
    5,
    6,
    8,
    ...
}

// For the second triangle only vertex 8
must be added

// and the other vertices are re-used.

 

原始索引相對于 vertexIndices 項進(jìn)行調(diào)整。

 

// original data
triangleIndices = {
    4,
    5,
    6,
    8,
    4,
    6,
    ...
}

// new data
primitiveIndices = {
    0,
    1,
    2,
    3,
    0,
    2,
    ...
}

// the primitive indices are local per
meshlet

 

一旦達(dá)到適當(dāng)?shù)拇笮∠拗疲ㄒ词俏ㄒ豁旤c(diǎn)太多,要么是基本體太多),就會啟動一個新的網(wǎng)格單元。隨后的網(wǎng)格將創(chuàng)建自己的唯一頂點(diǎn)集。

 呈現(xiàn)資源和數(shù)據(jù)流

在渲染期間,使用原始頂點(diǎn)緩沖區(qū)。但是,使用了三個新的緩沖區(qū),而不是原來的三角形索引緩沖區(qū),如下圖 8 所示:

  • 頂點(diǎn)索引緩沖區(qū) 如上所述。

    每個網(wǎng)格單元引用一組唯一的頂點(diǎn)。

    這些頂點(diǎn)的索引按順序存儲在所有網(wǎng)格單元的緩沖區(qū)中。

  • 原始索引緩沖區(qū) 如上所述。

    每個網(wǎng)格單元表示不同數(shù)量的基本體。

    每個三角形需要三個原始索引,這些索引存儲在一個緩沖區(qū)中。

    Note :

    可以在每個 meshlet 之后添加額外的索引以獲得四字節(jié)對齊。

  • Meshlet Desc 緩沖區(qū)。 存儲每個網(wǎng)格單元的工作負(fù)載和緩沖區(qū)偏移信息,以及集群剔除信息。

這三個緩沖區(qū)實(shí)際上比原始索引緩沖區(qū)小,因?yàn)榫W(wǎng)格著色允許更高的頂點(diǎn)重用。注意到,通常會將索引緩沖區(qū)大小減少到原始索引緩沖區(qū)大小的 75% 左右。

圖 8. 網(wǎng)狀緩沖結(jié)構(gòu)

  • 網(wǎng)格頂點(diǎn): vertexBegin 存儲開始獲取頂點(diǎn)索引的起始位置。

    vertexCount 存儲所涉及的連續(xù)頂點(diǎn)的數(shù)量。

    頂點(diǎn)在網(wǎng)格單元中是唯一的;

    沒有重復(fù)的索引值。

  • 網(wǎng)格元素: primBegin 存儲原始索引的起始位置,將從那里開始獲取索引。

    primCount 存儲 meshlet 中涉及的基本體數(shù)量。

    注意,索引的數(shù)量取決于基本體類型(這里:

    3 表示三角形)。

    注意,索引引用的是相對于 vertexBegin 的頂點(diǎn),這意味著索引“ 0 ”將引用位于 vertexBegin 的頂點(diǎn)索引。

下面的偽代碼描述了每個 網(wǎng)格著色器 工作組在原則上執(zhí)行的操作。它是串行的,僅用于說明目的。

// This code is just a serial pseudo
code,

// and doesn''t
reflect actual GLSL code that would

// leverage the
workgroup ''s local thread invocations.

  for (int v = 0; v <
meshlet.vertexCount; v ){

    int vertexIndex =
texelFetch(vertexIndexBuffer, meshlet.vertexBegin v).x;

   
vec4 vertex = texelFetch(vertexBuffer, vertexIndex);

   
gl_MeshVerticesNV[v].gl_Position = transform * vertex;

  }

  for (int p = 0; p <
meshlet.primCount; p ){

   
uvec3 triangle = getTriIndices(primitiveIndexBuffer, meshlet.primBegin
p);

   
gl_PrimitiveIndicesNV[p * 3 0] = triangle.x;

   
gl_PrimitiveIndicesNV[p * 3 1] = triangle.y;

   
gl_PrimitiveIndicesNV[p * 3 2] = triangle.z;

  }

  // one thread
writes the output primitives

  gl_PrimitiveCountNV
= meshlet.primCount;''

 

當(dāng)以并行方式編寫時,網(wǎng)格著色器可能看起來如下所示:

void main() {

    ...

    // As the
    workgoupSize may be less than the max_vertices / max_primitives

    // we still
    require an outer loop.Given their static nature

    // they should
    be unrolled by the compiler in the end.

    // Resolved at
    compile time

    const uint vertexLoops =

    (MAX_VERTEX_COUNT GROUP_SIZE - 1) / GROUP_SIZE;

    for (uint loop = 0; loop < vertexLoops; loop ) {

        // distribute
        execution across threads

        uint v = gl_LocalInvocationID.x loop * GROUP_SIZE;

        // Avoid
        branching to get pipelined memory loads.

        // Downside is
        we may redundantly compute the last

        // vertex
        several times

        v = min(v, meshlet.vertexCount - 1);

        {

            int vertexIndex = texelFetch(vertexIndexBuffer,

            int(meshlet.vertexBegin v)).x;

            vec4 vertex = texelFetch(vertexBuffer, vertexIndex);

            gl_MeshVerticesNV[v].gl_Position = transform * vertex;

        }

    }

    // Let''s pack 8
    indices into RG32 bit texture

    uint primreadBegin = meshlet.primBegin / 8;

    uint primreadIndex = meshlet.primCount * 3 - 1;

    uint primreadMax = primreadIndex / 8;

    // resolved at
    compile time and typically just 1

    const uint primreadLoops =

    (MAX_PRIMITIVE_COUNT * 3 GROUP_SIZE * 8 - 1)

    / (GROUP_SIZE * 8);

    for (uint loop = 0; loop < primreadLoops; loop ) {

        uint p = gl_LocalInvocationID.x loop * GROUP_SIZE;

        p = min(p, primreadMax);

        uvec2 topology = texelFetch(primitiveIndexBuffer,

        int(primreadBegin p)).rg;

        // use a
        built - in
        function,
        we took special care before when

        // sizing the
        meshlets to ensure we don ''t exceed the

    //
gl_PrimitiveIndicesNV array here

   
writePackedPrimitiveIndices4x8NV(p * 8 0, topology.x);

   
writePackedPrimitiveIndices4x8NV(p * 8 4, topology.y);

  }

  if(gl_LocalInvocationID.x == 0) {

   
gl_PrimitiveCountNV = meshlet.primCount;

  }''

 

這是一個直接的例子。由于所有數(shù)據(jù)獲取都是由開發(fā)人員完成的,自定義編碼、通過子組內(nèi)部函數(shù)或共享內(nèi)存進(jìn)行解壓縮,或者暫時使用頂點(diǎn)輸出,都可以節(jié)省額外的帶寬。

使用任務(wù)著色器進(jìn)行簇消隱

嘗試將更多的信息壓縮到一個 meshlet 描述符中以執(zhí)行早期剔除。已經(jīng)嘗試使用 128 位描述符對前面提到的值進(jìn)行編碼,以及 G.Wihlidal 提出的用于背面聚類剔除的相對 bbox 和一個圓錐體。在生成網(wǎng)格時,需要在良好的簇剔除特性和改進(jìn)的頂點(diǎn)重用之間取得平衡。一方可能對另一方產(chǎn)生負(fù)面影響。

下面的任務(wù)著色器最多可剔除 32 個網(wǎng)格。

layout(local_size_x = 32) in ;

taskNV out Task {

    uint baseID;

    uint8_t subIDs[GROUP_SIZE];

}
OUT;

void main() {

    // we padded the
    buffer to ensure we don ''t access it out of bounds

 
uvec4 desc = meshletDescs[gl_GlobalInvocationID.x];

  // implement
some early culling function

  bool render =
gl_GlobalInvocationID.x < meshletCount && !earlyCull(desc);

 
uvec4 vote  =
subgroupBallot(render);

 
uint  tasks =
subgroupBallotBitCount(vote);

  if(gl_LocalInvocationID.x == 0) {

    // write the
number of surviving meshlets, i.e.

    // mesh
workgroups to spawn

   
gl_TaskCountNV = tasks;

    // where the
meshletIDs started from for this task workgroup

   
OUT.baseID = gl_WorkGroupID.x * GROUP_SIZE;

  }

  {

    // write which
children survived into a compact array

   
uint idxOffset = subgroupBallotExclusiveBitCount(vote);

    if (render) {

      OUT.subIDs[idxOffset] =
uint8_t(gl_LocalInvocationID.x);

   
}

  }

}''

 

相應(yīng)的網(wǎng)格著色器現(xiàn)在使用來自任務(wù)著色器的信息來標(biāo)識要生成的網(wǎng)格。

 

taskNV in Task {

    uint baseID;

    uint8_t subIDs[GROUP_SIZE];

}
IN;

void main() {

    // We can no
    longer use gl_WorkGroupID.x directly

    // as it now
    encodes which child this workgroup is.

    uint meshletID = IN.baseID IN.subIDs[gl_WorkGroupID.x];

    uvec4 desc = meshletDescs[meshletID];

    ...

}

 

在渲染大三角形模型的上下文中剔除任務(wù)著色器中的網(wǎng)格。其他場景可能涉及到根據(jù)細(xì)節(jié)決策的級別選擇不同的 meshlet 數(shù)據(jù),或者完全生成幾何體(粒子、色帶等)。下面的圖 9 來自一個使用任務(wù)著色器進(jìn)行詳細(xì)級別計算的演示。

 

圖 9.  NVIDIA 小行星演示使用網(wǎng)格著色

 Conclusion

一些主要的感受:

  • 通過掃描索引緩沖區(qū)一次,可以將三角形網(wǎng)格轉(zhuǎn)換為網(wǎng)格。

    頂點(diǎn)緩存優(yōu)化器有助于經(jīng)典渲染,也有助于提高網(wǎng)格填充效率。

    更復(fù)雜的聚類允許改進(jìn)任務(wù)著色器階段的早期排斥(更緊密的邊界框、一致的三角形法線等)。

  • 在硬件需要為片上 網(wǎng)格著色器 調(diào)用分配頂點(diǎn)/基元內(nèi)存之前, 任務(wù)著色器 允許提前跳過一組原語。

    如果需要,還可以生成多個子調(diào)用。

  • 頂點(diǎn)在工作組的線程中并行處理,就像原始的 頂點(diǎn)渲染 一樣。

  • 頂點(diǎn)著色器 可以與 網(wǎng)格著色器 兼容,并帶有一些預(yù)處理器插入。

  • 由于更高的頂點(diǎn)重用,需要提取的數(shù)據(jù)更少(經(jīng)典頂點(diǎn)著色器的操作限制為 max _ vertices = 32 , max _ primitives = 32 )。

    平均三角形網(wǎng)格價意味著使用兩倍數(shù)量的三角形作為頂點(diǎn)是有益的。

  • 所有數(shù)據(jù)加載都是通過著色器指令來處理的,而不是經(jīng)典的固定函數(shù)原語 fetch ,因此使用更多的 流式多處理器 可以更好地伸縮。

    它還允許更容易地使用自定義頂點(diǎn)編碼來進(jìn)一步減少帶寬。

  • 對于頂點(diǎn)屬性的大量使用,同樣并行操作的基本消隱階段可能是有益的。

    可以剔除掉頂點(diǎn)數(shù)據(jù)。

    然而,最好的收獲是在任務(wù)級別進(jìn)行有效的篩選。

 

轉(zhuǎn)載聲明:本文來源于網(wǎng)絡(luò),不作任何商業(yè)用途。

免責(zé)聲明:本文內(nèi)部分內(nèi)容來自網(wǎng)絡(luò),所涉繪畫作品及文字版權(quán)與著作權(quán)歸原作者,若有侵權(quán)或異議請聯(lián)系我們處理。
收藏

全部評論

您還沒登錄

暫無留言,趕緊搶占沙發(fā)
繪學(xué)霸是國內(nèi)專業(yè)的CG數(shù)字藝術(shù)設(shè)計線上線下學(xué)習(xí)平臺,在繪學(xué)霸有2D繪畫、3D模型、影視后期、動畫、特效等數(shù)字藝術(shù)培訓(xùn)課程,也有學(xué)習(xí)資源下載,還有行業(yè)社區(qū)交流。學(xué)習(xí)、交流,來繪學(xué)霸就對了。
繪學(xué)霸iOS端二維碼

IOS下載

繪學(xué)霸安卓端二維碼

安卓下載

繪學(xué)霸微信小程序二維碼

小程序

版權(quán)聲明
本網(wǎng)站所有產(chǎn)品設(shè)計、功能及展示形式,均已受版權(quán)或產(chǎn)權(quán)保護(hù),任何公司及個人不得以任何方式復(fù)制部分或全部,違者將依法追究責(zé)任,特此聲明。
熱線電話
18026259035
咨詢時間:9:00~21:00
在線客服
聯(lián)系網(wǎng)站客服
客服微信:18026259035
公司地址
中國·廣州
廣州市海珠區(qū)曉港中馬路130號之19
繪學(xué)霸客戶端(權(quán)限暫無,用于CG資源與教程交流分享)
開發(fā)者:廣州王氏軟件科技有限公司 | 應(yīng)用版本:Android:6.0,IOS:5.1 | App隱私政策> | 應(yīng)用權(quán)限 | 更新時間:2020.1.6
主站蜘蛛池模板: 日本一区二区三区久久久 | 国产在线一区二区 | 99在线视频精品 | 狠狠色丁香久久婷婷综合_中 | 一级毛片真人免费播放视频 | 国产欧美亚洲精品 | 2021最新国产成人精品视频 | 精品三级国产精品经典三 | 久久综合丝袜长腿丝袜 | jizzjizz在线 | 一级做a爰片久久毛片了d | 亚洲日本色 | 欧美bbbbbxxxxx| 久久伊人一区二区三区四区 | jyzzjyzzjyzz日本在线观看 | 亚洲国产午夜 | 麻豆视频免费网站 | 日本一区二区视频在线观看 | 亚洲天堂亚洲天堂 | 欧美多人三级级视频播放 | 欧美一卡二卡三卡 | 久久精品一区二区三区中文字幕 | 国产网址在线观看 | 久久99中文字幕久久 | 日韩视频在线观看视频 | 欧美1314性欧美 | 特黄特色大片免费高清视频 | 国产成人丝袜美女厕所视频 | 精品欧美一区二区在线观看 | 99久久久免费精品免费 | 欧美精品免费一区欧美久久优播 | 在线亚洲精品福利网址导航 | 天啪天天天天拍天天碰 | 日本午夜高清视频 | 免费在线a | 欧美色综合网站 | 亚洲专区中文字幕 | 日韩不卡视频在线观看 | 免费jizz在在线播放国产 | 漂亮的保姆免费观看 | 国内精品小视频在线 |