2012-07-04 3 views
3

Я хотел добавить нормальную информацию о карте для своего шейдера. Я использовал учебник 5 из DirectX 11 C++ SDK в качестве базы.Добавление нормальной информации для шейдера в DirectX 11 - нормали, не видимые в шейдере?

Код для шейдерного СОЗДАНИЯ это (я кладу это просто, чтобы убедиться, я отправил каждую важную информацию, но я думаю, что только макет 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 макет [], чтобы (добавление "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 = вход .Нормальный).

Итак, в чем проблема? Мне нужно что-то изменить, чтобы получить информацию о нормалях в шейдере?

ответ

4

Похоже, что ваш массив 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 } 
}; 

Смещение для ваших нормалей должна включать в себя смещение "ПОЛОЖЕНИЕ" (12 байт) и "COLOR" (16 байт, а не 12). И я понятия не имею, почему вы устанавливаете входной слот для этого.

+0

Это было. Спасибо. – PolGraphic

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 байт, но это, кажется, не прав, я 'd ожидать, что 24 будет 28 на последней строке. Кроме того, вы устанавливаете входной слот на 12, я не совсем уверен, почему?

+0

Думаю, я не думал ... Спасибо. – PolGraphic