DirectX 11.2三角形形状被法向量扭曲

时间:2014-04-02 17:04:35

标签: c++ directx

我是DirectX的新手。我现在在某种程度上有一个愚蠢的问题。

我使用的是Windows 8.1 DirectX 11.2,我使用的是右手坐标系。

我尝试将纹理应用于x-y平面中的等边三角形,并以(0,0,0)为中心。 但输出形状是扭曲的(它看起来不像等边三角形!)。理论上,如果从x轴看,我什么也看不见,因为等边三角形位于x-y平面。但事实证明,我可以看到三角形。另外,如果我改变法向量的值,输出形状也会改变!我不明白为什么,请帮忙!

以下是视图矩阵配置:

    static const XMVECTORF32 eye = { 0.0f, 0.0f, 1.5f, 0.0f };
    static const XMVECTORF32 at = { 0.0f, 0.0f, 0.0f, 0.0f };
    static const XMVECTORF32 up = { 0.0f, 1.0f, 0.0f, 0.0f };

这是顶点着色器:

    cbuffer ModelViewProjectionConstantBuffer : register(b0)
    {
        matrix model;
        matrix view;
        matrix projection;
    };

    struct VertexShaderInput
    {
        float3 pos : POSITION;
        float3 norm : NORMAL;
        float2 tex : TEXCOORD0;
    };

    struct PixelShaderInput
    {
        float4 pos : SV_POSITION;
        float3 norm : NORMAL;
        float2 tex : TEXCOORD0;
    };

    PixelShaderInput main(VertexShaderInput input)
    {
        PixelShaderInput vertexShaderOutput;
        float4 pos = float4(input.pos, 1.0f);
        pos = mul(pos, model);
        pos = mul(pos, view);
        pos = mul(pos, projection);
        vertexShaderOutput.pos = pos;
        vertexShaderOutput.tex = input.tex;
        vertexShaderOutput.norm = mul(float4(normalize(input.norm), 0.0f), model).xyz;
        return vertexShaderOutput;
    }

这是pixelshader:

    Texture2D Texture : register(t0);
    SamplerState Sampler : register(s0);

    struct PixelShaderInput
    {
            float4 pos : SV_POSITION;
            float3 norm : NORMAL;
            float2 tex : TEXCOORD0;
    };

    float4 main(PixelShaderInput input) : SV_TARGET
    {
        float3 lightDirection = normalize(float3(0, 0, -1));
        return Texture.Sample(Sampler, input.tex); //* (0.8f *                    saturate(dot(normalize(input.norm), -lightDirection)) + 0.2f);
    }

这是坐标:

    VertexPositionTexture vertexPositionTexture[] =
{
    { XMFLOAT3(-1.5, -0.5*sqrtf(3), 0.0f), XMFLOAT3(0.0f, 0.0f, 0.4f),   XMFLOAT2(0.0, 1.0) },
    { XMFLOAT3(0.0f, sqrtf(3), 0.0f), XMFLOAT3(0.0f, 0.0f, 0.4f), XMFLOAT2(0.5, 0.0) },
    { XMFLOAT3(1.5, -0.5*sqrtf(3), 0.0f), XMFLOAT3(0.0f, 0.0f, 0.4f), XMFLOAT2(1.0, 1.0) },
    }

索引数组按顺时针顺序只是{0,1,2}。

因此,如果我将vertexPositionTexture XMFLOAT3(0.0,0.0,0.4)中的法线向量值更改为XMFLOAT3(0.0,0.0,-1),则形状肯定会发生变化。我不知道为什么?

