arjan de lumens
Veteran
Does alpha-to-coverage work correctly when there are multiple layers of alpha-blended/tested polygons drawn on top of each other?
Not quite, but that situation doesn't happen very often in those cases where alpha test is used currently. However, alpha to coverage has the same problem as alpha blending with magnification. If you get close to the edges, they will blur (and with a2c, you'll have banding, as you only have a small number of different coverage levels).arjan de lumens said:Does alpha-to-coverage work correctly when there are multiple layers of alpha-blended/tested polygons drawn on top of each other?
By keeping the test and the write in the same place we can enforce read-write coherency with relatively simple control and some tweaks to the required Z cache logic.
The problem is far worse than you think. If you think it's trivial, write a program that does everything you've described, give me the source code and I'll make it fail catastrophically.Xmas said:I don't get it. If you adjust the sample positions, then you're trying to put sample No. x at exactly the same location where it is in multisampling operation.OpenGL guy said:But if your compressed value depends on sample location...
And even if that's not possible, it's not too bad. Leave the sampling positions where they are. Ok, your texture and geometry sampling points are not in the same location then, but this is the case with multisampling, too. It may give slight overlap artifacts if polygons with alpha test are connected to polygons without alpha test, but considering how alpha test edges look like, I think it is a worthy tradeoff for many games.
If you don't move the sample positions, then probably not, however you're going to get weird artifacts on the edges on some objects. These weird artifacts can be very ugly.You don't have to decompress the Z buffer if you don't mess with the sample positions, but only use multisample mask, do you?But, as I mentioned, you'd have to decompress the whole buffer, meaning very poor performance... worse than supersampling since supersampling would benefit from compression.Rendering with multisample mask certainly isn't the best thing for performance because it makes compression almost useless for those tiles affected, but it's better than supersampling for the whole frame.
Not necessarily. Consider ALPHA_TO_COVERAGE.Cryect said:Also wouldn't any wise programmer batch his alpha tested polys all together as well as all of his alpha blended polys at the end?
More correctly, it's GL_SAMPLE_ALPHA_TO_COVERAGE_ARB, and the name shows probably the biggest problem with a2c...Dark Helmet said:Not necessarily. Consider ALPHA_TO_COVERAGE.
Is C#/MDX fine with you?OpenGL guy said:The problem is far worse than you think. If you think it's trivial, write a program that does everything you've described, give me the source code and I'll make it fail catastrophically.
The problem is far worse than you think. If you think it's trivial, write a program that does everything you've described, give me the source code and I'll make it fail catastrophically.
C or C++ please... I don't want to have to learn a new language just for thisXmas said:Is C#/MDX fine with you?OpenGL guy said:The problem is far worse than you think. If you think it's trivial, write a program that does everything you've described, give me the source code and I'll make it fail catastrophically.
How so? The thought running through my mind is it mandates the slow path (frag shader -> alpha value -> now we know which samples, so we can: stencil/alpha/depth test).Xmas said:More correctly, it's GL_SAMPLE_ALPHA_TO_COVERAGE_ARB, and the name shows probably the biggest problem with a2c...Dark Helmet said:Not necessarily. Consider ALPHA_TO_COVERAGE.
Well, then maybe you tell me what you need and I will write it. After learning MDX, I really don't want to go back to those clumsy COM interfaces.OpenGL guy said:C or C++ please... I don't want to have to learn a new language just for this
I meant the "GL_" part. There is no a2c in DirectX.Dark Helmet said:How so? The thought running through my mind is it mandates the slow path (frag shader -> alpha value -> now we know which samples, so we can: stencil/alpha/depth test).
You should be able to just grab one of the MS DX9 SDK samples, rip out the rendering path and add in everything you've described above for alpha tested textures. Then put the source someplace and I'll show you how to break itXmas said:Well, then maybe you tell me what you need and I will write it. After learning MDX, I really don't want to go back to those clumsy COM interfaces.OpenGL guy said:C or C++ please... I don't want to have to learn a new language just for this
Ok, just a very quick hack:OpenGL guy said:You should be able to just grab one of the MS DX9 SDK samples, rip out the rendering path and add in everything you've described above for alpha tested textures. Then put the source someplace and I'll show you how to break it
HRESULT CMyD3DApplication::DrawTrees()
{
bool bUseSuperSampling = true;
D3DXMATRIX pMatrix, tMatrix, pnMatrix[4];
float samplepos[4][2] = /*{ { -0.375f, -0.125 }, { 0.125f, -0.375f },
{ -0.125f, 0.375f }, { 0.375f, 0.125f } };*/ // RG
{ { 0, 0 }, { 0, 0.5f }, { 0.5f, 0 }, { 0.5f, 0.5f } } ; // OG
D3DVIEWPORT9 viewport;
if(bUseSuperSampling)
{
m_pd3dDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE);
m_pd3dDevice->GetTransform(D3DTS_PROJECTION, &pMatrix);
m_pd3dDevice->GetViewport(&viewport);
// prepare shifted projection matrices for sample positions
for(int j = 0; j < 4; ++j)
{
D3DXMatrixTranslation(&tMatrix, 2 * samplepos[j][0] / viewport.Width,
2 * samplepos[j][1] / viewport.Height, 0);
D3DXMatrixMultiply(&pnMatrix[j], &pMatrix, &tMatrix);
}
}
// Enable alpha testing (skips pixels with less than a certain alpha.)
if( m_d3dCaps.AlphaCmpCaps & D3DPCMPCAPS_GREATEREQUAL )
{
m_pd3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE );
m_pd3dDevice->SetRenderState( D3DRS_ALPHAREF, 0x7f );//***
m_pd3dDevice->SetRenderState( D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL );
}
// Loop through and render all trees
m_pd3dDevice->SetStreamSource( 0, m_pTreeVB, 0, sizeof(TREEVERTEX) );
m_pd3dDevice->SetFVF( TREEVERTEX::FVF );
for( DWORD i=0; i<NUM_TREES; i++ )
{
// Quick culling for trees behind the camera
// This calculates the tree position relative to the camera, and
// projects that vector against the camera's direction vector. A
// negative dot product indicates a non-visible tree.
if( 0 > ( m_Trees[i].vPos.x - m_vEyePt.x ) * g_vDir.x +
( m_Trees[i].vPos.z - m_vEyePt.z ) * g_vDir.z )
{
break;
}
// Set the tree texture
m_pd3dDevice->SetTexture( 0, m_pTreeTextures[m_Trees[i].dwTreeTexture] );
// Translate the billboard into place
m_matBillboardMatrix._41 = m_Trees[i].vPos.x;
m_matBillboardMatrix._42 = m_Trees[i].vPos.y;
m_matBillboardMatrix._43 = m_Trees[i].vPos.z;
m_pd3dDevice->SetTransform( D3DTS_WORLD, &m_matBillboardMatrix );
//***
if(bUseSuperSampling)
{
for(int j = 0; j < 4; ++j)
{
m_pd3dDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, 1 << j);
m_pd3dDevice->SetTransform(D3DTS_PROJECTION, &pnMatrix[j]);
// Render the billboard
m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, m_Trees[i].dwOffset, 2 );
}
}
else
{
// Render the billboard
m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, m_Trees[i].dwOffset, 2 );
}
//***
}
// Restore state
D3DXMATRIXA16 matWorld;
D3DXMatrixIdentity( &matWorld );
m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
m_pd3dDevice->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE );
//***
if(bUseSuperSampling)
{
m_pd3dDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xffff);
m_pd3dDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE);
m_pd3dDevice->SetTransform(D3DTS_PROJECTION, &pMatrix);
}
//***
return S_OK;
}
Haven't had time to look, but I've not forgotten about it.nelg said:So, can it be broken?
It doesn't even have to break when GCAA is done by the AA HWDemoCoder said:Not on all HW. On some HW, GCAA can be implemented via pixel shaders.
This seems like a very serious source of artifacts to me. I think the best case scenario would be setting it up so that all samples in a pixel have the same Z value (i.e. the translation matrix offsets match the subsample offsets). Then you get just plain aliased intersections between alpha-tested and non alpha-tested polys. Better than no alpha-test AA, but it may not be good enough considering the perf hit of your solution, Xmas. Still, we all love having IQ options, right?Xmas said:And even if that's not possible, it's not too bad. Leave the sampling positions where they are. Ok, your texture and geometry sampling points are not in the same location then, but this is the case with multisampling, too. It may give slight overlap artifacts if polygons with alpha test are connected to polygons without alpha test, but considering how alpha test edges look like, I think it is a worthy tradeoff for many games.