DirectX11着色器编译问题

DirectX11 Shader Compilation Issue

本文关键字:编译 问题 DirectX11      更新时间:2023-10-16

我正在制作一个简单的DirectX应用程序,将一对三角形一起显示为四面体,这在开始时一直崩溃。我用VS2012调试器检查了错误发生在Shader应该从。fx文件编译的阶段,所以我认为它与Shader有关。我不知道我做错了什么。下面是我使用的着色器的代码。需要援助。

 struct Light
 {
   float3 pos;
   float4 ambient;
   float4 diffuse;
 };
cbuffer cbPerFrame
 {
  Light light;
 };
cbuffer cbPerObject
{
   float4x4 WVP;
   float4x4 World;
};
  struct VS_OUTPUT
 {
  float4 Pos : SV_POSITION;
  float4 worldPos : POSITION;
  float4 color    : COLOR;
  float3 normal : NORMAL;
 };
 VS_OUTPUT VS(float4 inPos : POSITION, float4 inColor : COLOR, float3 normal : NORMAL)
 {
   VS_OUTPUT output;
    output.Pos = mul(inPos, WVP);
output.worldPos = mul(inPos, World);
output.normal = mul(normal, World);
    output.color = inColor;
   return output;
  }    
   float4 PS(VS_OUTPUT input) : SV_TARGET
  {
    input.normal = normalize(input.normal);
    float4 diffuse = input.color;
float3 finalColor = float3(0.0f, 0.0f, 0.0f);
//Create the vector between light position and pixels position
float3 lightToPixelVec = light.pos - input.worldPos;

//Add the ambient light
float3 finalAmbient = diffuse * light.ambient;
//Turn lightToPixelVec into a unit length vector describing
//the pixels direction from the lights position
lightToPixelVec /= d; 
//Calculate how much light the pixel gets by the angle
//in which the light strikes the pixels surface
float howMuchLight = dot(lightToPixelVec, input.normal);
//If light is striking the front side of the pixel
if( howMuchLight > 0.0f )
{   
    //Add light to the finalColor of the pixel
    finalColor += diffuse * light.diffuse;
}
//make sure the values are between 1 and 0, and add the ambient
finalColor = saturate(finalColor + finalAmbient);   
//Return Final Color
return float4(finalColor, diffuse.a);
  }

这是编译应该发生的部分

   bool InitScene()
   {
 //Compile Shaders from shader file
hr = D3DX11CompileFromFile(L"Effects.fx", 0, 0, "VS", "vs_4_0", 0, 0, 0,
     &VS_Buffer, 0, 0);
if(FAILED(hr))
    {
   MessageBox(0, L"Shader Compilation - Failed",
        L"Error", MB_OK);
   return false;
    }
hr = D3DX11CompileFromFile(L"Effects.fx", 0, 0, "PS", "ps_4_0", 0, 0, 0, 
     &PS_Buffer, 0, 0);
//Create the Shader Objects
hr = d3d11Device->CreateVertexShader(VS_Buffer->GetBufferPointer(), 
    VS_Buffer->GetBufferSize(), NULL, &VS);
hr = d3d11Device->CreatePixelShader(PS_Buffer->GetBufferPointer(), 
    PS_Buffer->GetBufferSize(), NULL, &PS);
//Set Vertex and Pixel Shaders
d3d11DevCon->VSSetShader(VS, 0, 0);
d3d11DevCon->PSSetShader(PS, 0, 0);
light.pos = XMFLOAT3(0.25f, 0.5f, -1.0f);
light.ambient = XMFLOAT4(0.2f, 0.2f, 0.2f, 1.0f);
light.diffuse = XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f);
//X,Y,Z,R,G,B,A,NX,NY,NZ
//Create the vertex buffer
Vertex v[] =
{
    Vertex( 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f),
    Vertex( -0.5f, -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f),
    Vertex( 0.5f,  -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f),
    Vertex( 0.0f,  -0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 1.0f,0.0f, 1.0f, 0.0f)
};
DWORD indices[] = {
    //Front
    0,  1,  2,
    //Left
    0,  1,  3,
    //Right
    0,  2,  3,
    //Bottom
    1,  2,  3
};
D3D11_BUFFER_DESC indexBufferDesc;
ZeroMemory( &indexBufferDesc, sizeof(indexBufferDesc) );
indexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
indexBufferDesc.ByteWidth = sizeof(DWORD) * 4 * 3;
indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
indexBufferDesc.CPUAccessFlags = 0;
indexBufferDesc.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA iinitData;
 iinitData.pSysMem = indices;
