繁体   English   中英

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

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

我想为我的着色器添加法线贴图信息。 我使用DirectX 11 C ++ SDK的教程5作为基础。

着色器创建的代码是(我只是为了确保我已经发布了所有重要信息,但我认为只有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();

}

所以我简单地将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 },
};

比我在框创建方法中更改了几行:

// 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 ) },
};

所以所有行中的最后一个XMFLOAT4都是正常的(不重要的是这些是错误的法线,现在我只想让它在顶点着色器中可见)。

我也改变了SimpleVertex:

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

我的着色器检查是否存在法线:

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;
}

但效果只是一个黑盒子(即使是output.Color = input.Normal)。

所以有什么问题? 我必须更改其他内容才能在着色器中获取法线信息?

看起来你的D3D11_INPUT_ELEMENT_DESC数组与你的顶点数据不匹配。 试试这个:

// 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 }
};

法线的偏移量应包括“POSITION”(12字节)和“COLOR”(16字节,而不是12)的偏移量。 我不知道为什么你为此设置输入槽。

我不知道这是不是你的问题,但这里看起来有些不对劲: -

{ "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 }, }; 

颜色r32g32b32a32类型的条目,大小为16字节,但似乎不对,我希望最后一行24是28。 另外你把输入槽设置为12,我不太清楚为什么?

暂无
暂无

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

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