Lately, I've been thinking about switching over to SMAA 2.7. The results SMAA gets are just much better than FXAA's. I've integrated the code given by the team just fine, but the resulting data is wrong. SMAA's split into three pass: edge detection, blending weight calculations and finally neighbor blending. The first step seemingly works perfectly, but the second step doesn't produce the results I should get, and thus the final result is that the image isn't even antialiased.
As a side note, I'm using the precompiled DX10 application but I've taken most of the code and logic from the DX9 sample.
First of all, here's the code which sets up the postprocess:
if(HkData::iSetSMAA)
{
#ifdef DEBUG_PIPELINE
OutputDebugString("SMAA\n");
D3DPERF_BeginEvent(PIX_COLOR, L"SMAA");
#endif
if(HkData::bBenchmark)
timerBench.start();
// save critical states
IDirect3DVertexDeclaration9* oldVertexDecl;
d3d9_realdevice->GetVertexDeclaration(&oldVertexDecl);
IDirect3DVertexBuffer9* pVBOLD;
uint iVBOLD_OFFSET, iVBOLD_STRIDE;
d3d9_realdevice->GetStreamSource(0, &pVBOLD, &iVBOLD_OFFSET, &iVBOLD_STRIDE);
d3d9_realdevice->SetVertexDeclaration( g_pVertDeclPP );
d3d9_realdevice->SetStreamSource( 0, pVB, 0, sizeof( PPVERT ) );
d3d9_realdevice->StretchRect(surfBackBuffer, 0, surfBackBufferTex, 0, D3DTEXF_NONE);
// edge detection pass
d3d9_realdevice->SetRenderTarget(0, surfSMAA_Edge);
d3d9_realdevice->SetDepthStencilSurface(surfOldDepth);
d3d9_realdevice->SetRenderState(D3DRS_STENCILENABLE, TRUE);
d3d9_realdevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
d3d9_realdevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL, 0x00000000, 0.0f, 0 );
g_pEffectSMAA->SetTexture("colorTex2D", texBackBuffer);
g_pEffectSMAA->SetTechnique("LumaEdgeDetection");
g_pEffectSMAA->Begin(&iPasses, 0);
g_pEffectSMAA->BeginPass(0);
d3d9_realdevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
g_pEffectSMAA->EndPass();
g_pEffectSMAA->End();
// blending weight pass
d3d9_realdevice->SetRenderTarget(0, surfSMAA_Blend);
d3d9_realdevice->Clear( 0L, NULL, D3DCLEAR_TARGET,
0x00000000, 1.0f, 0L );
g_pEffectSMAA->SetTexture("edgesTex2D", texSMAA_Edge);
g_pEffectSMAA->SetTexture("areaTex2D", texSMAA_Area);
g_pEffectSMAA->SetTexture("searchTex2D", texSMAA_Search);
g_pEffectSMAA->SetTechnique("BlendWeightCalculation");
g_pEffectSMAA->Begin(&iPasses, 0);
g_pEffectSMAA->BeginPass(0);
d3d9_realdevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
g_pEffectSMAA->EndPass();
g_pEffectSMAA->End();
d3d9_realdevice->StretchRect(surfSMAA_Blend, 0, surfBackBuffer, 0, D3DTEXF_NONE);
// final pass
/*d3d9_realdevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
d3d9_realdevice->SetRenderTarget(0, surfBackBuffer);
g_pEffectSMAA->SetTexture("blendTex2D", texSMAA_Blend);
g_pEffectSMAA->SetTexture("colorTex2D", texBackBuffer);
g_pEffectSMAA->SetTechnique("NeighborhoodBlending");
g_pEffectSMAA->Begin(&iPasses, 0);
g_pEffectSMAA->BeginPass(0);
SMAARenderQuad(surfdescBackBuffer.Width, surfdescBackBuffer.Height);
g_pEffectSMAA->EndPass();
g_pEffectSMAA->End();*/
// restore stuff
d3d9_realdevice->SetVertexDeclaration( oldVertexDecl );
oldVertexDecl->Release();
d3d9_realdevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
d3d9_realdevice->SetStreamSource(0, pVBOLD, iVBOLD_OFFSET, iVBOLD_STRIDE);
d3d9_realdevice->SetPixelShader(NULL);
d3d9_realdevice->SetVertexShader(NULL);
if(HkData::bBenchmark)
bench_current.tAA = timerBench.stop();
#ifdef DEBUG_PIPELINE
D3DPERF_EndEvent();
#endif
}
The shader code I'm using is taken bit-for-bit from the DX9 demo, so I won't copy the (lengthy) files here. Here's a link to the release I've been working with: https://github.com/iryoku/smaa/zipball/v2.7
I've debugged the application with maximum validation and output, but nothing in the log makes me believe the code is encountering errors. I've also done PIX runs, but I can't say I'm quite at the level necessary to understand the shader, so seeing what it does is slightly pointless. I have however taken pictures of each step (sorry for the large pictures but resizing kills all the details):
Initial image:

Edges:

Related edge stencil:

Weights:

Weights (alpha channel):

Demo program edges:

Demo program edge stencil:

Demo program weights:

Demo program weights (alpha):

Unless I'm missing something, it's pretty clear that my weights output is entirely different from what I'm supposed to be getting. I can't find a channel match which would indicate that the two versions use different channels for storing the data, either. I've double-checked and both surfaces I have are A8R8G8B8 like in the demo.
I'm quite stumped, but I have found very little information on how to implement SMAA outside of the main team's package. Most hits come back to the SMAA injector, which ironically works fine when wrapped around this (but it affects HUD elements and adds another layer of complexity, which is unacceptable). I can also say that I have modified the SMAA injector shader to get the weights image and it is extremely similar (if not identical) to the demo's, which makes me believe it's not a difference between DX9 and DX10 implementations, but a real problem with my code. However, considering the only inputs in the blend weights pass are the edge texture, the area texture and the search texture, all three of which appeared fine in PIX... I'm not sure what the error is.
Any help would be greatly appreciated.







