简体   繁体   English

在DirectX 11中为着色器添加常规信息 - 在着色器中看不到法线?

[英]Adding normal information for the shader in DirectX 11 - normals not visible in shader?

I wanted to add a normal map information for my shader. 我想为我的着色器添加法线贴图信息。 I was using tutorial 5 from DirectX 11 C++ SDK as a base. 我使用DirectX 11 C ++ SDK的教程5作为基础。

The code for shader creating is (I'm putting it just to be sure I have posted every important information, but I think that only the D3D11_INPUT_ELEMENT_DESC layout[] matters): 着色器创建的代码是(我只是为了确保我已经发布了所有重要信息,但我认为只有D3D11_INPUT_ELEMENT_DESC布局[]很重要):

// Compile the vertex shader
ID3DBlob* pVSBlob = NULL;
HRESULT hr = CompileShaderFromFile( strToWchart(vertexShaderFileName), "VS", "vs_4_0", &pVSBlob );

// Create the vertex shader
hr = device->CreateVertexShader( pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), NULL, &vertexShader );
if( FAILED( hr ) )
{   
pVSBlob->Release();
}


// Define the input layout
D3D11_INPUT_ELEMENT_DESC layout[] =
{
    { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    { "NORMAL", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 12, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};

UINT numElements = ARRAYSIZE( layout );

// Create the input layout
hr = device->CreateInputLayout( layout, numElements, pVSBlob->GetBufferPointer(),
                                      pVSBlob->GetBufferSize(), &*vertexLayout );
pVSBlob->Release();

    // Set the input layout
context->IASetInputLayout( *vertexLayout );

// Compile the pixel shader
ID3DBlob* pPSBlob = NULL;
hr = CompileShaderFromFile( strToWchart(pixelShaderFileName), "PS", "ps_4_0", &pPSBlob );

// Create the pixel shader
hr = device->CreatePixelShader( pPSBlob->GetBufferPointer(), pPSBlob->GetBufferSize(), NULL, &pixelShader );
pPSBlob->Release();

}

So simply I have changed D3D11_INPUT_ELEMENT_DESC layout[] to (adding "NORMAL" row): 所以我简单地将D3D11_INPUT_ELEMENT_DESC layout []更改为(添加“NORMAL”行):

D3D11_INPUT_ELEMENT_DESC layout[] =
{
    { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    { "NORMAL", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 12, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};

Than I have changed few lines in the box creating method: 比我在框创建方法中更改了几行:

// Create vertex buffer
SimpleVertex vertices[] =
{
    { XMFLOAT3(  - halfSize.getX(),  + halfSize.getY(),  - halfSize.getZ() ), XMFLOAT4( 0.0f, 0.0f, 1.0f, 1.0f ), XMFLOAT4( 0.0f, 0.0f, 1.0f, 1.0f ) },
    { XMFLOAT3(  + halfSize.getX(),  + halfSize.getY(),  - halfSize.getZ() ), XMFLOAT4( 0.0f, 1.0f, 0.0f, 1.0f ), XMFLOAT4( 0.0f, 1.0f, 1.0f, 1.0f ) },
    { XMFLOAT3(  + halfSize.getX(),  + halfSize.getY(),  + halfSize.getZ() ), XMFLOAT4( 0.0f, 1.0f, 1.0f, 1.0f ), XMFLOAT4( 0.0f, 0.0f, 1.0f, 1.0f ) },
    { XMFLOAT3(  - halfSize.getX(),  + halfSize.getY(),  + halfSize.getZ() ), XMFLOAT4( 1.0f, 0.0f, 0.0f, 1.0f ), XMFLOAT4( 0.0f, 0.0f, 1.0f, 1.0f ) },
    { XMFLOAT3(  - halfSize.getX(),  - halfSize.getY(),  - halfSize.getZ() ), XMFLOAT4( 1.0f, 0.0f, 1.0f, 1.0f ), XMFLOAT4( 0.0f, 1.0f, 1.0f, 1.0f ) },
    { XMFLOAT3(  + halfSize.getX(),  - halfSize.getY(),  - halfSize.getZ() ), XMFLOAT4( 1.0f, 1.0f, 0.0f, 1.0f ), XMFLOAT4( 0.0f, 0.0f, 1.0f, 1.0f ) },
    { XMFLOAT3(  + halfSize.getX(),  - halfSize.getY(),  + halfSize.getZ() ), XMFLOAT4( 1.0f, 1.0f, 1.0f, 1.0f ), XMFLOAT4( 1.0f, 0.0f, 1.0f, 0.0f ) },
    { XMFLOAT3(  - halfSize.getX(),  - halfSize.getY(),  + halfSize.getZ() ), XMFLOAT4( 0.0f, 0.0f, 0.0f, 1.0f ), XMFLOAT4( 0.0f, 0.0f, 1.0f, 1.0f ) },
};

So the last XMFLOAT4 in all rows are normal (not important that these are wrong normals, now I just want to make it visible in vertex shader). 所以所有行中的最后一个XMFLOAT4都是正常的(不重要的是这些是错误的法线,现在我只想让它在顶点着色器中可见)。

I have also changed SimpleVertex: 我也改变了SimpleVertex:

struct SimpleVertex
{
    XMFLOAT3 Pos;
    XMFLOAT4 Color;
    XMFLOAT4 Normal;
};

And my shader to check if the normals exists: 我的着色器检查是否存在法线:

cbuffer ConstantBuffer : register( b0 )
{
matrix World;
matrix View;
matrix Projection;
}

struct VS_INPUT
{
    float4 Pos : POSITION;
    float4 Color : COLOR;
float4 Normal : NORMAL; 
};

struct PS_INPUT
{
    float4 Pos : SV_POSITION;
    float4 Color : COLOR;
};

PS_INPUT VS( VS_INPUT input )
{
    PS_INPUT output = (PS_INPUT)0;



    output.Pos = mul( input.Pos, World );
    output.Pos = mul( output.Pos, View );
    output.Pos = mul( output.Pos, Projection );
output.Color = input.Normal; //just to know if I have a normals
    return output;
}

float4 PS( PS_INPUT input) : SV_Target
{
    return input.Color;
}

But the effect was just a black box (even with output.Color = input.Normal). 但效果只是一个黑盒子(即使是output.Color = input.Normal)。

So, what's the problem? 所以有什么问题? I have to change something else to get normals info in the shader? 我必须更改其他内容才能在着色器中获取法线信息?

It looks like your D3D11_INPUT_ELEMENT_DESC array doesn't match your vertex data. 看起来你的D3D11_INPUT_ELEMENT_DESC数组与你的顶点数据不匹配。 Try this: 试试这个:

// Define the input layout
D3D11_INPUT_ELEMENT_DESC layout[] =
{
  { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
  { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
  { "NORMAL", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 28, D3D11_INPUT_PER_VERTEX_DATA, 0 }
};

The offset for your normals should include the offset for "POSITION" (12 byte) and "COLOR" (16 byte, not 12). 法线的偏移量应包括“POSITION”(12字节)和“COLOR”(16字节,而不是12)的偏移量。 And I have no idea why you set the input slot for this. 我不知道为什么你为此设置输入槽。

I don't know if it's your problem but something looks wrong here :- 我不知道这是不是你的问题,但这里看起来有些不对劲: -

{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
 { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
 { "NORMAL", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 12, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 }, }; 

The entry for colour r32g32b32a32 type which is 16 bytes in size but that doesn't seem to be right, I'd expect the 24 to be 28 on the last line. 颜色r32g32b32a32类型的条目,大小为16字节,但似乎不对,我希望最后一行24是28。 Plus you set the input slot to 12, I'm not quite sure why? 另外你把输入槽设置为12,我不太清楚为什么?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM