2014-01-18 2 views
2

DirectX를 사용하여 MS3D 모델을 표시하는 프로그램을 작성 중이지만 불행히도 화면에 아무것도 표시되지 않습니다. 난 비주얼 스튜디오 13에서 그래픽 디버거를 사용하면 픽셀 쉐이더 파이프 라인에서 누락되는이 아래 그림에 도시 된 바와 같이 , 나는 알파이프 라인의 DirectX11 픽셀 쉐이더가 누락되었습니다.

image

이 내 픽셀 쉐이더 소스 코드 :

cbuffer SkinningTransforms 
{ 
    matrix WorldMatrix; 
    matrix ViewProjMatrix; 
}; 
//-------------------------------------------------------------------------------- 
// Inter-stage structures 
//-------------------------------------------------------------------------------- 
struct VS_INPUT 
{ 
    float3 position  : POSITION; 
    int4 bone   : BONEID; 
    float4 weights   : BONEWEIGHT; 
    float3 normal   : NORMAL; 
    float3 tangent   : TANGENT; 
    float2 tex    : TEXCOORD; 
}; 
//-------------------------------------------------------------------------------- 
struct VS_OUTPUT 
{ 
    float4 position   : SV_Position; 
    float3 normal   : NORMAL; 
    float3 light   : LIGHT; 
    float2 tex    : TEXCOORDS; 
}; 

Texture2D  ColorTexture : register(t0);   
SamplerState LinearSampler : register(s0); 

//-------------------------------------------------------------------------------- 
VS_OUTPUT VSMAIN(in VS_INPUT input) 
{ 
    VS_OUTPUT output; 
    //Transform vertex and pass them to the pixel shader 
    return output; 
} 

//-------------------------------------------------------------------------------- 
float4 PSMAIN(in VS_OUTPUT input) : SV_Target 
{ 
    // Calculate the lighting 
    float3 n = normalize(input.normal); 
    float3 l = normalize(input.light); 


    float4 texColor = ColorTexture.Sample(LinearSampler, input.tex); 

    float4 color = texColor * (max(dot(n,l),0) + 0.05f); 
    return(color); 
} 

Graphics Debugger에서 알 수 있듯이 모든 그래픽 이벤트가 올바르다. 나는 픽셀 쉐이더에 관한 될 수 중요한 이벤트, 아래에 나와 :

106:(obj:4) ID3D11Device::CreateDepthStencilView(obj:24,NULL,obj:25)* 
108:(obj:5) ID3D11DeviceContext::OMSetRenderTargets(8,{obj:1,NULL,NULL,NULL,NULL,NULL,NULL,NULL},obj:25)* 
109:(obj:5) ID3D11DeviceContext::ClearRenderTargetView(obj:1,addr:21)* 
111:(obj:5) ID3D11DeviceContext::ClearDepthStencilView(obj:25,1,1.000f,0)* 
119:(obj:4) ID3D11Device::CreateSamplerState(addr:24,obj:27)* 
134:(obj:4) ID3D11Device::CreatePixelShader(addr:27,21056,NULL,obj:30)* 
135:CreateObject(D3D11 Pixel Shader,obj:30) 
136:(obj:5) ID3D11DeviceContext::PSSetShader(obj:30,NULL,0)* 
137:(obj:5) ID3D11DeviceContext::PSSetSamplers(0,1,{obj:27})* 
139:(obj:4) ID3D11Device::CreateTexture2D(addr:28,addr:5,obj:31)* 
140:CreateObject(D3D11 Texture2D,obj:31) 
142:(obj:4) ID3D11Device::CreateShaderResourceView(obj:31,NULL,obj:32)* 
143:CreateObject(D3D11 Shader Resource View,obj:32) 
144:(obj:5) ID3D11DeviceContext::PSSetShaderResources(0,1,{obj:32})* 
146:(obj:4) ID3D11Device::CreateRasterizerState(addr:29,obj:33)* 
147:CreateObject(D3D11 Rasterizer State,obj:33) 
152:(obj:5) ID3D11DeviceContext::RSSetState(obj:33)* 
154:(obj:5) ID3D11DeviceContext::RSSetViewports(1,addr:30)* 
156:(obj:4) ID3D11Device::CreateBlendState(addr:11,obj:34)* 
157:CreateObject(D3D11 Blend State,obj:34) 
159:(obj:5) ID3D11DeviceContext::OMSetBlendState(obj:34,addr:31,-1)* 
162:(obj:4) ID3D11Device::CreateDepthStencilState(addr:32,obj:35)* 
163:CreateObject(D3D11 Depth-Stencil State,obj:35) 
165:(obj:5) ID3D11DeviceContext::OMSetDepthStencilState(obj:35,0)* 

내가 위의 목록에서 함수의 모든 디버깅, 그리고 그들 모두 OK 돌아갑니다. 아무 잘못 없음. 제 질문은 픽스 털 셰이더가 pipleline에서 누락 된 이유이며, 다시 빈 화면이 될 수 있습니다.

+0

결국 문제를 파악 했습니까? 나는 같은 문제가있다. (PS는 파이프 라인 단계에서는 빠졌지 만 즉각적인 컨텍스트의 객체보기에서 활성화되어 있으므로 http://msdn.microsoft.com/en-us/library/jj191650에서 설명하는 문제는 아니다. .aspx). 물론, 이미지는 검은 색입니다 ... – Christoph

+0

똑같은 문제, VS에서 RS 상태 및 출력을 확인했습니다. RSSetViewports가 호출되었지만 그리기 호출의 뷰포트가 '설정되지 않음'이지만 이벤트를 확인했습니다. 나는 아직도 이것을 조사하고있다. –

+0

좋아, 내가 낙관적으로 1.0f가되어야 할 때 뷰포트에 최대 깊이 100.0f를 주었기 때문에 나에게 일어났다. 래스터 라이저에서 깊이 클리핑을 비활성화 했는데도 RSSetViewport가 뷰포트를 설정하지 못하게하고 오류가 발생하지 않습니다. 장치 컨텍스트의 뷰포트가 실제로 설정되어 있는지 그래픽 디버거에서 확인하십시오. –

답변

1

내 의견에 썼듯이 비슷한 문제가 있습니다.

필자의 경우 픽셀 쉐이더가 정확하게 바운드되었습니다 (http://msdn.microsoft.com/en-us/library/jj191650.aspx 참조). 게다가, 나는 변환의 결과가 가시적이어야하고 따라서 가시적 인 조각을 생성해야한다는 점을 버텍스 쉐이더를 디버깅함으로써 보장했다.

이 경우 (설명하는 것과 같음) 래스터 라이저 상태가 올바른지 확인하십시오. 즉치 컨텍스트의 그래픽 객체보기를 사용하여 실제로 설정되었는지와 지오메트리를 통과시킬 수 있는지 확인할 수 있습니다. 디버깅 목적으로, 나는 뒤쪽 컬링 (backface culling)을 무력화시키는 것이 도움이된다는 것을 발견했다. 나는 다른 답변에 추가

D3D11_RASTERIZER_DESC rasterDesc; 
ZeroMemory(&rasterDesc, sizeof(rasterDesc)); 
rasterDesc.CullMode = D3D11_CULL_MODE::D3D11_CULL_NONE; 
rasterDesc.FillMode = D3D11_FILL_MODE::D3D11_FILL_SOLID; 
2

사용, 일정한 버퍼 조직은이 문제의 원인이 될 수 있습니다. 제 경우에는 픽셀 쉐이더가 파이프 라인에서 사라졌지 만 버텍스 쉐이더가 버텍스를 올바르게 변형시키지 못했습니다. 검사 결과 상수 버퍼 상단의 불리언 값으로 인해 데이터 정렬이 잘못되어 세계 행렬에 잘못된 값이있는 것으로 나타났습니다. HLSL은 벡터이라는 4 개의 구성 요소가있는 16 바이트 경계에 데이터를 압축합니다. 부울은 부동 소수점과 동일한 4 바이트입니다.

그래서 위의 상수 버퍼에, 부울 + 세계 행렬의 첫 번째 행의 처음 3 개 구성 요소는 첫째 벡터에 매핑됩니다
cbuffer cbPerObject : register(b1) 
{ 
    bool gUseTexture ; 

    row_major float4x4 gWorld ; 
    row_major float4x4 gWorldInvTranspose ; 
    row_major float4x4 gWorldViewProj ; 
    row_major float4x4 gTexTransform ; 
    Material gMaterial ; 
} ; 

이 모든 것을이 세 구성 요소에 의해 이동 얻을됩니다, 월드 행렬 (및 다른 행렬 및 가능하면 다른 데이터)의 정렬이 잘못되었습니다.

두 가지 가능한 솔루션 :

  1. 이동 구조의 끝에 부울. 나는 이것을했고 효과가 있었다.
  2. 세계 행렬과 부울 사이의 변수 패딩을 추가하십시오. C++ 구조체에 XMFLOAT3을 추가하고 HLSL에 float3을 추가하여이 작업을 시도했습니다. 이것 역시 효과가있었습니다.

짧은 이야기이므로 HLSL 포장에주의하십시오.

EDIT :이 방법은 부울을 제외한 모든 변수가 올바른 값을 가지고 있기 때문에이 방법이 효과가 있다고 생각했습니다. 나는 그 시간에 bool을 사용하지 않았으므로 나는 그것도 괜찮다고 생각했다. 그렇지 않은 것으로 밝혀졌습니다.

HLSL bools 및 C++ bools는 크기가 다릅니다. HLSL bool은 4 바이트이며, C++ bool은 구현 정의되어 있습니다 (예 : 내 컴퓨터의 1 바이트). 어쨌든, 그들은 서로 다를 가능성이 높으며 문제를 일으킬 수 있습니다.

Windows BOOL 유형 또는 int 또는 uint와 같은 다른 적절한 크기의 값을 사용하십시오.

https://gamedev.stackexchange.com/a/22605을 살펴보십시오.

또한 마지막 두 번째 게시물 here은 상황을 명확하게 설명합니다 (이 링크는 위의 gamedev 링크의 답변에서도 참조됩니다).

포장은 여전히 ​​문제이므로주의하시기 바랍니다. BOOL이나 uint 등을 사용하는 경우에도 이전 구조와 같이 처음에 배치하면 상수 버퍼에 잘못된 값이 생깁니다. 따라서 상수 버퍼로 작업 할 때 이러한 두 가지 문제 (데이터 정렬 및 부울 문제)를 고려하십시오.

관련 문제