2017-02-09 6 views
0

질문 : 의미 론적 매핑을 사용하여 구조체를 반환하여 HLSL을 통해 대상에 렌더링하는 방법은 무엇입니까?텍스처에 대한 HLSL 렌더링의 문제점

안녕하세요. 저는 DirectX11을 처음 사용하고 있습니다. 렌더링을 텍스처로 설정하려고 시도하고 있습니다. 그래서 지연 음영을 구현할 수 있습니다. 나는 하루 만에 문제를 해결하기 위해 인터넷을 샅샅이 뒤졌지만 지금까지는 운이 없었습니다.

현재 HLSL을 통해 내 장면을 단일 텍스처로 렌더링 할 수 있으며 문제없이 전체 텍스처 쿼드로 텍스처를 렌더링하여 마무리 할 수 ​​있습니다. 그러나 여러 렌더 타겟을 묶는다면, 필자가 보게되는 모든 것이 타겟을위한 명확한 컬러이며, 픽셀 쉐이더는 결코 바운드 텍스처를 얻지 못합니다. D3D11_CREATE_DEVICE_DEBUG을 런타임에 경고/오류없이 설정하고 Visual Studio 2013 그래픽 디버깅 도구를 사용해 보았지만 문제가 무엇인지 이해하는 데 어려움이 있습니다.

쉐이더 코드 : (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 *의 정적 배열을 사용하여 시도했다 . EDIT2 : DirectX Control Panel 출력도 사용할 수 있었으며 평범한 것을 보지 못했습니다.

답변

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); 
관련 문제