Advertisement

Implementing SSAA

Started by July 24, 2019 07:44 PM
5 comments, last by Wuszt 5 years, 6 months ago

Hello!

I'm trying to implement SSAA by myself. My idea is to draw entire scene few times with different offsets (not always regular, but I would like to test for example checker) to textures and merge them later. And it works in some way... but I don't see difference above 8 samples and I'm pretty sure that MSAA x8 looks much much better than my 64 samples SSAA.

My main suspect is wrong applied offsets. I'm calculating my offsets in range [-0.5,0.5] and then I'm dividing them by half of my resolution. Why half? Because if I think correctly NDC in D3D11 is in range [-1,1] so one pixel is twice as bigger. Then I modify my projection matrix:


void Camera::SetOffset(const DirectX::XMFLOAT2& offset)
{
    m_offset = offset;

    XMFLOAT4 tmp;
    XMStoreFloat4(&tmp, m_projectionMatrix.r[3]);

    tmp.x = m_offset.x;
    tmp.y = m_offset.y;

    m_projectionMatrix.r[3] = XMLoadFloat4(&tmp);
}

And now I'm not sure if translating my projection matrix is a proper way to apply offset... Can you see something wrong in my thinking or it's bug somewhere in my code?

Adding an additional translation to your projection matrix is a totally valid way to do this. And you're correct that you should divide your offset by half your resolution in order to get the right offset in NDC space. In general you'll want to be careful to add your translation on top of what's already in your projection matrix, but the code you have should be fine for a typical perspective projection that only offsets along Z. For reference have some similar code here that I've used for TAA jittering: https://github.com/TheRealMJP/MSAAFilter/blob/master/MSAAFilter/MSAAFilter.cpp#L219

In the code I linked my jitter offset is in the range [-1, 1] which is why I divide by the viewport size and not half of it.

If your AA doesn't look good, I would double-check that your offsets are what you expect them to be. Also, how exactly are you merging the individual samples to generate the final antialiased image?

Advertisement
13 hours ago, MJP said:

If your AA doesn't look good, I would double-check that your offsets are what you expect them to be. Also, how exactly are you merging the individual samples to generate the final antialiased image?

I checked my offsets few times already, but please have a look:


void Get8x8Grid(DirectX::XMFLOAT2 offsets[64])
{
    XMFLOAT2 offset(0.4375f, 0.4375f);

    for (int i = 0; i < 64; ++i)
    {
        offsets[i].x = -offset.x;
        offsets[i].y = -offset.y;

        offsets[i].x += (i % 8) * 0.125f;
        offsets[i].y += (i / 8) * 0.125f;
    }
}

To merge my samples I just render fullscreen quad and averaging textures.


cbuffer cbSSAA : register(b2)
{
    int TexturesAmount;
};

Texture2D Textures[64];

float4 PS(VS_OUTPUT input) : SV_Target
{
    float4 result = 0;

    for (int i = 0; i < TexturesAmount;++i)
    {
        result += Textures[i].Sample(PointSampler, input.Tex);
    }

    result /= TexturesAmount;

    result.a = 1.0f;

    return result;
}

I'm updating cbSSAA for sure. Do you see any mistake?

wtf.png

Hello again!

I've just noticed that my SSAA works pretty well on close things! Sometimes it even blurs image too much. But it can't deal with small edges? I don't get it, because MSAA can do it somehow and I use same algorithm to resolve it...

 

Please ignore white elements on house. It's some artifact after uploading images here.

170295701.png

170297729.png

170299392.png

170316643.png

170332264.png

170555308.png

170576710.png

170580584.png

On 7/25/2019 at 5:44 AM, Wuszt said:

tmp.x = m_offset.x; tmp.y = m_offset.y;

I haven't worked through the math to find out whether simply setting the offset into the 4th row is the same as multiplying with a translation matrix, but my code is similar to MJP's example code too -- 


Mat4 translation = Mat4::Translation({2.0f * m_jitter[0] / m_width, 2.0f * m_jitter[1] / m_height, 0.0f});
newProjection = translation * projection;

 

3 hours ago, Wuszt said:

I've just noticed that my SSAA works pretty well on close things! Sometimes it even blurs image too much. But it can't deal with small edges? I don't get it, because MSAA can do it somehow and I use same algorithm to resolve it...

Yeah it looks like it's jittering by much more than 1px up close, but less than 1px in the distance?? Which is what would happen if the translation happens before perspective, instead of after perspective...?

16 hours ago, Hodgman said:

I haven't worked through the math to find out whether simply setting the offset into the 4th row is the same as multiplying with a translation matrix

YES! I changed it to translation and I don't really understand why, but it works! Thank You! I literally checked everything few times except this, because camera was moving in proper directions so I assumed it's fine. It's always about math...

FYI:Untitled.thumb.png.5ca4b83a18cefb5a173ac3ed6529a43e.png

This topic is closed to new replies.

Advertisement