Flickering geometry

Started by
17 comments, last by Mumsfilibaba 8 years, 6 months ago
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?
Advertisement

Maybe some depth test, depth write state is changing, mutualy between successive frames.

Do you have overlapping polygons?

I've seen this happen when two polygons have exactly the same coordinates so the rendering doesn't know which is in front of the other...

I only have a quad with four vertices, so I don't think that it's because of overlapping polygons.

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;
}


//release DepthStencil
depthBuffer->Release();

Have you tried not releasing this texture (I would think it's needed for your depth stencil view, even after CreateDepthStencilView() is called)?

.:vinterberg:.

The view holds a reference to the texture.

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:

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

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

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?

This topic is closed to new replies.

Advertisement