Reputation: 6377
Shader successfully compiles to cso file at build time. But when I try to call CreateVertexShader - I get an error:
D3D11 ERROR: ID3D11Device::CreateVertexShader: Encoded Vertex Shader size doesn't match specified size.
I set shader type "Effect(/fx)", entry point: "VS", shader model - 5.0.
I tried models 4.0, 4.1 - the error is different:
D3D11 ERROR: ID3D11Device::CreateVertexShader: Shader is corrupt or in an unrecognized format.
My code:
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);
Device features:
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,
};
My shader code:
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);
}
Upvotes: 1
Views: 1112
Reputation: 41127
Visual Studio's build-in HLSL build rules are useful for small projects, but there is one concept to keep in mind: Visual Studio's project system assumes each source file is used to generate one compiled object file (in this case .cso
).
To make this work when you have combined shader types in the same file, you just need to create some additional files. For example:
First file is MyShader.hlsli
. This would contain your combined shader code for VS & PS
The second file MyShaderVS.hlsl
#include "MyShader.hlsli"
The third file MyShaderPS.hlsl
#include "MyShader.hlsli"
You then set the VS Project build properties up to build the MyShaderVS.hlsl
as a Vertex Shader (/vs
). You build the MyShaderPS.hlsl
as a Pixel Shader (/ps)
. Set the Entry-points appropriate for each one.
The result will get your original shader code built more than once.
The Effects file system that had one
.fx
that compiled into lots of shader blobs all in one compiled object works with the Visual Studio system, but (a) the compiler support is deprecated, and (b) you need a runtime library to use it from GitHub. Using HLSL shader types instead is recommended. See the wiki.
Upvotes: 3