2012-01-23 3 views
0

Я визуализирую сцену текстуры, а затем используя эту текстуру и ее глубинуBuffer в последующих визуализациях, чтобы применить некоторые эффекты (Depth Of Field, Bloom и т. Д.).Извлечение глубиныBuffer рендера для другого рендеринга. (D3DX9)

В этом заключается проблема: мне удалось установить DepthStencilBuffer на пользовательскую поверхность и визуализировать мою сцену текстурой. Сцена выполнена отлично, и проблем с глубиной нет. При этом, используя текстуру (к которой привязана пользовательская поверхность), все значения глубины равны 1.0

Я подозреваю, что вызов device-> clear влияет на неправильную поверхность, но даже при их отключении, он ничего не фиксирует.

Вот фактический код:

HRESULT hr = S_FALSE; 

VCND3D* renderer = static_cast<VCND3D*>(VCNRenderCore::GetInstance()); 
LPDIRECT3DDEVICE9 device = renderer->GetD3DDevice(); 

//device->EndScene(); 

VCNDXShaderCore* shaderCore = static_cast<VCNDXShaderCore*>(VCNDXShaderCore::GetInstance()); 

VCNNode* rootNode = VCNNodeCore::GetInstance()->GetRootNode(); 

LPDIRECT3DSURFACE9 currentSurface; 
device->GetRenderTarget(0, &currentSurface); 

LPDIRECT3DSURFACE9 currentDepthBuffer; 
device->GetDepthStencilSurface(&currentDepthBuffer); 

///// INITIAL HDR RENDER : ////////////////////////////////////// 

hr = device->SetRenderTarget(0, mInitialHDRSurface); 
VCN_ASSERT(SUCCEEDED(hr)); 

hr = device->SetDepthStencilSurface(mDepthSurface); 
VCN_ASSERT(SUCCEEDED(hr)); 

device->Clear( 0, 
       NULL, 
       D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 
       D3DCOLOR_XRGB(100,100,100), 
       1.0f, 
       0); 

//device->BeginScene(); 
rootNode->Render(); 
//device->EndScene(); 

//hr = device->UpdateSurface(currentDepthBuffer, NULL, mDepthSurface, NULL); 
//VCN_ASSERT(SUCCEEDED(hr)); 

//////////// DOF EFFECT : ///////////////////////////////////////////////// 

hr = device->SetRenderTarget(0, currentSurface); 
VCN_ASSERT(SUCCEEDED(hr)); 

device->SetRenderState(D3DRS_COLORWRITEENABLE, 
D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE); 

device->Clear( 0, 
       NULL, 
       D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 
       D3DCOLOR_XRGB(100,100,100), 
       1.0f, 
       0); 

//device->BeginScene(); 

// Set DOF shader 
VCNDXShader* dofShader = shaderCore->GetShader(sidDof); 

// Field of view to cover full screen : 
hr = device->SetFVF(D3DFVF_SCREEN); 
VCN_ASSERT(SUCCEEDED(hr)); 

// select the vertex buffer to display 
hr = device->SetStreamSource(0, mScreenVertexBuffer, 0, sizeof(SCREENVERTEX)); 
VCN_ASSERT(SUCCEEDED(hr)); 

// Draw the Dof result 
hr = dofShader->GetEffect()->SetTechnique("BaseTechnique"); 
VCN_ASSERT(SUCCEEDED(hr)); 
hr = dofShader->GetEffect()->SetTexture("gInputImageTexture", mInitialHDRTexture); 
VCN_ASSERT(SUCCEEDED(hr)); 
hr = dofShader->GetEffect()->SetTexture("gDepthTexture", mDepthTexture); 
VCN_ASSERT(SUCCEEDED(hr)); 
hr = dofShader->GetEffect()->SetFloat("gMinDepth", 3.0f); 
VCN_ASSERT(SUCCEEDED(hr)); 
hr = dofShader->GetEffect()->SetFloat("gMaxDepth", 7.0f); 
VCN_ASSERT(SUCCEEDED(hr)); 

dofShader->RenderPrimitive(2, D3DPT_TRIANGLESTRIP); 

hr = device->SetDepthStencilSurface(currentDepthBuffer); 
VCN_ASSERT(SUCCEEDED(hr)); 

А вот инициализации текстуры и поверхностей, так как ошибка может быть там:

// Texture for the initial HDR Render (Before effects) 
hr = device->CreateTexture(res.x, res.y, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A32B32G32R32F, D3DPOOL_DEFAULT, &mInitialHDRTexture, 0); 
VCN_ASSERT_MSG(SUCCEEDED(hr), _T("Unable to create initial HDR Render Texture")); 

// Extract the associated surface for rendering 
hr = mInitialHDRTexture->GetSurfaceLevel(0, &mInitialHDRSurface); 
VCN_ASSERT(SUCCEEDED(hr)); 

// Texture with depth of the scene 
hr = device->CreateTexture(res.x, res.y, 1, D3DUSAGE_DEPTHSTENCIL, D3DFMT_D32F_LOCKABLE, D3DPOOL_DEFAULT, &mDepthTexture, 0); 
VCN_ASSERT_MSG(SUCCEEDED(hr), _T("Unable to create depth texture")); 

// Extract the associated surface for rendering 
hr = mDepthTexture->GetSurfaceLevel(0, &mDepthSurface); 
VCN_ASSERT(SUCCEEDED(hr)); 

Обратите внимание, что ни один ASSERT не становится запускается (что именно меня раздражает, я бы хотел, чтобы некоторые ошибки указывали, где искать)

Nic

ответ

1

Если я правильно прочитал ваш код, вы очистите mDepthSurface дважды: сначала в разделе INITIAL HDR RENDER, затем в DOF EFFECT. Вам нужно либо сделать SetDepthStencilSurface перед вторым, либо не установить D3DCLEAR_ZBUFFER в этом вызове. В противном случае вторая четкая сбрасывает все, что отображается rootNode->Render(), и при запуске у вас есть весь чистый z-буфер.

+0

Да, но я обнаружил, что до dx10, чтение буфера глубины официально не поддерживается, поскольку формат памяти depthStencilBuffer свободен от реализации для производителя графических карт. Похоже, что лучше просто сделать рендер с шейдером, который печатает глубину в текстуре R32F. – NGauthier