2015-02-28 2 views
0

Я написал простой код, чтобы сделать какие-то объекты с DirectX 11.Попутный нормальные данные шейдера

Положение было передано правильно шейдера. Однако, нормали , кажется, потеряны где-то. Я изменил шейдер, чтобы увидеть значение нормалей в качестве цвета (только отлаживать цели), и я получаю черный ящик (0,0,0 нормалей каждой вершины?), В правильном положении:

enter image description here

Обратите внимание, что на правой панели можно увидеть мои значения NORMAL (они правы!), Но в «местных» установлен только position, а остальные значения - NaN. Зачем?

closer look


Шейдер:

... //some constants 

struct VertexInputType 
{ 
    float4 position : POSITION; 
    float2 tex : TEXCOORD; 
    float3 normal : NORMAL; 
    float3 tangent : TANGENT; 
    //float3 binormal : BINORMAL; 
}; 

struct VS_OUTPUT 
{ 
    float4 Pos : SV_POSITION; 
    float4 worldPos : POSITION; 
    float2 TexCoord : TEXCOORD; 
    float3 normal : NORMAL; 
    float3 tangent : TANGENT; 
}; 

//VS_OUTPUT VS(float4 inPos : POSITION, float2 inTexCoord : TEXCOORD, float3 inNormal : NORMAL, float3 tangent : TANGENT) 
VS_OUTPUT VS(VertexInputType input) 
{ 
    VS_OUTPUT output; 
    output.Pos = mul(input.position, WVP); 
    output.worldPos = mul(input.position, World); 
    output.normal = input.normal; 
    return output; 
} 

float4 PS(VS_OUTPUT input) : SV_TARGET 
{ 
    return float4(input.normal*100, 1); 
} 

technique10 RENDER 
{ 
    pass P0 
    { 
     SetVertexShader(CompileShader(vs_4_0, VS())); 
     // SetGeometryShader(CompileShader(gs_4_0, GS()));  
     SetPixelShader(CompileShader(ps_4_0, PS())); 
     SetBlendState(SrcAlphaBlendingAdd, float4(0.0f, 0.0f, 0.0f, 0.0f), 0xFFFFFFFF); 
    }  
} 

Во время рендеринга я использую:

UINT stride = sizeof(Vertex); 
UINT offset = 0; 
context->IASetVertexBuffers(0, 1, &buffers->vertexBuffer, &stride, &offset); //set vertex buffer 
context->IASetIndexBuffer(buffers->indexBuffer, DXGI_FORMAT_R16_UINT, 0); //set index buffer 

for(int i=0; i<structure.subsets.size(); i++){ 
    //set matrices 
    DirectX::XMFLOAT4X4 view = camera->getView(); 
    DirectX::XMMATRIX camView = XMLoadFloat4x4(&view); 
    DirectX::XMFLOAT4X4 projection = camera->getProjection(); 
    DirectX::XMMATRIX camProjection = XMLoadFloat4x4(&projection); 
    DirectX::XMMATRIX worldViewProjectionMatrix = objectWorldMatrix * camView * camProjection; 

    //set the constants per object 
    ConstantBufferStructure constantsPerObject; 
    constantsPerObject.worldViewProjection = XMMatrixTranspose(worldViewProjectionMatrix); 
    constantsPerObject.world = XMMatrixTranspose(objectWorldMatrix); 

    //bind constants per object to constant buffer and send it to vertex and pixel shaders 
    context->UpdateSubresource(constantBuffer, 0, NULL, &constantsPerObject, 0, 0); 
    context->VSSetConstantBuffers(0, 1, &constantBuffer); 
    context->PSSetConstantBuffers(0, 1, &constantBuffer); 

    //context->PSSetSamplers(0,1,&m_sampleState); 
    context->RSSetState(RSCullDefault); 
    int start = structure.subsets[i]->getVertexIndexStart(); 
    int count = structure.subsets[i]->getVertexIndexAmmount(); 
    context->DrawIndexed(count, start, 0); 
} 

И для затенения инициализация:

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

//create the input layout 
VertexLayoutDescirption layoutDescription; //will gives us the data that is corresponding with Vertex structure 
hr = device->CreateInputLayout(layoutDescription.layout, layoutDescription.entriesCount, pVSBlob->GetBufferPointer(), pVSBlob->GetBufferSize(), &*vertexLayout); 
pVSBlob->Release(); 
context->IASetInputLayout(*vertexLayout); 

//compile the pixel shader 
ID3DBlob* pPSBlob = NULL; 
CompileShaderFromFile(C::toWChar(C::toString(pixelShaderFileName)), "PS", "ps_4_0", &pPSBlob); 

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

Где:

struct Vertex{//vertex structure 
    Vertex() : weightCount(0){} 
    Vertex(float x, float y, float z, float u, float v, float nx, float ny, float nz, float tx, float ty, float tz) 
     : position(x, y, z), textureCoordinates(u, v), normals(nx, ny, nz), tangents(tx, ty, tz), weightCount(0){} 
    Vertex(DirectX::XMFLOAT3 position, DirectX::XMFLOAT2 textureCoordinates, DirectX::XMFLOAT3 normals, DirectX::XMFLOAT3 biTangents) 
     : position(position), textureCoordinates(textureCoordinates), normals(normals), tangents(tangents), weightCount(0){} 

