【问题标题】:Adding normal information for the shader in DirectX 11 - normals not visible in shader?在 DirectX 11 中为着色器添加法线信息 - 法线在着色器中不可见?
【发布时间】:2012-07-04 15:28:27
【问题描述】:

我想为我的着色器添加法线贴图信息。我使用 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)。

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

【问题讨论】:

    标签: c++ directx shader hlsl normals


    【解决方案1】:

    您的 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 字节)的偏移量。而且我不知道你为什么要为此设置输入槽。

    【讨论】:

      【解决方案2】:

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

      { "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,我不太清楚为什么?

      【讨论】:

      • 我想我没想到...谢谢。
      猜你喜欢
      • 2012-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-26
      相关资源
      最近更新 更多