Diligent Core は、Diligent エンジンの基盤となる最新のクロスプラットフォームの低レベル グラフィックス API です。このモジュールは、Direct3D11、Direct3D12、OpenGL、OpenGLES、および Vulkan レンダリング バックエンド (商用クライアントには Metal 実装が利用可能) と、基本的なプラットフォーム固有のユーティリティを実装します。自己完結型であり、独自に構築することができます。サポートされているプラットフォームと機能、ビルド手順などについては、メイン リポジトリを参照してください。
プラットフォーム | ビルドステータス |
---|---|
Win32 | |
ユニバーサルウィンドウ | |
Linux | |
アンドロイド | |
MacOS | |
iOS | |
テレビOS | |
エムスクリプト |
リポジトリのクローン作成
APIの基本
パイプラインリソースのレイアウト
Win32
ユニバーサル Windows プラットフォーム
Linux
MacOS
アンドロイド
iOS
エムスクリプト
エンジンの破壊
エンジンの初期化
リソースの作成
シェーダーの作成
パイプライン状態の初期化
シェーダーリソースのバインディング
パイプライン状態の設定と描画コマンドの呼び出し
低レベルの API の相互運用性
NuGet パッケージのビルド手順
ライセンス
貢献する
発売履歴
リポジトリとすべてのサブモジュールを取得するには、次のコマンドを使用します。
git clone --recursive https://github.com/DiligentGraphics/DiligentCore.git
モジュールをビルドするには、マスター リポジトリのビルド手順を参照してください。
エンジンによって提供される機能を使用する前に、レンダー デバイス、イミディエイト コンテキスト、およびスワップ チェーンを作成する必要があります。
Win32 プラットフォームでは、以下に示すように、OpenGL、Direct3D11、Direct3D12、または Vulkan デバイスを作成できます。
void InitializeDiligentEngine(HWND NativeWindowHandle) { SwapChainDesc SCDesc;// RefCntAutoPtr<IRenderDevice> m_pDevice;// RefCntAutoPtr<IDeviceContext> m_pImmediateContext;// RefCntAutoPtr<ISwapChain> m_pSwapChain;switch (m_DeviceType) {ケース RENDER_DEVICE_TYPE_D3D11: { EngineD3D11CreateInfo EngineCI; # if ENGINE_DLL// DLL をロードしてインポート GetEngineFactoryD3D11() functionauto* GetEngineFactoryD3D11 = LoadGraphicsEngineD3D11(); # endifauto* pFactoryD3D11 = GetEngineFactoryD3D11(); pFactoryD3D11->CreateDeviceAndContextsD3D11(EngineCI, &m_pDevice, &m_pImmediateContext); Win32NativeWindow ウィンドウ{hWnd}; pFactoryD3D11->CreateSwapChainD3D11(m_pDevice, m_pImmediateContext, SCDesc, FullScreenModeDesc{}、ウィンドウ、&m_pSwapChain); }ブレーク;ケース RENDER_DEVICE_TYPE_D3D12: { # if ENGINE_DLL// DLL をロードしてインポート GetEngineFactoryD3D12() functionauto GetEngineFactoryD3D12 = LoadGraphicsEngineD3D12(); # endifEngineD3D12CreateInfo EngineCI;auto* pFactoryD3D12 = GetEngineFactoryD3D12(); pFactoryD3D12->CreateDeviceAndContextsD3D12(EngineCI, &m_pDevice, &m_pImmediateContext); Win32NativeWindow ウィンドウ{hWnd}; pFactoryD3D12->CreateSwapChainD3D12(m_pDevice, m_pImmediateContext, SCDesc, FullScreenModeDesc{}、ウィンドウ、&m_pSwapChain); }ブレーク;ケース RENDER_DEVICE_TYPE_GL: { # if EXPLICITLY_LOAD_ENGINE_GL_DLL// DLL をロードしてインポート GetEngineFactoryOpenGL() functionauto GetEngineFactoryOpenGL = LoadGraphicsEngineOpenGL(); # endifauto* pFactoryOpenGL = GetEngineFactoryOpenGL(); EngineGLCreateInfo EngineCI; EngineCI.Window.hWnd = hWnd; pFactoryOpenGL->CreateDeviceAndSwapChainGL(EngineCI, &m_pDevice, &m_pImmediateContext, SCDesc、&m_pSwapChain); }ブレーク;ケース RENDER_DEVICE_TYPE_VULKAN: { # if EXPLICITLY_LOAD_ENGINE_VK_DLL// DLL をロードしてインポート GetEngineFactoryVk() functionauto GetEngineFactoryVk = LoadGraphicsEngineVk(); # endifEngineVkCreateInfo EngineCI;auto* pFactoryVk = GetEngineFactoryVk(); pFactoryVk->CreateDeviceAndContextsVk(EngineCI, &m_pDevice, &m_pImmediateContext); Win32NativeWindow ウィンドウ{hWnd}; pFactoryVk->CreateSwapChainVk(m_pDevice, m_pImmediateContext, SCDesc, Window, &m_pSwapChain); }ブレイク;デフォルト: std::cerr << "不明なデバイス タイプ"; } }
Windows では、エンジンをアプリケーションに静的にリンクすることも、別個の DLL として構築することもできます。最初のケースでは、ファクトリ関数GetEngineFactoryOpenGL()
、 GetEngineFactoryD3D11()
、 GetEngineFactoryD3D12()
、およびGetEngineFactoryVk()
を直接呼び出すことができます。 2 番目のケースでは、 LoadGraphicsEngineOpenGL()
、 LoadGraphicsEngineD3D11()
、 LoadGraphicsEngineD3D12()
、またはLoadGraphicsEngineVk()
関数を使用して、DLL をプロセスのアドレス空間にロードする必要があります。各関数は適切な動的ライブラリをロードし、エンジンの初期化に必要な関数をインポートします。次のヘッダーを含める必要があります。
#include "EngineFactoryD3D11.h"#include "EngineFactoryD3D12.h"#include "EngineFactoryOpenGL.h"#include "EngineFactoryVk.h"
また、次のディレクトリをインクルード検索パスに追加する必要があります。
DiligentCore/Graphics/GraphicsEngineD3D11/interface
DiligentCore/Graphics/GraphicsEngineD3D12/interface
DiligentCore/Graphics/GraphicsEngineOpenGL/interface
DiligentCore/Graphics/GraphicsEngineVulkan/interface
別の方法として、ルート フォルダーへのパスのみを追加し、それに対する相対的なインクルード パスを使用することもできます。
Diligent
名前空間を有効にします。
名前空間 Diligent を使用します。
IEngineFactoryD3D11::CreateDeviceAndContextsD3D11()
、 IEngineFactoryD3D12::CreateDeviceAndContextsD3D12()
、およびIEngineFactoryVk::CreateDeviceAndContextsVk()
関数は、指定された数の即時コンテキストと遅延コンテキストを作成することもできます。非同期レンダリングとマルチスレッドコマンド記録。コンテキストは、エンジンの初期化中にのみ作成できます。この関数は、コンテキストへのポインターの配列を設定します。最初に即時コンテキストが配置され、その後にすべての遅延コンテキストが続きます。
詳細については、Tutorial00_HelloWin32.cpp ファイルを参照してください。
ユニバーサル Windows プラットフォームでは、Direct3D11 または Direct3D12 デバイスを作成できます。初期化は、Win32 プラットフォームの場合と同じ方法で実行されます。違いは、最初にIEngineFactoryD3D11::CreateDeviceAndContextsD3D11()
またはIEngineFactoryD3D12::CreateDeviceAndContextsD3D12()
を呼び出してレンダー デバイスとデバイス コンテキストを作成することです。スワップ チェーンは、後でIEngineFactoryD3D11::CreateSwapChainD3D11()
またはIEngineFactoryD3D12::CreateSwapChainD3D12()
を呼び出すことによって作成されます。詳細については、SampleAppUWP.cpp ファイルを参照してください。
Linux プラットフォームでは、エンジンは OpenGL および Vulkan バックエンドをサポートします。 Linux での GL コンテキストの初期化は、ウィンドウの作成と密接に結びついています。その結果、Diligent Engine はコンテキストを初期化せず、アプリによって初期化されたコンテキストにアタッチします。 Linux でのエンジン初期化の例は、Tutorial00_HelloLinux.cpp にあります。
MacOS では、Diligent Engine は OpenGL、Vulkan、および Metal バックエンドをサポートします。 MacOS 上の GL コンテキストの初期化はアプリケーションによって実行され、エンジンはアプリによって作成されたコンテキストに接続されます。詳細については、GLView.mm を参照してください。 Vulkan バックエンドは他のプラットフォームと同様に初期化されます。 MetalView.mm を参照してください。
Android では、OpenGLES または Vulkan デバイスを作成できます。次のコード スニペットは例を示しています。
auto* pFactoryOpenGL = GetEngineFactoryOpenGL(); EngineGLCreateInfo EngineCI; EngineCI.Window.pAWindow = NativeWindowHandle; pFactoryOpenGL->CreateDeviceAndSwapChainGL( EngineCI、&m_pDevice、&m_pContext、SCDesc、&m_pSwapChain);
エンジンが動的ライブラリとして構築されている場合、ライブラリはネイティブ アクティビティによってロードされる必要があります。次のコードは、考えられる方法の 1 つを示しています。
static{try{System.loadLibrary("GraphicsEngineOpenGL"); catch (UnsatisfiedLinkError e) {Log.e("native-activity", "GraphicsEngineOpenGL library.n のロードに失敗しました" + e); } }
iOS 実装は、OpenGLES、Vulkan、および Metal バックエンドをサポートします。 iOS 上の GL コンテキストの初期化はアプリケーションによって実行され、エンジンはアプリによって初期化されたコンテキストに接続されます。詳細については、EAGLView.mm を参照してください。
Emscripten では、OpenGLES デバイスを作成できます。次のコード スニペットは例を示しています。
//キャンバスの ID を NativeWindowauto* に渡す必要があります * pFactoryOpenGL = GetEngineFactoryOpenGL(); EngineGLCreateInfo EngineCI = {}; EngineCI.Window = NativeWindow{"#canvas"}; pFactoryOpenGL->CreateDeviceAndSwapChainGL(EngineCI, &m_pDevice, &m_pContext, SCDesc, &m_pSwapChain);
既存のコンテキストで SDL または GLFW を使用している場合は、ネイティブ ウィンドウ ハンドルとして null を指定できます: EngineCI.Window = NativeWindow{nullptr}
エンジンは自動参照カウントを実行し、エンジン オブジェクトへの最後の参照が解放されるとシャットダウンします。
デバイス リソースはレンダー デバイスによって作成されます。 2 つの主要なリソース タイプは、線形メモリを表すバッファと、高速フィルタリング用に最適化されたメモリ レイアウトを使用するテクスチャです。バッファを作成するには、 BufferDesc
構造体を設定し、 IRenderDevice::CreateBuffer()
を呼び出す必要があります。次のコードは、均一 (定数) バッファーを作成します。
BufferDesc BuffDesc; BuffDesc.Name = "均一バッファ"; BuffDesc.BindFlags = BIND_UNIFORM_BUFFER; BuffDesc.Usage = USAGE_DYNAMIC; BuffDesc.uiSizeInBytes = sizeof(ShaderConstants); BuffDesc.CPUAccessFlags = CPU_ACCESS_WRITE; m_pDevice->CreateBuffer(BuffDesc, nullptr, &m_pConstantBuffer);
同様に、テクスチャを作成するには、次の例のようにTextureDesc
構造体を設定し、 IRenderDevice::CreateTexture()
を呼び出します。
TextureDesc TexDesc; TexDesc.Name = "私のテクスチャ 2D"; TexDesc.Type = TEXTURE_TYPE_2D; TexDesc.Width = 1024; TexDesc.Height = 1024; TexDesc.Format = TEX_FORMAT_RGBA8_UNORM; TexDesc.Usage = USAGE_DEFAULT; TexDesc.BindFlags = BIND_SHADER_RESOURCE | BIND_RENDER_TARGET | BIND_UNORDERED_ACCESS; TexDesc.Name = "サンプル 2D テクスチャ"; m_pRenderDevice->CreateTexture(TexDesc, nullptr, &m_pTestTex);
すべてのタイプのテクスチャを作成できる関数はCreateTexture()
1 つだけです。タイプ、形式、配列サイズ、およびその他すべてのパラメーターは、 TextureDesc
構造体のメンバーによって指定されます。
テクスチャ作成時に指定されたバインド フラグごとに、テクスチャ オブジェクトはデフォルト ビューを作成します。デフォルトのシェーダ リソース ビューはテクスチャ全体を扱い、デフォルトのレンダー ターゲットとデプス ステンシル ビューは最も詳細なミップ レベルのすべての配列スライスを参照し、順序なしアクセス ビューはテクスチャ全体を参照します。テクスチャからデフォルトのビューを取得するには、 ITexture::GetDefaultView()
関数を使用します。この関数は、返されたインターフェイスの参照カウンターをインクリメントしないことに注意してください。 ITexture::CreateView()
を使用して追加のテクスチャ ビューを作成できます。 IBuffer::CreateView()
使用して、バッファーの追加ビューを作成します。
シェーダを作成するには、 ShaderCreateInfo
構造体を設定します。
ShaderCreateInfo ShaderCI;
シェーダを作成するには 3 つの方法があります。 1 つ目の方法は、 ShaderCreateInfo::Source
メンバーを通じてシェーダー ソース コードへのポインターを提供することです。 2 番目の方法は、ファイル名を指定することです。 3 番目の方法は、 ShaderCreateInfo::ByteCode
メンバーを通じてコンパイルされたバイト コードへのポインターを提供することです。グラフィックス エンジンはプラットフォームから完全に切り離されています。ホスト ファイル システムはプラットフォームに依存するため、この構造はエンジンにファイル システムへのアクセスを与えることを目的としたShaderCreateInfo::pShaderSourceStreamFactory
メンバーを公開します。ソース ファイル名を指定した場合は、シェーダ ソース ストリーム ファクトリへの null 以外のポインタも指定する必要があります。シェーダー ソースに#include
ディレクティブが含まれている場合、ソース ストリーム ファクトリはこれらのファイルのロードにも使用されます。このエンジンは、サポートされているすべてのプラットフォームにデフォルトの実装を提供しますが、ほとんどの場合、これで十分です。ただし、独自の実装を定義することもできます。
重要なメンバーはShaderCreateInfo::SourceLanguage
です。このメンバーの有効な値は次のとおりです。
SHADER_SOURCE_LANGUAGE_DEFAULT
- シェーダー ソース形式は、基礎となるグラフィック API (D3D11 または D3D12 モードの場合は HLSL、OpenGL、OpenGLES、および Vulkan モードの場合は GLSL) と一致します。
SHADER_SOURCE_LANGUAGE_HLSL
- シェーダー ソースは HLSL です。 OpenGL および OpenGLES モードの場合、ソース コードは GLSL に変換されます。 Vulkan バックエンドでは、コードは SPIRV に直接コンパイルされます。
SHADER_SOURCE_LANGUAGE_GLSL
- シェーダ ソースは GLSL にあります。
SHADER_SOURCE_LANGUAGE_GLSL_VERBATIM
- シェーダーのソース言語は GLSL であり、そのままコンパイルする必要があります。
SHADER_SOURCE_LANGUAGE_MSL
- ソース言語はメタル シェーディング言語です。
ShaderCreateInfo
構造体の他のメンバーは、検索ディレクトリ、シェーダ マクロ定義、シェーダ エントリ ポイント、その他のパラメータなどのシェーダを定義します。
ShaderMacroHelper マクロ。 Macros.AddShaderMacro("USE_SHADOWS", 1); Macros.AddShaderMacro("NUM_SHADOW_SAMPLES", 4); Macros.Finalize(); ShaderCI.Macros = マクロ;
すべての準備ができたら、 IRenderDevice::CreateShader()
を呼び出してシェーダー オブジェクトを作成します。
ShaderCreateInfo ShaderCI; ShaderCI.Desc.Name = "MyPixelShader"; ShaderCI.FilePath = "MyShaderFile.fx"; ShaderCI.EntryPoint = "MyPixelShader"; ShaderCI.Desc.ShaderType = SHADER_TYPE_PIXEL; ShaderCI.SourceLanguage = SHADER_SOURCE_LANGUAGE_HLSL;const auto* SearchDirectories = "shaders;shadersinc;"; RefCntAutoPtr<IShaderSourceInputStreamFactory> pShaderSourceFactory; m_pEngineFactory->CreateDefaultShaderSourceStreamFactory(SearchDirectories, &pShaderSourceFactory); ShaderCI.pShaderSourceStreamFactory = pShaderSourceFactory; RefCntAutoPtr<IShader> pShader; m_pDevice->CreateShader(ShaderCI, &pShader);
Diligent Engine は、Direct3D12/Vulkan スタイルに従ってグラフィックス/コンピューティング パイプラインを構成します。 1 つのモノリシック パイプライン状態オブジェクト (PSO) には、必要なすべての状態 (すべてのシェーダー ステージ、入力レイアウトの説明、深度ステンシル、ラスタライザーおよびブレンド状態の説明など) が含まれます。グラフィックス パイプライン状態オブジェクトを作成するには、 GraphicsPipelineStateCreateInfo
構造体のインスタンスを定義します。
GraphicsPipelineStateCreateInfo PSOCreateInfo; PipelineStateDesc& PSODesc = PSOCreateInfo.PSODesc; PSODesc.Name = "パイプラインの状態";
レンダー ターゲットの数と形式、深度ステンシル形式などのパイプラインの詳細を説明します。
// これはグラフィックス パイプラインですPSODesc.PipelineType = PIPELINE_TYPE_GRAPHICS; PSOCreateInfo.GraphicsPipeline.NumRenderTargets = 1; PSOCreateInfo.GraphicsPipeline.RTVFormats[0] = TEX_FORMAT_RGBA8_UNORM_SRGB; PSOCreateInfo.GraphicsPipeline.DSVFormat = TEX_FORMAT_D32_FLOAT;
深度ステンシル状態の説明DepthStencilStateDesc
を初期化します。コンストラクターはデフォルト値でメンバーを初期化し、デフォルトとは異なる値のみを設定できることに注意してください。
// 深度ステンシル状態の初期化DepthStencilStateDesc& DepthStencilDesc = PSOCreateInfo.GraphicsPipeline.DepthStencilDesc; DepthStencilDesc.DepthEnable = true; DepthStencilDesc.DepthWriteEnable = true;
ブレンド状態の説明BlendStateDesc
を初期化します。
// ブレンド状態の初期化BlendStateDesc& BSDesc = PSOCreateInfo.GraphicsPipeline.BlendDesc; BSDesc.IndependentBlendEnable = False;auto &RT0 = BSDesc.RenderTargets[0]; RT0.BlendEnable = True; RT0.RenderTargetWriteMask = COLOR_MASK_ALL; RT0.SrcBlend = BLEND_FACTOR_SRC_ALPHA; RT0.DestBlend = BLEND_FACTOR_INV_SRC_ALPHA; RT0.BlendOp = BLEND_OPERATION_ADD; RT0.SrcBlendAlpha = BLEND_FACTOR_SRC_ALPHA; RT0.DestBlendAlpha = BLEND_FACTOR_INV_SRC_ALPHA; RT0.BlendOpAlpha = BLEND_OPERATION_ADD;
ラスタライザー状態の説明を初期化しますRasterizerStateDesc
:
// ラスタライザーの初期化 stateRasterizerStateDesc& RasterizerDesc = PSOCreateInfo.GraphicsPipeline.RasterizerDesc; RasterizerDesc.FillMode = FILL_MODE_SOLID; RasterizerDesc.CullMode = CULL_MODE_NONE; RasterizerDesc.FrontCounterClockwise = True; RasterizerDesc.ScissorEnable = True; RasterizerDesc.AntialiasedLineEnable = False;
入力レイアウトの説明を初期化するInputLayoutDesc
:
// 入力レイアウトを定義InputLayoutDesc& Layout = PSOCreateInfo.GraphicsPipeline.InputLayout; LayoutElement LayoutElems[] = {LayoutElement( 0, 0, 3, VT_FLOAT32, False ),LayoutElement( 1, 0, 4, VT_UINT8, True ),LayoutElement( 2, 0, 2, VT_FLOAT32, False ), }; Layout.LayoutElements = LayoutElems; Layout.NumElements = _countof(LayoutElems);
プリミティブ トポロジを定義し、シェーダ ポインタを設定します。
// シェーダとプリミティブ トポロジを定義しますPSOCreateInfo.GraphicsPipeline.PrimitiveTopology = PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; PSOCreateInfo.pVS = m_pVS; PSOCreateInfo.pPS = m_pPS;
パイプライン リソース レイアウトは、アプリケーションがさまざまなシェーダー リソース変数をどのように使用するかをエンジンに通知します。予想されるリソース バインディングの変更頻度に基づいてリソースをグループ化できるようにするために、Diligent Engine ではシェーダー変数の分類が導入されています。
静的変数( SHADER_RESOURCE_VARIABLE_TYPE_STATIC
) は、1 回のみ設定されることが期待される変数です。リソースが変数にバインドされると、それらを変更することはできません。このような変数は、カメラ属性やグローバル ライト属性定数バッファなどのグローバル定数を保持することを目的としています。変更できないのはリソース バインディングですが、リソースの内容は使用状況に応じて変更できることに注意してください。
可変変数( SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE
) は、マテリアルごとの周波数で変化すると予想されるリソースを定義します。例には、拡散テクスチャ、法線マップなどが含まれます。ここでも、リソースのコンテンツの更新はバインディングの変更と直交します。
動的変数( SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC
) は、頻繁かつランダムに変更されることが予想されます。
変数の型を定義するには、 ShaderResourceVariableDesc
構造体の配列を準備し、 PSODesc.ResourceLayout.Variables
メンバーとPSODesc.ResourceLayout.NumVariables
メンバーを初期化します。また、 PSODesc.ResourceLayout.DefaultVariableType
使用して、変数名が指定されていない場合に使用されるタイプを設定することもできます。
ShaderResourceVariableDesc ShaderVars[] = { {SHADER_TYPE_PIXEL、「g_StaticTexture」、SHADER_RESOURCE_VARIABLE_TYPE_STATIC}、 {SHADER_TYPE_PIXEL、「g_MutableTexture」、SHADER_RESOURCE_VARIABLE_TYPE_MUTABLE}、 {SHADER_TYPE_PIXEL、「g_DynamicTexture」、SHADER_RESOURCE_VARIABLE_TYPE_DYNAMIC} }; PSODesc.ResourceLayout.Variables = ShaderVars; PSODesc.ResourceLayout.NumVariables = _countof(ShaderVars); PSODesc.ResourceLayout.DefaultVariableType = SHADER_RESOURCE_VARIABLE_TYPE_STATIC;
パイプライン状態を作成するとき、テクスチャに不変サンプラーを永続的に割り当てることができます。不変サンプラーがテクスチャに割り当てられている場合、テクスチャ シェーダ リソース ビューで初期化されたサンプラーの代わりに、常にそれが使用されます。不変サンプラーを定義するには、 ImmutableSamplerDesc
構造体の配列を準備し、 PSODesc.ResourceLayout.ImmutableSamplers
メンバーとPSODesc.ResourceLayout.NumImmutableSamplers
メンバーを初期化します。不変サンプラーは、必ずしも静的である必要はない任意のタイプのテクスチャ変数に割り当てることができるため、サンプラーは不変のままで、テクスチャ バインディングを実行時に変更できることに注意してください。可能な限り不変サンプラーを使用することを強くお勧めします。
ImmutableSamplerDesc ImtblSampler; ImtblSampler.ShaderStages = SHADER_TYPE_PIXEL; ImtblSampler.Desc.MinFilter = FILTER_TYPE_LINEAR; ImtblSampler.Desc.MagFilter = FILTER_TYPE_LINEAR; ImtblSampler.Desc.MipFilter = FILTER_TYPE_LINEAR; ImtblSampler.TextureName = "g_MutableTexture"; PSODesc.ResourceLayout.NumImmutableSamplers = 1; PSODesc.ResourceLayout.ImmutableSamplers = &ImtblSampler;
このドキュメントでは、テクスチャ サンプラーの使用に関する詳細情報を提供します。
PSO 記述構造の必須フィールドがすべて設定されたら、 IRenderDevice::CreateGraphicsPipelineState()
を呼び出して PSO オブジェクトを作成します。
m_pDevice->CreateGraphicsPipelineState(PSOCreateInfo, &m_pPSO);
前述したように、Diligent Engine のシェーダー リソース バインディングは、変数を 3 つの異なるグループ (静的、変更可能、動的) にグループ化することに基づいています。静的変数は、1 回だけ設定されることが期待される変数です。リソースが変数にバインドされると、それらを変更することはできません。このような変数は、カメラ属性やグローバル ライト属性定数バッファなどのグローバル定数を保持することを目的としています。これらはパイプライン状態オブジェクトに直接バインドされます。
m_pPSO->GetStaticShaderVariable(SHADER_TYPE_PIXEL, "g_tex2DShadowMap")->Set(pShadowMapSRV);
可変変数と動的変数は、シェーダー リソース バインディング (SRB) と呼ばれる新しいオブジェクトを介してバインドされます。これは、パイプライン状態 ( IPipelineState::CreateShaderResourceBinding()
) によって作成されるか、高度な使用例ではパイプライン リソース シグネチャによって作成されます。
m_pPSO->CreateShaderResourceBinding(&m_pSRB, true);
2 番目のパラメーターは、PSO の静的変数を参照する SRB オブジェクトの内部構造を初期化するようにシステムに指示します。
動的で変更可能なリソースは、SRB オブジェクトを通じてバインドされます。
m_pSRB->GetVariable(SHADER_TYPE_PIXEL, "tex2DDiffuse")->Set(pDiffuseTexSRV); m_pSRB->GetVariable(SHADER_TYPE_VERTEX, "cbRandomAttribs")->Set(pRandomAttrsCB);
可変リソースと動的リソースの違いは、可変リソースはシェーダー リソース バインディングのインスタンスごとに 1 回しか設定できないことです。動的リソースは複数回設定できます。パフォーマンスに影響するため、変数の型を適切に設定することが重要です。静的変数と可変変数はより効率的です。動的変数はより高価であり、実行時のオーバーヘッドが発生します。
シェーダ リソースをバインドする別の方法は、リソース リテラル名を実際のリソースにマップするIResourceMapping
インターフェイスを作成することです。
ResourceMappingEntry エントリ[] = { {"g_Texture", pTexture->GetDefaultView(TEXTURE_VIEW_SHADER_RESOURCE)} }; ResourceMappingCreateInfo ResMappingCI.pEntries = エントリ; ResMappingCI.NumEntries = _countof(エントリ); RefCntAutoPtr<IResourceMapping> pResMapping; pRenderDevice->CreateResourceMapping(ResMappingCI, &pResMapping);
その後、リソース マッピングを使用して、すべての静的リソースをパイプライン状態にバインドできます ( IPipelineState::BindStaticResources()
)。
m_pPSO->BindStaticResources(SHADER_TYPE_VERTEX | SHADER_TYPE_PIXEL, pResMapping, BIND_SHADER_RESOURCES_VERIFY_ALL_RESOLVED);
または、シェーダー リソース バインディング ( IShaderResourceBinding::BindResources()
) 内のすべての可変リソースと動的リソース:
m_pSRB->BindResources(SHADER_TYPE_VERTEX | SHADER_TYPE_PIXEL, pResMapping, BIND_SHADER_RESOURCES_VERIFY_ALL_RESOLVED);
すべてのBindResources()
関数の最後のパラメータは、リソースを解決する方法を定義します。
BIND_SHADER_RESOURCES_UPDATE_STATIC
- 静的変数バインディングが更新されることを示します。
BIND_SHADER_RESOURCES_UPDATE_MUTABLE
- 可変変数バインディングが更新されることを示します。
BIND_SHADER_RESOURCES_UPDATE_DYNAMIC
- 動的変数バインディングが更新されることを示します。
BIND_SHADER_RESOURCES_UPDATE_ALL
- すべての変数タイプ (静的、変更可能、動的) が更新されることを示します。 BIND_SHADER_RESOURCES_UPDATE_STATIC
、 BIND_SHADER_RESOURCES_UPDATE_MUTABLE
、およびBIND_SHADER_RESOURCES_UPDATE_DYNAMIC
フラグがいずれも設定されていない場合、すべての変数タイプはBIND_SHADER_RESOURCES_UPDATE_ALL
が指定されたかのように更新されることに注意してください。
BIND_SHADER_RESOURCES_KEEP_EXISTING
- このフラグを指定すると、未解決のバインディングのみが更新されます。既存のバインディングはすべて元の値を保持します。このフラグが指定されていない場合、マッピングに対応するリソースが含まれていれば、すべてのシェーダー変数が更新されます。
BIND_SHADER_RESOURCES_VERIFY_ALL_RESOLVED
- このフラグが指定されている場合、呼び出し後にすべてのシェーダー バインディングが解決されることが期待されます。そうでない場合は、エラーが報告されます。
BindResources()
リソースをバインドするために、異なるリソース マッピングを使用して複数回呼び出される場合があります。ただし、マッピングのサイズは要素の検索時間に影響しないため、1 つの大きなリソース マッピングを使用することをお勧めします。
エンジンは実行時チェックを実行して、正しいリソースがバインドされていることを確認します。たとえば、定数バッファをシェーダ リソース ビュー変数にバインドしようとすると、デバッグ コンソールにエラーが出力されます。
描画コマンドを呼び出す前に、必要なすべての頂点バッファーとインデックス バッファー、およびパイプライン状態をデバイス コンテキストにバインドする必要があります。
// 描画コマンドを発行する前にレンダー ターゲットを設定します。auto* pRTV = m_pSwapChain->GetCurrentBackBufferRTV();auto* pDSV = m_pSwapChain->GetDepthBufferDSV(); m_pContext->SetRenderTargets(1, &pRTV, pDSV, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);// レンダー ターゲットと Depth-stencilconst float zero[4] = {0, 0, 0, 0}; をクリアします。 m_pContext->ClearRenderTarget(pRTV、ClearColor、RESOURCE_STATE_TRANSITION_MODE_TRANSITION); m_pContext->ClearDepthStencil(pDSV, CLEAR_DEPTH_FLAG, 1.f, 0, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);// 頂点バッファーとインデックス バッファーを設定しますIBuffer*buffer[] = {m_pVertexBuffer}; Uint32 オフセット[] = {0}; m_pContext->SetVertexBuffers(0, 1, バッファ, オフセット, SET_VERTEX_BUFFERS_FLAG_RESET, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); m_pContext->SetIndexBuffer(m_pIndexBuffer, 0, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); m_pContext->SetPipelineState(m_pPSO);
リソース状態遷移を実行する必要があるすべてのメソッドは、パラメーターとしてRESOURCE_STATE_TRANSITION_MODE
列挙型を受け取ります。列挙型は次のモードを定義します。
RESOURCE_STATE_TRANSITION_MODE_NONE
- リソースの状態遷移を実行しません。
RESOURCE_STATE_TRANSITION_MODE_TRANSITION
- リソースをコマンドで必要な状態に遷移します。
RESOURCE_STATE_TRANSITION_MODE_VERIFY
- 遷移しませんが、状態が正しいことを確認します。
最後のステップは、シェーダ リソースをデバイス コンテキストにコミットすることです。これはIDeviceContext::CommitShaderResources()
メソッドによって実現されます。
m_pContext->CommitShaderResources(m_pSRB, COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES);
メソッドが呼び出されない場合、エンジンはリソースがコミットされていないことを検出し、デバッグ メッセージを出力します。最後のパラメータは、リソースを正しい状態に移行するようにシステムに指示することに注意してください。このフラグが指定されていない場合は、 IDeviceContext::TransitionShaderResources()
を呼び出して、リソースを必要な状態に明示的に移行する必要があります。
m_pContext->TransitionShaderResources(m_pPSO, m_pSRB);
このメソッドには、シェーダ リソース バインディングを作成したパイプライン状態へのポインタが必要であることに注意してください。
必要な状態とリソースがすべてバインドされている場合、 IDeviceContext::DrawIndexed()
使用して描画コマンドを実行するか、 IDeviceContext::DispatchCompute()
使用して計算コマンドを実行できます。描画コマンドの場合はグラフィックス パイプラインをバインドする必要があり、ディスパッチ コマンドの場合は計算パイプラインをバインドする必要があることに注意してください。 DrawIndexed()
、引数としてDrawIndexedAttribs
構造体を受け取ります。次に例を示します。
DrawIndexedAttribs 属性。 attrs.IndexType = VT_UINT16; attrs.NumIndices = 36; attrs.Flags = DRAW_FLAG_VERIFY_STATES; pContext->DrawIndexed(attrs);
DRAW_FLAG_VERIFY_STATES
フラグは、描画コマンドによって使用される頂点バッファーとインデックス バッファーが適切な状態に遷移していることを検証するようにエンジンに指示します。
DispatchCompute()
計算グリッドのディメンションを定義するDispatchComputeAttribs
構造体を受け取ります。
m_pContext->SetPipelineState(m_pComputePSO); m_pContext->CommitShaderResources(m_pComputeSRB, COMMIT_SHADER_RESOURCES_FLAG_TRANSITION_RESOURCES); DispatchComputeAttribs DispatchAttrs{64, 64, 8}; m_pContext->DispatchCompute(DispatchAttrs);
サンプルとチュートリアルを学習することで、エンジン API についてさらに詳しく学ぶことができます。
Diligent Engine は、基礎となる低レベル API との相互運用性を幅広くサポートしています。このエンジンは、既存の D3D11/D3D12 デバイスまたは OpenGL/GLES コンテキストに接続することで初期化でき、基礎となるネイティブ API オブジェクトへのアクセスを提供します。詳細については、次のページを参照してください。
Direct3D11 の相互運用性
Direct3D12 の相互運用性
OpenGL/GLESの相互運用性
Vulkan の相互運用性
NuGet パッケージをビルドするには、次の手順に従います。
必要な Python パッケージをインストールする
python -m pip install -r ./BuildTools/.NET/requirements.txt
NuGet パッケージ ビルド スクリプトを実行します。例:
python ./BuildTools/.NET/dotnet-build-package.py -c Debug -d ./
口論 | 説明 | 必須 |
---|---|---|
-c ( configuration ) | ネイティブ動的ライブラリのビルド構成 (デバッグ、リリースなど) | はい |
-d ( root-dir ) | DiligentCore のルート ディレクトリへのパス | はい |
-s ( settings ) | 設定ファイルへのパス | いいえ |
dotnet-tests | .NET テストを実行するかどうかを示すフラグ | いいえ |
dotnet-publish | パッケージを NuGet ギャラリーに公開するかどうかを示すフラグ | いいえ |
free-memory | ビルド プロセス中にメモリ不足が発生した場合は、この引数を使用します。 | いいえ |
設定ファイルを使用してデフォルト設定をオーバーライドできます ( dotnet-build-package.py
のdefault_settings
ディクショナリを確認してください)。
「Apache 2.0 ライセンス」を参照してください。
このプロジェクトにはいくつかのサードパーティ依存関係があり、それぞれに独立したライセンスが付与されている場合があります。
Vulkan-Headers: Vulkan ヘッダー ファイルと API レジストリ (Apache License 2.0)。
SPIRV-Cross: SPIRV 解析およびクロスコンパイル ツール (Apache License 2.0)。
SPIRV-Headers: SPIRV ヘッダー ファイル (Khronos MIT のようなライセンス)。
SPIRV-Tools: SPIRV の最適化および検証ツール (Apache License 2.0)。
glslang: GLSL、ESL、HLSL (3 条項 BSD ライセンス、2 条項 BSD ライセンス、MIT、Apache License 2.0) 用の Khronos リファレンス コンパイラおよびバリデータ。
glew: OpenGL 拡張機能 Wrangler ライブラリ (Mesa 3-D グラフィックス ライブラリ、Khronos MIT のようなライセンス)。
volk: Vulkan API のメタ ローダー (Arseny Kapoulkine MIT ライク ライセンス)。
stb: C/C++ 用の stb 単一ファイルのパブリック ドメイン ライブラリ (MIT ライセンスまたはパブリック ドメイン)。
googletest: Google テストおよびモッキング フレームワーク (BSD 3 条項「新規」または「改訂」ライセンス)。
DirectXShaderCompiler: LLVM/Clang ベースの DirectX シェーダー コンパイラー (LLVM リリース ライセンス)。
DXBCChecksum: AMD 開発者ツール チーム (MIT ライセンス) による DXBC チェックサム計算アルゴリズム。
xxHash: 非常に高速な非暗号化ハッシュ アルゴリズム (2 条項 BSD ライセンス)。
コードを提供するには、このリポジトリにプル リクエストを送信してください。 Diligent Engine は、 DiligentCoreリポジトリ内のコンテンツが知的財産上の制約を受けないことを保証する Apache 2.0 ライセンスに基づいて配布されます。このリポジトリにコンテンツを送信すると、同じ条件に基づいてそのコンテンツにライセンスを付与することになり、コンテンツには知的財産権の主張がなく、これらの条件に基づいてライセンスを付与する権利があることに同意するものとします。
Diligent Engine は、clang 形式を使用して、コード ベース全体で一貫したソース コード スタイルを保証します。形式はコミットおよびプル リクエストごとに CI によって検証され、コード形式の問題が見つかった場合、ビルドは失敗します。 Clang 形式と自動コード フォーマットの設定方法については、このページを参照してください。
リリース履歴を参照
diligentgraphics.com