Multipass artifacts

Started by
8 comments, last by sepul 18 years, 6 months ago
I'm using multipass to render an effect on a mesh. pass #1 - mesh is normally rendered pass #2 - same mesh is rendered using different shader (effect), with these states :

	_device->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
	_device->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );

	_device->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
	_device->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
but when you get close to the objects there are some annoying artifacts due to z-fighting. the depth of z-buffer is 16bit and when I increase the depth I get more artifacts. what should I do to fix this multipass problem ?

dark-hammer engine - http://www.hmrengine.com

Advertisement
Set the zfunction to D3DCMP_EQUAL. This will have the added advantage of speeding up the render time as unseen items will not be rendered - you'll essentially have done a depthfill pass.
You need to be sure to send the exact same geometry in the exact same order to avoid all z fighting artifacts.

Also, if pass one is triangle strips, then pass two must also be triangle strips, no mixing lists & strips.

I have not experienced any issues making pass 1 an indexed triangle list and pass 2 a non-indexed triangle list.
Quote:Original post by Source
Set the zfunction to D3DCMP_EQUAL. This will have the added advantage of speeding up the render time as unseen items will not be rendered - you'll essentially have done a depthfill pass.


I would better go with D3DCMP_LESSEQUAL or D3DCMP_GREATEREQUAL, because assuming that 2 values in such unprecise z-buffer will equal is a bit odd :)

You can also disable Z-writes for the second (and third etc) pass.
I've found the solution, by disabling z-writes and setting the z-function to ALWAYS :
	_device->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );	_device->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );	_device->SetRenderState( D3DRS_ZFUNC, D3DCMP_ALWAYS );


thanks

dark-hammer engine - http://www.hmrengine.com

First off, two triangles rendered with the same transformations will be exactly the same in depth - so using an equal depth function will work perfectly - otherwise techniques such as depth fill passes would not work.

Also using D3DCMP_ALWAYS is essentially turning off depth-buffering, and you will probably get some weird visual artefacts as your object turns, unless you're rendering totally concave and back-face culled objects such as spheres.
that was a good point "source", but I have tested with z-function = EQUAL, and I got the same artifacts, and meshes are exactly the same.
but luckily I have found the problem to the z fighting problem, the point is when I render the mesh in the first pass, vertex shader has WorldViewProjMatrix as input paramter and transform the vertex. and in the second pass, there is another vertex shader that has world, view and projection matrix seperated and multiplies them itself, and then transform the vertex.
here will rise a precision point problem, cuz I think the matrices that I multiply on the CPU are a little different than when multiplied on GPU.

dark-hammer engine - http://www.hmrengine.com

Quite possibly - you could try adding a small depth bias to your second pass to help it along a little by using D3DDevice->SetRenderState() with the D3DRS_DEPTHBIAS state (or this can be done inside an effect file) - or concatenate the transforms in both instances the same way (if you're currently using FFP for the first mesh you could use a dummy vertex shader which creates the transform - this will be slower but not by a great amount).
thanks for the quick answers source, I have edited the last post, cuz it is solved

dark-hammer engine - http://www.hmrengine.com

This topic is closed to new replies.

Advertisement