共用方式為


在 Direct3D 10 中使用著色器

管線有三個著色器階段,每個階段都是使用 HLSL 著色器進行程序設計。 所有 Direct3D 10 著色器都是以 HLSL 撰寫,以著色器模型 4 為目標。

Direct3D 9 與 Direct3D 10 之間的差異:

  • 不同於可以使用中繼元件語言撰寫的 Direct3D 9 著色器模型,著色器模型 4.0 著色器只會以 HLSL 撰寫。 脫機編譯著色器成為設備可用的位元組代碼仍然受到支援,且建議在大多數情況下採用。

這個範例只會使用頂點著色器。 由於所有著色器都是從通用著色器核心建置,因此瞭解如何使用頂點著色器與使用幾何或像素著色器非常類似。

撰寫 HLSL 著色器之後(此範例會使用頂點著色器 HLSLWithoutFX.vsh),您必須針對將使用它的特定管線階段做好準備。 若要這樣做,您需要:

需要針對管線中的每個著色器重複這些步驟。

編譯著色器

第一個步驟是編譯著色器,檢查您是否已正確撰寫 HLSL 語句的程序代碼。 這是藉由呼叫 D3D10CompileShader 併為其提供數個參數來完成,如下所示:

    IPD3D10Blob * pBlob;
    
        
    // Compile the vertex shader from the file
    D3D10CompileShader( strPath, strlen( strPath ), "HLSLWithoutFX.vsh", 
        NULL, NULL, "Ripple", "vs_4_0", dwShaderFlags, &pBlob, NULL );

此函式會採用下列參數:

  • 包含著色器的檔案名稱(以及名稱字串的位元長度)。 此範例僅使用頂點著色器。(位於文件 HLSLWithoutFX.vsh 中,並且其中的文件擴展名 .vsh 是頂點著色器的縮寫。)

  • 著色器函式名稱。 此範例會從 Ripple 函式編譯頂點著色器,該函式會接受單一輸入並傳回輸出結構(此函式來自 HLSLWithoutFX 範例):

    VS_OUTPUT Ripple( in float2 vPosition : POSITION )
    
  • 指向著色器所用所有宏定義的指標。 使用D3D10_SHADER_MACRO來協助定義巨集;只要建立名稱字串,其中包含所有巨集名稱(每個名稱都以空格分隔)和定義字串(每個巨集主體以空格分隔)。 這兩個字串都必須以 NULL 終止。

  • 指向任何其他必要檔案的指標,以包含在內以使著色器能夠編譯。 這使用了 ID3D10Include 介面,具有兩個由使用者實作的方法:Open 和 Close。 若要讓這項工作能夠運作,您必須實作 Open 和 Close 方法的主體;在 Open 方法中,新增您要用來開啟任何包含檔案的程式代碼,在 Close 函式中新增程式代碼,以在您完成檔案時關閉檔案。

  • 要編譯的著色器函式名稱。 這個著色器會編譯 Ripple 函式。

  • 編譯時要設定目標的著色器配置檔。 因為您可以將函式編譯成頂點、幾何或圖元著色器,因此配置檔會告知編譯程式哪一種著色器和要比較程式碼的著色器模型。

  • 著色器編譯程式旗標。 這些旗標會告知編譯程式要將哪些資訊放入編譯的輸出,以及您希望輸出程式代碼優化的方式:針對速度、偵錯等。如需可用旗標的清單,請參閱 效果常數 (Direct3D 10)。 此範例包含一些程式代碼,您可以用來設定專案的編譯器旗標值,這主要取決於您是否想要生成偵錯資訊。

  • 緩衝區的指標,其中包含已編譯的著色器代碼。 緩衝區也包含編譯程式旗標所要求的任何內嵌偵錯和符號數據表資訊。

  • 緩衝區的指標,其中包含編譯期間所遇到的錯誤和警告清單,如果您在編譯著色器時執行調試程式,您會在偵錯輸出中看到的相同訊息。 當您不想將錯誤傳回至緩衝區時,NULL 是可接受的值。

如果著色器成功編譯,則會將著色器程式碼的指標以 ID3D10Blob 介面傳回。 它稱為 Blob 介面,因為指標是記憶體中由 DWORD 陣列組成的位置。 這個介面提供給您,使您可以取得編譯著色器的指標,這是您在下一個步驟中所需的。

從 2006 年 12 月 SDK 開始,DirectX 10 HLSL 編譯程式現在是 DirectX 9 和 DirectX 10 中的預設編譯程式。 如需詳細資訊,請參閱 Effect-Compiler 工具

取得指向已編譯著色器的指標

數個 API 方法需要已編譯著色器的指標。 這個自變數通常稱為 pShaderBytecode,因為它指向以位元組程式代碼序列表示的已編譯著色器。 若要取得已編譯著色器的指標,請先呼叫 D3D10CompileShader 或類似的函式來編譯著色器。 如果編譯成功,則會在 ID3D10Blob 介面中傳回已編譯的著色器。 最後,使用 GetBufferPointer 方法來傳回指標。

建立著色器物件

編譯著色器之後,請呼叫 CreateVertexShader 來建立著色器物件:

    ID3D10VertexShader ** ppVertexShader
    ID3D10Blob pBlob;


    // Create the vertex shader
    hr = pd3dDevice->CreateVertexShader( (DWORD*)pBlob->GetBufferPointer(),
        pBlob->GetBufferSize(), &ppVertexShader );

    // Release the pointer to the compiled shader once you are done with it
    pBlob->Release();

若要建立著色器物件,請將指向編譯後著色器的指標傳遞給 CreateVertexShader。 由於您必須先成功編譯著色器,除非您計算機上發生記憶體問題,否則此呼叫幾乎肯定會通過。

您可以視需要建立多個著色器物件,只要保留它們的指標即可。 這個相同的機制也適用於幾何著色器和像素著色器,前提是您在呼叫編譯方法時,將著色器設定檔與介面名稱相匹配(在您呼叫 create 方法時)。

設定著色器物件

最後一步是將著色器設置在管線的某一階段。 由於管線中有三個著色器階段,因此您必須進行三個 API 呼叫,每個階段各一個。

    // Set a vertex shader
    pd3dDevice->VSSetShader( g_pVS10 );

呼叫 VSSetShader 函數時,會取得在步驟 1 中創建的頂點著色器指標。 這會設定裝置中的著色器。 頂點著色器階段現已使用其頂點著色器程式碼初始化,接下來只需初始化任何著色器變數。

為所有三個著色器階段重複此動作

重複這些相同的步驟集,以建置任何頂點或像素著色器,甚至是輸出至圖元著色器的幾何著色器。

編譯著色器

HLSL 程序設計指南