2017-02-09 144 views
0

問題: 如何通過返回帶有語義映射的結構通過HLSL呈現目標?HLSL呈現紋理的問題

你好。我是DirectX11的新手,並試圖設置渲染紋理,以便我可以實現延遲着色。我花了一天的時間在網絡上尋找解決問題的方法,但迄今爲止還沒有運氣。

目前,我可以使我的場景,通過HLSL單一的紋理和我的渲染紋理全屏四沒有問題的完成。但是,如果我綁定多個渲染目標,我所看到的所有目標都是我的目標的清晰顏色,像素着色器似乎從未看到任何綁定的紋理。我在運行時設置了D3D11_CREATE_DEVICE_DEBUG,沒有警告/錯誤,我嘗試過使用Visual Studio 2013圖形調試工具,但我很難理解問題所在。這可能是相關的源代碼:

shader代碼:(編譯vs_5_0,ps_5_0)

// vertex shader 
cbuffer mTransformationBuffer 
{ 
    matrix worldMatrix; 
    matrix viewMatrix; 
    matrix projectionMatrix; 
}; 

struct VertexInputType 
{ 
    float4 position : POSITION; 
    float4 color : COLOR; 
    float3 normal : NORMAL; 
}; 
struct PixelInputType 
{ 
    float4 position : SV_POSITION; 
    float4 color : COLOR; 
    float3 normal : NORMAL; 
}; 
// this does not seem to work! 
struct PixelOutputType 
{ 
    float4 position : SV_TARGET0; 
    float4 normal : SV_TARGET1; 
}; 


PixelInputType VertexEntry(VertexInputType input) 
{ 
    input.position.w = 1.0f; 

    PixelInputType output; 
    output.position = mul(input.position, worldMatrix); 
    output.normal = mul(input.normal, (float3x3)worldMatrix); 
    output.normal = normalize(output.normal); 

    output.color = input.color; 

    return output; 
} 

// fragment shader 
PixelOutputType FragmentEntry(PixelInputType input) 
{ 
    PixelOutputType output; 

    // render as white so I can see MRT working 
    output.position = float4(1.0f, 1.0f, 1.0f, 1.0f); 
    output.normal = float4(1.0f, 1.0f, 1.0f, 1.0f); 

    return output; 
} 

渲染創建目標:

void RenderTargetManager::createTarget(const std::string& name, unsigned int width, unsigned int height, DXGI_FORMAT format) 
{ 
unsigned int hash = hashString(name); 

RenderTarget target; 

// create the texture to render to 
target.mTexture = TextureUtils::createTexture2d(mDevice, width, height, format, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE); 

// create the render target view 
D3D11_RENDER_TARGET_VIEW_DESC rtViewDesc; 
memset(&rtViewDesc, 0, sizeof(rtViewDesc)); 

rtViewDesc.Format = format; 
rtViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; 

HRESULT ret = S_OK; 
ret = mDevice.CreateRenderTargetView(target.mTexture, &rtViewDesc, &target.mRenderTargetView); 
ASSERT(ret == S_OK, "Failed to create a render target view."); 

// create the shader resource view 
D3D11_SHADER_RESOURCE_VIEW_DESC srViewDesc; 
memset(&srViewDesc, 0, sizeof(srViewDesc)); 

srViewDesc.Format = format; 
srViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; 
srViewDesc.Texture2D.MipLevels = 1; 

ret = mDevice.CreateShaderResourceView(target.mTexture, &srViewDesc, &target.mShaderResourceView); 
ASSERT(ret == S_OK, "Failed to create a shader resource view."); 

mRenderTargetMap[hash] = target; 
} 

設置渲染目標:

void RenderTargetManager::setTargets(ID3D11DepthStencilView* depthStencilView, unsigned int numTargets, ...) 
{ 
    va_list args; 
    va_start(args, numTargets); 

    std::vector<ID3D11RenderTargetView*> renderTargetViews; 

    for (unsigned int i = 0; i < numTargets; ++i) 
    { 
     std::string renderTargetName = va_arg(args, char*); 
     unsigned int hash = hashString(renderTargetName); 

     auto it = mRenderTargetMap.find(hash); 
     if (it != mRenderTargetMap.end()) 
     { 
      renderTargetViews.push_back(it->second.mRenderTargetView); 
     } 
     else 
     { 
      LOGW("Render target view '%s' not found.", renderTargetName.c_str()); 
     } 
    } 

    va_end(args); 

    if (!renderTargetViews.empty()) 
    { 
     ASSERT(renderTargetViews.size() == numTargets, "Failed to set render targets. Not all targets found."); 
     mDeviceContext.OMSetRenderTargets(renderTargetViews.size(), &renderTargetViews[0], depthStencilView); 
    } 
} 

如果它返回一個float4,我的像素着色器將寫入這些目標中的任何一個,返回一個結構似乎永遠不會工作,並導致渲染目標只有清晰的顏色。我也試過這個作爲返回結構沒有成功:

struct PixelOutputType 
{ 
    float4 position : SV_TARGET 
}; 

謝謝您花時間閱讀此。我非常感謝幫助。

-T

編輯: 我一直在使用ID3D11RenderTargetView *的靜態數組,同樣的問題也試過。編輯2:我也啓用了DirectX控制面板輸出,並沒有看到任何不尋常的東西。

回答

0

經過很多測試和挫折,我終於發現了我的問題; __;

有我的紋理,視圖或狀態沒有問題,但與着色器和SV_POSITION的問題。

我被錯誤地試圖用我的像素着色器輸入「FLOAT4位置:SV_TARGET」作爲我的輸出位置,並在世界頂點着色器座標只改造。經過一段時間的思考之後,我意識到這必須是完全轉換的點,作爲像素着色器的輸入並且足夠肯定,完全轉換它可以解決問題。

這:

output.position = mul(input.position, worldMatrix); 
output.position = mul(output.position, viewMatrix); 
output.position = mul(output.position, projectionMatrix); 

,而不是這樣的:

output.position = mul(input.position, worldMatrix); 
//output.position = mul(output.position, viewMatrix); 
//output.position = mul(output.position, projectionMatrix);