d3d11Device->CreateBuffer(&indexBufferDesc, &iinitData, &IndexBuffer);
//d3d11DevCon->IASetIndexBuffer( squareIndexBuffer, DXGI_FORMAT_R32_UINT, 0);

D3D11_BUFFER_DESC vertexBufferDesc;
ZeroMemory( &vertexBufferDesc, sizeof(vertexBufferDesc) );
vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
vertexBufferDesc.ByteWidth = sizeof( Vertex ) * 4;
vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexBufferDesc.CPUAccessFlags = 0;
vertexBufferDesc.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA vertexBufferData; 
ZeroMemory( &vertexBufferData, sizeof(vertexBufferData) );
vertexBufferData.pSysMem = v;
hr = d3d11Device->CreateBuffer( &vertexBufferDesc, &vertexBufferData, &VertBuffer);
//Set the vertex buffer
UINT stride = sizeof( Vertex );
UINT offset = 0;
//d3d11DevCon->IASetVertexBuffers( 0, 1, &squareVertBuffer, &stride, &offset );
//Create the Input Layout
hr = d3d11Device->CreateInputLayout( layout,  
             numElements,VS_Buffer->GetBufferPointer(), 
             VS_Buffer->GetBufferSize(), &vertLayout );
//Set the Input Layout
d3d11DevCon->IASetInputLayout( vertLayout );
//Set Primitive Topology
d3d11DevCon->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
//Create the Viewport
D3D11_VIEWPORT viewport;
ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = width;
viewport.Height = height;
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 2.0f;
//Set the Viewport
d3d11DevCon->RSSetViewports(1, &viewport);
//Create the buffer to send to the cbuffer in effect file
D3D11_BUFFER_DESC cbbd; 
ZeroMemory(&cbbd, sizeof(D3D11_BUFFER_DESC));
cbbd.Usage = D3D11_USAGE_DEFAULT;
cbbd.ByteWidth = sizeof(cbPerObject);
cbbd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
cbbd.CPUAccessFlags = 0;
cbbd.MiscFlags = 0;
hr = d3d11Device->CreateBuffer(&cbbd, NULL, &cbPerObjectBuffer);
ZeroMemory(&cbbd, sizeof(D3D11_BUFFER_DESC));
cbbd.Usage = D3D11_USAGE_DEFAULT;
cbbd.ByteWidth = sizeof(cbPerFrame);
cbbd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
cbbd.CPUAccessFlags = 0;
cbbd.MiscFlags = 0;
hr = d3d11Device->CreateBuffer(&cbbd, NULL, &cbPerFrameBuffer);
//Camera information
camPosition = XMVectorSet( -5.0f, 5.0f, 8.0f, 0.0f );
camTarget = XMVectorSet( 0.0f, 0.0f, 0.0f, 0.0f );
camUp = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f );
//Set the View matrix
camView = XMMatrixLookAtLH( camPosition, camTarget, camUp );
//Set the Projection matrix
camProjection = XMMatrixPerspectiveFovLH( 0.4f*3.14f, width/height, 1.0f, 1000.0f);
return true;
    }

你的顶点着色器编译,但你的像素着色器不:

lightToPixelVec /= d; 

d未定义

因为在你的代码中你只检查VS编译结果,这是有意义的,它崩溃时试图创建像素着色器(当你发送一个无效的指针)。

正如在评论中提到的,检查功能级别也很重要,如果你为台式机/笔记本电脑开发,几乎任何设备都应该至少是功能级别10.1

在电话的情况下,你应该使用这些配置文件之一(哪个最匹配):ps_4_0_level_9_1、ps_4_0_level_9_2 ps_4_0_level_9_3