    DirectX::XMFLOAT3 position; 
    DirectX::XMFLOAT2 textureCoordinates; 
    DirectX::XMFLOAT3 normals; 
    DirectX::XMFLOAT3 tangents; 
    DirectX::XMFLOAT3 biTangents; 

    //will not be sent to shader (and used only by skinned models) 
    int startWeightIndex; //index in Subset::weights (from 0 to X for each subset separately) 
    int weightCount; //=0 means that it's not skinned vertex 
}; 

/* will be used by Shader, should be corresponding th Vertex (the data that we want to transfer to shader) */ 
struct VertexLayoutDescirption{ 
    D3D11_INPUT_ELEMENT_DESC layout[4]; //the input layout 
    UINT entriesCount; //the numer of elements of layout[], will be also used by Shader 

    VertexLayoutDescirption(){ 
     entriesCount = 4; 
     for(UINT i=0; i<entriesCount; i++){ 
      layout[i].SemanticIndex = 0; 
      layout[i].Format = DXGI_FORMAT_R32G32B32_FLOAT; 
      layout[i].InputSlot = 0; 
      layout[i].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA; 
      layout[i].InstanceDataStepRate = 0; 
     } 

     layout[0].SemanticName ="POSITION"; 
     layout[0].AlignedByteOffset = 0; //(not D3D11_APPEND_ALIGNED_ELEMENT) 

     layout[1].SemanticName ="TEXCOORD"; 
     layout[1].AlignedByteOffset = 12; //or D3D11_APPEND_ALIGNED_ELEMENT 

     layout[2].SemanticName ="NORMAL"; 
     layout[2].AlignedByteOffset = 20; //or D3D11_APPEND_ALIGNED_ELEMENT 

     layout[3].SemanticName ="TANGENT"; 
     layout[3].AlignedByteOffset = 32; //or D3D11_APPEND_ALIGNED_ELEMENT 
    } 
}; 

коробки модель:

/*top vertices*/ 
structure.vertices[0] = Vertex(/*pos*/ -1.0f, +1.0f, -1.0f, /*uv*/ 1.0f, 1.0f, /*normals*/ 0.0f, 1.0f, -1.0f, /*tan*/ +1.0f, -1.0f, 1.0f); 
structure.vertices[1] = Vertex(/*pos*/ +1.0f, +1.0f, -1.0f, /*uv*/ 0.0f, 1.0f, /*normals*/ 0.0f, 1.0f, +1.0f, /*tan*/ +1.0f, -1.0f, 1.0f); 
structure.vertices[2] = Vertex(/*pos*/ +1.0f, +1.0f, +1.0f, /*uv*/ 1.0f, 0.0f, /*normals*/ 0.0f, 1.0f, +1.0f, /*tan*/ +1.0f, +1.0f, 1.0f); 
structure.vertices[3] = Vertex(/*pos*/ -1.0f, +1.0f, +1.0f, /*uv*/ 0.0f, 0.0f, /*normals*/ 0.0f, 1.0f, -1.0f, /*tan*/ +1.0f, +1.0f, 1.0f); 

/*bottom vertices*/                        
structure.vertices[4] = Vertex(/*pos*/ -1.0f, -1.0f, -1.0f, /*uv*/ 1.0f, 0.0f, /*normals*/ 0.0f, 1.0f, -1.0f, /*tan*/ -1.0f, -1.0f, 1.0f); 
structure.vertices[5] = Vertex(/*pos*/ +1.0f, -1.0f, -1.0f, /*uv*/ 0.0f, 0.0f, /*normals*/ 0.0f, 1.0f, +1.0f, /*tan*/ -1.0f, -1.0f, 1.0f); 
structure.vertices[6] = Vertex(/*pos*/ +1.0f, -1.0f, +1.0f, /*uv*/ 1.0f, 1.0f, /*normals*/ 0.0f, 1.0f, +1.0f, /*tan*/ -1.0f, +1.0f, 1.0f); 
structure.vertices[7] = Vertex(/*pos*/ -1.0f, -1.0f, +1.0f, /*uv*/ 0.0f, 1.0f, /*normals*/ 0.0f, 1.0f, -1.0f, /*tan*/ -1.0f, +1.0f, 1.0f); 

buffers = new Buffers(); 

D3D11_BUFFER_DESC bd; 
ZeroMemory(&bd, sizeof(bd)); 
bd.Usage = D3D11_USAGE_DEFAULT; //D3D11_USAGE_DYNAMIC 
bd.ByteWidth = sizeof(Vertex) * structure.getVerticesCount(); 
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; 
bd.CPUAccessFlags = 0; 
D3D11_SUBRESOURCE_DATA InitData; 
ZeroMemory(&InitData, sizeof(InitData)); 
InitData.pSysMem = structure.vertices; 
if(device->CreateBuffer(&bd, &InitData, &buffers->vertexBuffer) != S_OK){ 
    return false; 
} 

... //index buffer 

Почему нормали не были приняты шейдером в то время как позиция? Что я пропустил?

ответ

0

В шейдер файл пытается использовать float3 normal : TEXCOORD1; или float3 normal : TEXCOORD2; или любой семантический TEXCOORD с любым индексом вместо float3 normal : NORMAL; в VS_OUTPUT структуры,

Смежные вопросы