Sign in to follow this  
Mumsfilibaba

Flickering geometry

Recommended Posts

Hello, I've started to build my own engine based on the d3d11-api, but I have encountered quite a big problem. My geometry is flickering and I have no more ideas on how to solve it. I think I have located the problem to be a depthbuffer or a matrix issue. I didn't have any issues before I implemented the camera, but since the geometry seems to be rotated correctly in the vertexshader-stage when I use the visual studio 2015 graphics debugger, it makes me think that it's a depthbuffer problem. The geometry seems to only be rendered every second frame.

Can't post any code at the moment, because I'm writing on my phone, but do any of you have any ideas?

Share this post


Link to post
Share on other sites

Ok, so I thought that I should post some of my code. Here's all my code surrounding the matrices:

void Camera::render(Vector3 objectWorldPosition, Vector3 objectRotation, Vector3 objectScale)
{
	//create and set matrices
	DirectX::XMMATRIX objectRotationMatrix = DirectX::XMMatrixRotationRollPitchYawFromVector(objectRotation);
	DirectX::XMMATRIX objectScalingMatrix = DirectX::XMMatrixScalingFromVector(objectScale);
	DirectX::XMMATRIX objectWorldPositionMatrix = DirectX::XMMatrixTranslationFromVector(objectWorldPosition);
	DirectX::XMMATRIX cameraRotationMatrix = DirectX::XMMatrixRotationRollPitchYawFromVector(this->rotation);

	//calculate new lookAt an up- vectors with camera rotation
	this->lookAt = DirectX::XMVector3TransformCoord(this->lookAt, cameraRotationMatrix);
	this->up = DirectX::XMVector3TransformCoord(this->up, cameraRotationMatrix);

	//create matrices
	DirectX::XMStoreFloat4x4(&this->viewMatrix, DirectX::XMMatrixLookToLH(this->position, this->lookAt, this->up));
	DirectX::XMStoreFloat4x4(&this->worldMatrix, objectRotationMatrix * objectScalingMatrix * objectWorldPositionMatrix);

	//transpose the matrices before sending them to the vertex shader
	DirectX::XMStoreFloat4x4(&this->viewMatrix, DirectX::XMMatrixTranspose(DirectX::XMLoadFloat4x4(&this->viewMatrix)));
	DirectX::XMStoreFloat4x4(&this->projectionMatrix, DirectX::XMMatrixTranspose(DirectX::XMLoadFloat4x4(&this->projectionMatrix)));
	DirectX::XMStoreFloat4x4(&this->worldMatrix, DirectX::XMMatrixTranspose(DirectX::XMLoadFloat4x4(&this->worldMatrix)));
}

And here's when I render the quad:

bool GraphicsManager::render(Mesh* mesh, Color color)
{	
	UINT stride = sizeof(VERTEX);
	UINT offset = 0;	

	//set all resources to the "Input Assembly"-stage
	this->d3dHandle->getImmediateContext()->IASetInputLayout(this->defaultInputLayout);
	this->d3dHandle->getImmediateContext()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
	this->d3dHandle->getImmediateContext()->IASetVertexBuffers(0, 1, mesh->getVertexBufferPtr(), &stride, &offset);
	this->d3dHandle->getImmediateContext()->IASetIndexBuffer(mesh->getIndexBuffer(), DXGI_FORMAT_R32_UINT, 0);

	//set shaders
	this->d3dHandle->getImmediateContext()->VSSetShader(this->vertexShader->getShader(), nullptr, 0);
	this->d3dHandle->getImmediateContext()->PSSetShader(this->pixelShader->getShader(), nullptr, 0);

	//set resources to "Rasterizer"-stage
	this->d3dHandle->getImmediateContext()->RSSetState(this->defaultRasterizerState);

	//set vertex shader data
	this->d3dHandle->getImmediateContext()->VSSetConstantBuffers(0, 1, &this->vertexShaderDataBuffer);

	//create this frame's matrices
	this->defaultCamera->render(Vector3(1.25f, 0.5f, 1.0f), Vector3(0.0f, (DirectX::XM_PI / 6), 0.0f), Vector3(1.0f));

	//set the vertex shader data
	this->vertexShaderData.color = color;
	this->vertexShaderData.worldMatrix = this->defaultCamera->getWorldMatrix();
	this->vertexShaderData.projectionMatrix = this->defaultCamera->getProjectionMatrix();
	this->vertexShaderData.viewMatrix = this->defaultCamera->getViewMatrix();

	//update the data in the vertex shader data buffer
	this->d3dHandle->getImmediateContext()->UpdateSubresource(this->vertexShaderDataBuffer, 0, 0, &this->vertexShaderData, 0, 0);

	//draw mesh
	this->d3dHandle->getImmediateContext()->DrawIndexed(mesh->getIndexCount(), 0, 0);

	return true;
}

