【问题标题】:Unable to create vertex shader from cso file (created from fx file)无法从 cso 文件创建顶点着色器(从 fx 文件创建)
【发布时间】:2020-04-26 06:32:44
【问题描述】:

Shader 在构建时成功编译为 cso 文件。但是当我尝试调用 CreateVertexShader - 我得到一个错误:

D3D11 错误:ID3D11Device::CreateVertexShader:编码顶点着色器大小与指定大小不匹配。

我设置着色器类型“Effect(/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);
}

【问题讨论】:

  • 你应该在编译时将着色器类型设置为Vertex Shader (/vs)
  • 它有效。但我在同一个文件中有两个着色器,像素着色器现在不编译。

标签: c++ uwp directx-11


【解决方案1】:

Visual Studio 的内置 HLSL 构建规则对于小型项目很有用,但要记住一个概念:Visual Studio 的项目系统假定每个源文件都用于生成一个已编译的目标文件(在本例中为 .cso )。

当您在同一个文件中组合了着色器类型时,要使这项工作发挥作用,您只需要创建一些额外的文件。例如:

第一个文件是MyShader.hlsli。这将包含您用于 VS 和 PS 的组合着色器代码

第二个文件MyShaderVS.hlsl

#include "MyShader.hlsli"

第三个文件MyShaderPS.hlsl

#include "MyShader.hlsli"

然后设置 VS 项目构建属性以将 MyShaderVS.hlsl 构建为顶点着色器 (/vs)。您将MyShaderPS.hlsl 构建为像素着色器(/ps)。为每个设置适当的入口点。

结果将使您的原始着色器代码构建不止一次。

具有一个 .fx 的效果文件系统在一个编译对象中编译成大量着色器 blob 可与 Visual Studio 系统一起使用,但 (a) 编译器支持已弃用,并且 (b) 您需要运行时库从GitHub 使用它。建议使用 HLSL 着色器类型。见the wiki

【讨论】:

    猜你喜欢
    • 2016-03-24
    • 1970-01-01
    • 2021-09-10
    • 2011-10-28
    • 2020-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多