DirectX 11漫射照明问题

时间:2014-07-22 19:01:33

标签: 3d directx game-engine directx-11

目前我正在从这些教程中学习DirectX 11: http://www.rastertek.com/tutdx11.html

教程工作正常,所以我在我的小引擎中实现了这些东西。问题是,directx不会在所有多边形上渲染漫反射光,并且光的方向似乎是错误的。

以下是具有两个多边形的渲染平面的图片: https://www.dropbox.com/s/9m94n1q7oichi2b/DX11Plane.PNG

以下是源代码的一些部分:

//The vertex structure
struct BE_SVERTEX{
    BE_SVERTEX(){

    }

    BE_SVERTEX(D3DXVECTOR3 position, D3DXVECTOR2 texture, D3DXVECTOR3 normal){
        this->position = position;
        this->texture = texture;
        this->normal = normal;
    }

    BE_SVERTEX(const BE_SVERTEX &v){
        this->normal = v.normal;
        this->position = v.position;
        this->texture = v.texture;
    }

    D3DXVECTOR3 position;
    D3DXVECTOR2 texture;
    D3DXVECTOR3 normal;
};

这里我创建了顶点和索引缓冲区:

        aVertices = new BE_SVERTEX[vVertices.size()];
        aIndices = new unsigned long[vIndices.size()];

        //Filling the vertex and index array with the data from the wavefront file
        for (int i = 0; i < vVertices.size(); i++){
            //To test the normalvector of the plane i have set the normalvectors from all vertices of the plane manually
            aVertices[i].normal = D3DXVECTOR3{ 0.0f, 0.0f, -1.0f};
            aVertices[i].position = vVertices[i].position;
            aVertices[i].texture = vVertices[i].texture;
            //The indices for the index buffer. Currently the index buffer is unnecessary because the engine creates for each polygon 3 new vertices.
            aIndices[i] = vIndices[i];
        }

        //Creating the vertex buffer
        vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
        vertexBufferDesc.ByteWidth = sizeof(BE_SVERTEX) * vVertices.size();
        vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
        vertexBufferDesc.CPUAccessFlags = 0;
        vertexBufferDesc.MiscFlags = 0;
        vertexBufferDesc.StructureByteStride = 0;

        vertexData.pSysMem = aVertices;
        vertexData.SysMemPitch = 0;
        vertexData.SysMemSlicePitch = 0;

        mesh->vertexBuffer = NULL;

        result = device->CreateBuffer(&vertexBufferDesc, &vertexData, &mesh->vertexBuffer);
        if (FAILED(result)){
            return BE_SRESULT{ 7, false };
        }
        else{
            //Creating the index buffer
            indexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
            indexBufferDesc.ByteWidth = sizeof(unsigned long) * vIndices.size();
            indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
            indexBufferDesc.CPUAccessFlags = 0;
            indexBufferDesc.MiscFlags = 0;
            indexBufferDesc.StructureByteStride = 0;

            indexData.pSysMem = aIndices;
            indexData.SysMemPitch = 0;
            indexData.SysMemSlicePitch = 0;

            mesh->indexBuffer = NULL;

            result = device->CreateBuffer(&indexBufferDesc, &indexData, &mesh-       >indexBuffer);
            if (FAILED(result)){
                return BE_SRESULT{ 7, false };
            }

着色器创建的某些部分:

        //Creating the input layout
        polygonLayout[0].SemanticName = "POSITION";
        polygonLayout[0].SemanticIndex = 0;
        polygonLayout[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
        polygonLayout[0].InputSlot = 0;
        polygonLayout[0].AlignedByteOffset = 0;
        polygonLayout[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
        polygonLayout[0].InstanceDataStepRate = 0;

        polygonLayout[1].SemanticName = "TEXCOORD";
        polygonLayout[1].SemanticIndex = 0;
        polygonLayout[1].Format = DXGI_FORMAT_R32G32B32_FLOAT;
        polygonLayout[1].InputSlot = 0;
        polygonLayout[1].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
        polygonLayout[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
        polygonLayout[1].InstanceDataStepRate = 0;

        polygonLayout[2].SemanticName = "NORMAL";
        polygonLayout[2].SemanticIndex = 0;
        polygonLayout[2].Format = DXGI_FORMAT_R32G32B32_FLOAT;
        polygonLayout[2].InputSlot = 0;
        polygonLayout[2].AlignedByteOffset = D3D11_APPEND_ALIGNED_ELEMENT;
        polygonLayout[2].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
        polygonLayout[2].InstanceDataStepRate = 0;

        numElements = sizeof(polygonLayout) / sizeof(polygonLayout[0]);

        result = device->CreateInputLayout(polygonLayout, numElements, vertexShaderBuffer->GetBufferPointer(), vertexShaderBuffer->GetBufferSize(), &layout);

着色器的渲染功能:

//Setting rendering settings. This methode is called every frame before shader   rendering.
BE_SRESULT ObjectElements::BE_OE_Shader::setShaderParameters(D3DXMATRIX worldMatrix, D3DXMATRIX viewMatrix, D3DXMATRIX projectionMatrix, ID3D11ShaderResourceView *texture,   D3DXVECTOR3 lightDirection, D3DXVECTOR4 diffuseColor){
    HRESULT result;
    D3D11_MAPPED_SUBRESOURCE mappedResource;
    unsigned int bufferNumber;
    MatrixBufferType *dataPtr;
    LightBufferType *dataPtr2;

    D3DXMatrixTranspose(&worldMatrix, &worldMatrix);
    D3DXMatrixTranspose(&viewMatrix, &viewMatrix);
    D3DXMatrixTranspose(&projectionMatrix, &projectionMatrix);

    result = immediateDevice->Map(matrixBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
    if (FAILED(result)){
        return BE_SRESULT{ 8, false };
    }
    else{

        dataPtr = (MatrixBufferType*)mappedResource.pData;

        dataPtr->world = worldMatrix;
        dataPtr->view = viewMatrix;
        dataPtr->projection = projectionMatrix;

        immediateDevice->Unmap(matrixBuffer, 0);

        bufferNumber = 0;

        immediateDevice->VSSetConstantBuffers(bufferNumber, 1, &matrixBuffer);
        immediateDevice->PSSetShaderResources(0, 1, &texture);

        result = immediateDevice->Map(lightBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);

        if (FAILED(result)){
            return BE_SRESULT{ 8, false };
        }
        else{

            dataPtr2 = (LightBufferType*)mappedResource.pData;

            dataPtr2->diffuseColor = diffuseColor;
            dataPtr2->lightDirection = lightDirection;
            dataPtr2->padding = 0.0f;

            immediateDevice->Unmap(lightBuffer, 0);

            bufferNumber = 0;

            immediateDevice->PSSetConstantBuffers(bufferNumber, 1, &lightBuffer);

            return BE_SRESULT{ 0, true };
        }
    }
}

   //The render function of the shader
   void ObjectElements::BE_OE_Shader::render(int indexCount){
       immediateDevice->IASetInputLayout(layout);

       immediateDevice->VSSetShader(vertexShader, NULL, 0);
       immediateDevice->PSSetShader(pixelShader, NULL, 0);

       immediateDevice->PSSetSamplers(0, 1, &sampleState);

       immediateDevice->DrawIndexed(indexCount, 0, 0);
   }

光线方向为D3DXVECTOR3 {0.0f,0.0f,1.0f}。

我已经搜索了几个小时才发现故障,但灯仍然无法正常工作。我使用的着色器与教程中的着色器相同。

我希望有人可以帮助我。

1 个答案:

答案 0 :(得分:0)

顶点缓冲区包含一个根据BE_SVERTEX的float2 uv,但是输入布局声明了一个float3,并且由于你使用了自动偏移,所以法线被错误地偏移了。

polygonLayout[1].Format = DXGI_FORMAT_R32G32B32_FLOAT;

成为

polygonLayout[1].Format = DXGI_FORMAT_R32G32_FLOAT;