In the future the position, scale and rotation sent as arguments to the camera's render-function is ment to be parameters to the graphicsmanager's render-function, I just wanted to make sure everything worked before doing so. Anyway here's all my depthbuffer related code:

D3DHandle::D3DHandle()
{
        ...
	
	//setup default DepthBuffer
	RtlSecureZeroMemory(&this->depthBufferDescription, sizeof(D3D11_TEXTURE2D_DESC));

	this->depthBufferDescription.ArraySize = 1;
	this->depthBufferDescription.BindFlags = D3D11_BIND_DEPTH_STENCIL;
	this->depthBufferDescription.CPUAccessFlags = 0;
	this->depthBufferDescription.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
	this->depthBufferDescription.MipLevels = 1;
	this->depthBufferDescription.MiscFlags = 0;
	this->depthBufferDescription.Usage = D3D11_USAGE_DEFAULT;

        ...
}
bool D3DHandle::createDepthBuffer()
{
	ID3D11Texture2D* depthBuffer = nullptr;

	//setup rest of DepthBufferDescription
	this->depthBufferDescription.Height = this->swapChainDescription.BufferDesc.Height;
	this->depthBufferDescription.Width = this->swapChainDescription.BufferDesc.Width;
	this->depthBufferDescription.SampleDesc = this->swapChainDescription.SampleDesc;

	//create Depthbuffer
	HRESULT result = this->device->CreateTexture2D(&this->depthBufferDescription, nullptr, &depthBuffer);

	if (FAILED(result))
	{
		MessageBoxW(0, L"Could not create DepthBuffer", L"ERROR", MB_OK | MB_ICONERROR);
		return false;
	}

	//create DepthStencil
	result = this->device->CreateDepthStencilView(depthBuffer, &this->depthStencilDescription, &this->depthStencil);

	if (FAILED(result))
	{
		MessageBoxW(0, L"Could not create DepthStencilView", L"ERROR", MB_OK | MB_ICONERROR);
		return false;
	}

	//release DepthStencil
	depthBuffer->Release();
	depthBuffer = nullptr;

	return true;
}
void D3DHandle::setBuffers()
{
	//set RenderTarget and DepthStencil
	this->immediateContext->OMSetRenderTargets(1, &this->renderTarget, this->depthStencil);
}
void GraphicsManager::clear(Color color, float depth)
{
	//clear backbuffer rendertarget
	this->d3dHandle->getImmediateContext()->ClearRenderTargetView(this->d3dHandle->getRenderTarget(), color);

	//clear depthbuffer and depthstencil
	this->d3dHandle->getImmediateContext()->ClearDepthStencilView(this->d3dHandle->getDepthStencil(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, depth, 0);
}

Made the text bigger so it would be easier to distinguish from the code. Hope that someone can help me

 

EDIT: Forgot to show post the vertexshader:

cbuffer ConstantBuffer
{
	float4x4 worldMatrix;
	float4x4 viewMatrix;
	float4x4 projectionMatrix;
	float4 inputColor : COLOR;
}

struct VERTEX
{
	float4 position : SV_POSITION;
	float4 color : COLOR;
};

VERTEX VShader (float4 position : POSITION, float4 color : COLOR)
{
	VERTEX output;

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

	return output;
}
Edited by Mumsfilibaba

Share this post


Link to post
Share on other sites

Well that's sounds very logical, don't know why I didn't think of that. Changed the code a bit and made that texture2d a member of the D3DHandle and release it when the program shuts down. Sadly it didn't help. The flickering is still as bad as before.

 

EDIT: Here's a clip showing the flickering: https://youtu.be/4Xk7yVNNW0c

Should be watched with 60fps, otherwise it doesn't look like it looks for me

Edited by Mumsfilibaba

Share this post


Link to post
Share on other sites

Have you tried using  D3D11_CREATE_DEVICE_DEBUG to see if it reports any errors?

 Yepp, but no errors. Right now I wish there would be an error that tells me what've done wrong. 

 

Have played around with my depthstencilstate (default settings), and I choosed D3D11_COMPARISON_ALWAYS, and I set DepthEnable = false. And nothing changed witch made wonder if it really is a problem with the depth, becuase if the depth test always passes, could there really be depth errors?

Edited by Mumsfilibaba

Share this post


Link to post
Share on other sites

Here's the SwapChainDescription:

//setup default SwapChainDescription
RtlSecureZeroMemory(&this->swapChainDescription, sizeof(DXGI_SWAP_CHAIN_DESC));

this->swapChainDescription.BufferCount = 1;
this->swapChainDescription.BufferDesc.Width = 0;
this->swapChainDescription.BufferDesc.Height = 0;
this->swapChainDescription.BufferDesc.RefreshRate.Numerator = 0;
this->swapChainDescription.BufferDesc.RefreshRate.Denominator = 1;
this->swapChainDescription.BufferDesc.Scaling = DXGI_MODE_SCALING::DXGI_MODE_SCALING_UNSPECIFIED;
this->swapChainDescription.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER::DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
this->swapChainDescription.BufferDesc.Format = DXGI_FORMAT::DXGI_FORMAT_R8G8B8A8_UNORM;
this->swapChainDescription.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
this->swapChainDescription.Flags = 0;
this->swapChainDescription.SampleDesc.Count = 1;
this->swapChainDescription.SampleDesc.Quality = 0;
this->swapChainDescription.SwapEffect = DXGI_SWAP_EFFECT::DXGI_SWAP_EFFECT_DISCARD;
this->swapChainDescription.Windowed = true;
this->swapChainDescription.OutputWindow = this->outputWindow;

And here's the present call:

bool GraphicsManager::present()
{
	HRESULT result = 0;

	//present swapchain
	if (this->verticalSync)
	{
		result = this->d3dHandle->getSwapChain()->Present(1, 0);
	}
	else
	{
		result = this->d3dHandle->getSwapChain()->Present(0, 0);
	}

	if (FAILED(result))
	{
		MessageBoxW(0, L"SwapChain presentation failed", L"ERROR", MB_OK | MB_ICONERROR);
		return false;
	}

	return true;
}

Share this post


Link to post
Share on other sites

this->swapChainDescription.BufferDesc.RefreshRate.Numerator = 0;
this->swapChainDescription.BufferDesc.RefreshRate.Denominator = 1;

 

Shouldn't Numerator be 60 and Denominator 0 (for 60 Hz example)?

 

It also seems like you need to set BufferCount to 2 or more:

 

 

DXGI_SWAP_EFFECT_DISCARD

Use this flag to specify the bit-block transfer (bitblt) model and to specify that DXGI discard the contents of the back buffer after you call IDXGISwapChain1::Present1. This flag is valid for a swap chain with more than one back buffer, although, applications only have read and write access to buffer 0. Use this flag to enable the display driver to select the most efficient presentation technique for the swap chain.

Edited by vinterberg

Share this post


Link to post
Share on other sites

Denominator must be at least 1, otherwise there will be a division with zero. Have tested to put 60 as numerator and 1 as denominator, but no change.

 

Well the buffercount thing is weird. I checked a couple of examples and they have buffercount = 1 and uses that flag. However I don't use a IDXGISwapChain1, I use a IDXGISwapChain. I don't now if that has something to do with it.

Share this post


Link to post
Share on other sites

Hmm, I also found this, which may be related to your problem: http://gamedev.stackexchange.com/questions/15651/mapping-a-vertex-buffer-in-directx11

 

On an unrelated note: I'd premultiply the WorldViewProjection matrix outside of the shader, since it's the same for all vertices in a mesh

Share this post


Link to post
Share on other sites

Have read that post a coupe of times, but can't find anything that could help me. His problem seems to be becuase he has uninitialized data in his buffer. If I have understood everything correctly I doesn't have any uninitialized data. But I can be wrong. 

 

I really have no idea whats wrong

Share this post


Link to post
Share on other sites

Ok, so after some "professional" detective work (maybe not professional) I think I've located the problem to the UpdateSubresource call, or maybe the constant buffer itself. My quess is that the matrices doesn't have a value some frames and then the geometry "dissapears" out of frame and I get the flickering. 

 

Hmm, I also found this, which may be related to your problem: http://gamedev.stackexchange.com/questions/15651/mapping-a-vertex-buffer-in-directx11

 

On an unrelated note: I'd premultiply the WorldViewProjection matrix outside of the shader, since it's the same for all vertices in a mesh

 

So you problably were right...

 

EDIT: 

Problem solved :D

 

The problem were that I transposed the projection matrix every frame, when the projection matrix itself weren't updated. So because of the way the transpose changes the matrix, the projectionmatrix were correct one frame, but the next frame it weren't, then it became correct again, and so on and so on.

 

Stupid me :D

 

But thanks so much to all of you gave some of your time to help me. 

Edited by Mumsfilibaba

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this