从字符串创建DX11着色器

时间:2018-05-03 12:55:56

标签: shader directx-11

我一直无法找到任何相关内容,我不确定它是否真的可行,但是这里有:

我希望能够为我的DX11游戏提供一个着色器,一个未从文件中加载的游戏(从那时起,该文件必须包含在使用我的框架的eeeeevery项目中)。我想直接使用HLSL文件的内容。我试过这个,但它给了我E_INVALIDARG。

以下是代码:

auto pixelShaderByteCode = std::string("struct PixelShaderInput" \
  "{" \
  "float4 pos : SV_POSITION;" \
  "float3 color : COLOR0;" \
  "};" \
  "float4 main(PixelShaderInput input) : SV_TARGET" \
  "{" \
  "return float4(input.color, 1.0f);" \
  "}");

Microsoft::WRL::ComPtr<ID3D11PixelShader> ps;

auto hr = m_deviceResources->GetD3DDevice()->CreatePixelShader(
  pixelShaderByteCode.c_str(),
  pixelShaderByteCode.length(),
  nullptr,
  &ps);

if (FAILED(hr))
{
    // that did not work... hr = E_INVALIDARG
}

我是否需要一个已编译的着色器来实现此功能?如果是这样,那么&#34;烘焙&#34;的最佳做法是什么?着色器进入引擎?

1 个答案:

答案 0 :(得分:2)

您无法使用HLSL源调用CreatePixelShader方法。您必须先将其编译为二进制着色器blob

Microsoft::WRL::ComPtr<ID3DBlob> blob;
HRESULT hr = D3DCompile(
    pixelShaderByteCode.c_str(),
    pixelShaderByteCode.length(),
    nullptr,
    nullptr,
    nullptr,
    "main", "ps_4_0",
    D3DCOMPILE_ENABLE_STRICTNESS, 0,
    &blob;
    nullptr);
if (FAILED(hr))
    ...

Microsoft::WRL::ComPtr<ID3D11PixelShader> ps;
hr = m_deviceResources->GetD3DDevice()->CreatePixelShader(
    blob.GetBufferPointer(),
    blob.GetBufferSize(),
    nullptr,
    &ps);
if (FAILED(hr))
    ...
  

请注意,更好的答案是将着色器脱机编译,并使用fxc/Fh参数将二进制blob生成为C源头文件中的C数组。然后,您将包含该标头,该标头将着色器数据直接放入您的程序中。请参阅使用此方法的DirectX Tool Kit