以下是我创建DeviceDependentResources的方法:

    void TextureSceneRenderer::CreateDeviceDependentResources()
   {
        // Load shaders asynchronously.
        auto loadVSTask = DX::ReadDataAsync(L"TextureVertexShader.cso");
        auto loadPSTask = DX::ReadDataAsync(L"TexturePixelShader.cso");
        BasicLoader^ loader = ref new BasicLoader(m_deviceResources->GetD3DDevice());

        loader->LoadTexture(
            L"cat.dds",
            &m_texture,
            &m_textureSRV
    );

        // create the sampler
        D3D11_SAMPLER_DESC samplerDesc;
        ZeroMemory(&samplerDesc, sizeof(D3D11_SAMPLER_DESC));
        samplerDesc.Filter = D3D11_FILTER_ANISOTROPIC;
        samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
        samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
        samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
        samplerDesc.MipLODBias = 0.0f;
        // use 4x on feature level 9.2 and above, otherwise use only 2x
        samplerDesc.MaxAnisotropy = 8;
        samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
        samplerDesc.BorderColor[0] = 0.0f;
        samplerDesc.BorderColor[1] = 0.0f;
        samplerDesc.BorderColor[2] = 0.0f;
        samplerDesc.BorderColor[3] = 0.0f;
        // allow use of all mip levels
        samplerDesc.MinLOD = 0;
        samplerDesc.MaxLOD = D3D11_FLOAT32_MAX;

        DX::ThrowIfFailed(
           m_deviceResources->GetD3DDevice()->CreateSamplerState(
           &samplerDesc,
           &m_sampler)
    );

        // After the vertex shader file is loaded, create the shader and input layout.
        auto createVSTask = loadVSTask.then([this](const std::vector<byte>& fileData)      {
    DX::ThrowIfFailed(
        m_deviceResources->GetD3DDevice()->CreateVertexShader(
        &fileData[0],
        fileData.size(),
        nullptr,
        &m_vertexShader
        )
        );

    static const D3D11_INPUT_ELEMENT_DESC vertexDesc[] =
    {
        { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
        { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 },
    };

    DX::ThrowIfFailed(
        m_deviceResources->GetD3DDevice()->CreateInputLayout(
        vertexDesc,
        ARRAYSIZE(vertexDesc),
        &fileData[0],
        fileData.size(),
        &m_inputLayout
        )
        );
});

// After the pixel shader file is loaded, create the shader and constant buffer.
        auto createPSTask = loadPSTask.then([this](const std::vector<byte>& fileData) {
            DX::ThrowIfFailed(
                m_deviceResources->GetD3DDevice()->CreatePixelShader(
                &fileData[0],
                fileData.size(),
                nullptr,
                &m_pixelShader
        )
        );

            CD3D11_BUFFER_DESC    constantBufferDesc(sizeof(ModelViewProjectionConstantBuffer), D3D11_BIND_CONSTANT_BUFFER);
            DX::ThrowIfFailed(
                m_deviceResources->GetD3DDevice()->CreateBuffer(
                &constantBufferDesc,
                nullptr,
                &m_constantBuffer
        )
        );
        });



        // Once both shaders are loaded, create the mesh.
        auto createCubeTask = (createPSTask && createVSTask).then([this]() {

            D3D11_SUBRESOURCE_DATA vertexBufferData = { 0 };
            vertexBufferData.pSysMem = this->model->getVertexPositionTexture();
            vertexBufferData.SysMemPitch = 0;
            vertexBufferData.SysMemSlicePitch = 0;
            CD3D11_BUFFER_DESC vertexBufferDesc(sizeof(this->model-  >getVertexPositionTexture()[0])*this->model->n_texture_vertex, D3D11_BIND_VERTEX_BUFFER);
            DX::ThrowIfFailed(
                m_deviceResources->GetD3DDevice()->CreateBuffer(
                &vertexBufferDesc,
                &vertexBufferData,
                &m_vertexBuffer
        )
        );


            m_indexCount = this->model->n_mesh;//ARRAYSIZE(cubeIndices);

            D3D11_SUBRESOURCE_DATA indexBufferData = { 0 };
            indexBufferData.pSysMem = this->model->getMeshTextureIndex();
            indexBufferData.SysMemPitch = 0;
            indexBufferData.SysMemSlicePitch = 0;
            CD3D11_BUFFER_DESC indexBufferDesc(sizeof(this->model->getMeshTextureIndex()[0])*m_indexCount, D3D11_BIND_INDEX_BUFFER);
            DX::ThrowIfFailed(
                m_deviceResources->GetD3DDevice()->CreateBuffer(
                &indexBufferDesc,
                &indexBufferData,
                &m_indexBuffer
        )
        );
        });

        // Once the cube is loaded, the object is ready to be rendered.
        createCubeTask.then([this]() {
            m_loadingComplete = true;
        });
    }

这是渲染功能:

    void TextureSceneRenderer::Render()
    {
        // Loading is asynchronous. Only draw geometry after it's loaded.
        if (!m_loadingComplete)
        {
           return;
        }

        auto context = m_deviceResources->GetD3DDeviceContext();

        // Set render targets to the screen.
        ID3D11RenderTargetView *const targets[1] = { m_deviceResources->GetBackBufferRenderTargetView() };
        context->OMSetRenderTargets(1, targets, m_deviceResources->GetDepthStencilView());

        // Prepare the constant buffer to send it to the graphics device.
        context->UpdateSubresource(
        m_constantBuffer.Get(),
        0,
        NULL,
        &m_constantBufferData,
        0,
        0
        );

        // Each vertex is one instance of the VertexPositionColor struct.
        UINT stride = sizeof(VertexPositionColor);
        UINT offset = 0;
        context->IASetVertexBuffers(
        0,
        1,
        m_vertexBuffer.GetAddressOf(),
        &stride,
        &offset
    );

        context->IASetIndexBuffer(
        m_indexBuffer.Get(),
        DXGI_FORMAT_R16_UINT, // Each index is one 16-bit unsigned integer (short).
        0
    );

        context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

        context->IASetInputLayout(m_inputLayout.Get());

        // Attach our vertex shader.
        context->VSSetShader(
        m_vertexShader.Get(),
        nullptr,
        0
    );

        // Send the constant buffer to the graphics device.
        context->VSSetConstantBuffers(
        0,
        1,
        m_constantBuffer.GetAddressOf()
    );

        // Attach our pixel shader.
        context->PSSetShader(
        m_pixelShader.Get(),
        nullptr,
        0
    );

        context->PSSetShaderResources(
            0,
            1,
            m_textureSRV.GetAddressOf()
    );

        context->PSSetSamplers(
            0,                          // starting at the first sampler slot
            1,                          // set one sampler binding
            m_sampler.GetAddressOf()
    );

        // Draw the objects.
        context->DrawIndexed(
            m_indexCount,
            0,
            0
    );
    }

0 个答案:

没有答案