Невозможно создать вершинный шейдер из файла cso (созданного из файла fx) - PullRequest
1 голос
/ 08 января 2020

Шейдер успешно компилируется в файл cso во время сборки. Но когда я пытаюсь вызвать CreateVertexShader - я получаю сообщение об ошибке:

D3D11 ОШИБКА: ID3D11Device :: CreateVertexShader: Размер закодированного вершинного шейдера не соответствует указанному размеру.

Я установил тип шейдера «Эффект (/ fx)», точка входа: «VS», модель шейдера - 5.0.

Я пробовал модели 4.0, 4.1 - ошибка другая:

D3D11 ОШИБКА: ID3D11Device :: CreateVertexShader: шейдер поврежден или в нераспознанном формате.

Мой код:

ID3DBlob* pVSBlob = NULL;
HRESULT hr = D3DReadFileToBlob((WCHAR*)name.c_str(), &pVSBlob);
if (FAILED(hr))
{
    return;
}

hr = g_pd3dDevice->CreateVertexShader(pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, &vertexShader); 

Функции устройства:

D3D_FEATURE_LEVEL featureLevels[] =
{
    D3D_FEATURE_LEVEL_12_1,
    D3D_FEATURE_LEVEL_12_0,
    D3D_FEATURE_LEVEL_11_1,
    D3D_FEATURE_LEVEL_11_0,
    D3D_FEATURE_LEVEL_10_1,
    D3D_FEATURE_LEVEL_10_0,
};

Мой код шейдера:

cbuffer cbTrunkCutMode : register(b1)
{
    float HighlightAdj;
};

cbuffer cbChangesEveryFrame : register(b0)
{
    matrix Matrices[2];
};


struct VS_INPUT
{
    float3 VertexPosition_modelspace : POSITION;
    float3 vertexNormal_modelspace : NORMAL;
    float age : AGE;
};

struct PS_INPUT
{
    float4 Position : SV_POSITION;
    float3 Position_worldspace : WSPOSITION;
    float3 Normal_cameraspace : NORMAL;
    float3 EyeDirection_cameraspace : EYEDIRECTION;
    float age : AGE;
};

PS_INPUT VS(VS_INPUT input)
{
    PS_INPUT output;
    output.Position= mul(Matrices[1], float4(input.VertexPosition_modelspace, 1.0));
    output.Position_worldspace = input.VertexPosition_modelspace;

    float3 vertexPosition_cameraspace = mul(Matrices[0], float4(input.VertexPosition_modelspace,1.0)).xyz;
    output.EyeDirection_cameraspace = float3(0.0, 0.0, 0.0) - vertexPosition_cameraspace;

    output.Normal_cameraspace = mul((float3x3)Matrices[0], input.vertexNormal_modelspace); // Only correct if ModelMatrix does not scale the model ! Use its inverse transpose if not.
    output.age = input.age;

    return output;
}

static const float3 LightPosition = normalize(float3(1.0, 1.0, 1.0));

float4 PS(PS_INPUT input) : SV_Target
{
    float3 MaterialDiffuseColor = float3(0.05,0.3,0.05);
    float3 MaterialAmbientColor = float3(0.3, 0.3, 0.3) * MaterialDiffuseColor;
    float3 MaterialSpecularColor = 0.5*MaterialDiffuseColor;

    float3 n = normalize(input.Normal_cameraspace);
    float3 l = LightPosition;
    float cosTheta = clamp(dot(n,l), 0.0,1.0);

    float3 E = normalize(input.EyeDirection_cameraspace);
    float3 R = reflect(-l,n);
    float cosAlpha = clamp(dot(E,R), 0.0,1.0);

    return float4((
        float3(HighlightAdj - input.age, -HighlightAdj, -input.age - HighlightAdj) +
        MaterialAmbientColor +
        MaterialDiffuseColor * cosTheta +
        MaterialSpecularColor * pow(cosAlpha, 5.0)),1);
}

1 Ответ

2 голосов
/ 09 января 2020

Встроенные в Visual Studio правила сборки HLSL полезны для небольших проектов, но следует учитывать одну концепцию: система проектов Visual Studio предполагает, что каждый исходный файл используется для создания одного скомпилированного объектного файла (в данном случае .cso ).

Чтобы это работало, когда вы комбинировали типы шейдеров в одном файле, вам просто нужно создать несколько дополнительных файлов. Например:

Первый файл - MyShader.hlsli. Он будет содержать ваш комбинированный код шейдера для VS & PS

Второй файл MyShaderVS.hlsl

#include "MyShader.hlsli"

Третий файл MyShaderPS.hlsl

#include "MyShader.hlsli"

Затем вы установите свойства сборки VS Project для построения MyShaderVS.hlsl как вершинного шейдера (/vs). Вы строите MyShaderPS.hlsl как пиксельный шейдер (/ps). Установите точки входа, соответствующие каждому из них.

В результате ваш исходный код шейдера будет построен более одного раза.

Файловая система Effects, в которой была одна .fx, скомпилированная во множество шейдерных двоичных объектов в одном скомпилированном объекте, работает с системой Visual Studio, но (a) поддержка компилятора устарела, и (b) вам нужна среда выполнения библиотека для использования из GitHub . Рекомендуется использовать вместо этого типы шейдеров HLSL. См. вики .

...