SMAA (Antialiasing technique) - image comparison added
Posted: Wed Apr 25, 2012 10:28 pm
If you haven't heard about SMAA (SMAA: Enhanced Subpixel Morphological Antialiasing), it is a new AA technique with very good results: http://www.iryoku.com/smaa/ - Make sure to download the HD movie for image comparison!
Because it's purely a post-processing technique, I figured it would be easy to integrate in Ogre and gave it a shot.
Here are the results (this is only SMAA1x, there are also SMAA T2x among others which should give much better results, but they are harder to integrate):
off

on

off

on

To enable it, simply add the SMAA compositor to your viewport and activate it.
smaa.material
SMAA.compositor
smaa.cg
SMAA.h (this goes in the same folder as smaa.cg, it is mostly copy&paste from their demo)
Download here: https://github.com/scrawl/smaa/raw/master/SMAA.h
Then, download these 2 precomputed textures and put them in your resource path:
https://github.com/iryoku/smaa/raw/mast ... exDX10.dds
https://github.com/iryoku/smaa/raw/mast ... rchTex.dds
Because it's purely a post-processing technique, I figured it would be easy to integrate in Ogre and gave it a shot.
Here are the results (this is only SMAA1x, there are also SMAA T2x among others which should give much better results, but they are harder to integrate):
off

on

off

on

To enable it, simply add the SMAA compositor to your viewport and activate it.
smaa.material
Code: Select all
vertex_program SMAA/EdgeDetection_VS cg
{
source smaa.cg
profiles vs_4_0 vs_1_1 vp40 arbvp1
entry_point EdgeDetection_VS
default_params
{
param_named_auto viewportSize viewport_size
param_named_auto wvp worldviewproj_matrix
}
}
fragment_program SMAA/ColorEdgeDetection_PS cg
{
source smaa.cg
profiles ps_4_0 ps_2_x fp40 arbfp1
entry_point ColorEdgeDetection_PS
default_params
{
param_named_auto viewportSize viewport_size
}
}
fragment_program SMAA/LumaEdgeDetection_PS cg
{
source smaa.cg
profiles ps_4_0 ps_2_x fp40 arbfp1
entry_point LumaEdgeDetection_PS
default_params
{
param_named_auto viewportSize viewport_size
}
}
fragment_program SMAA/DepthEdgeDetection_PS cg
{
source smaa.cg
profiles ps_4_0 ps_2_x fp40 arbfp1
entry_point DepthEdgeDetection_PS
default_params
{
param_named_auto viewportSize viewport_size
}
}
vertex_program SMAA/BlendWeightCalculation_VS cg
{
source smaa.cg
profiles vs_4_0 vs_1_1 vp40 arbvp1
entry_point BlendWeightCalculation_VS
default_params
{
param_named_auto viewportSize viewport_size
param_named_auto wvp worldviewproj_matrix
}
}
fragment_program SMAA/BlendWeightCalculation_PS cg
{
source smaa.cg
profiles ps_4_0 ps_2_x fp40 arbfp1
entry_point BlendWeightCalculation_PS
default_params
{
param_named_auto viewportSize viewport_size
}
}
vertex_program SMAA/NeighborhoodBlending_VS cg
{
source smaa.cg
profiles vs_4_0 vs_1_1 vp40 arbvp1
entry_point NeighborhoodBlending_VS
default_params
{
param_named_auto viewportSize viewport_size
param_named_auto wvp worldviewproj_matrix
}
}
fragment_program SMAA/NeighborhoodBlending_PS cg
{
source smaa.cg
profiles ps_4_0 ps_2_x fp40 arbfp1
entry_point NeighborhoodBlending_PS
default_params
{
param_named_auto viewportSize viewport_size
}
}
material SMAA/ColorEdgeDetection
{
technique
{
pass
{
vertex_program_ref SMAA/EdgeDetection_VS
{
}
fragment_program_ref SMAA/ColorEdgeDetection_PS
{
}
depth_check off
texture_unit colorGammaTex
{
tex_address_mode clamp
filtering linear linear linear
}
texture_unit predicationTex
{
tex_address_mode clamp
filtering linear linear linear
}
}
}
}
material SMAA/LumaEdgeDetection
{
technique
{
pass
{
vertex_program_ref SMAA/EdgeDetection_VS
{
}
fragment_program_ref SMAA/LumaEdgeDetection_PS
{
}
depth_check off
texture_unit colorGammaTex
{
tex_address_mode clamp
filtering linear linear linear
}
texture_unit predicationTex
{
tex_address_mode clamp
filtering linear linear linear
}
}
}
}
material SMAA/DepthEdgeDetection
{
technique
{
pass
{
vertex_program_ref SMAA/EdgeDetection_VS
{
}
fragment_program_ref SMAA/LumaEdgeDetection_PS
{
}
depth_check off
texture_unit depthTex
{
tex_address_mode clamp
filtering linear linear linear
}
}
}
}
material SMAA/BlendWeightCalculation
{
technique
{
pass
{
vertex_program_ref SMAA/BlendWeightCalculation_VS
{
}
fragment_program_ref SMAA/BlendWeightCalculation_PS
{
}
depth_check off
texture_unit edgesTex
{
tex_address_mode clamp
filtering linear linear linear
}
texture_unit areaTex
{
texture AreaTexDX10.dds
tex_address_mode clamp
filtering linear linear linear
}
texture_unit searchTex
{
texture SearchTex.dds
tex_address_mode clamp
filtering point point point
}
}
}
}
material SMAA/NeighborhoodBlending
{
technique
{
pass
{
vertex_program_ref SMAA/NeighborhoodBlending_VS
{
}
fragment_program_ref SMAA/NeighborhoodBlending_PS
{
}
depth_check off
texture_unit colorTex
{
tex_address_mode clamp
filtering linear linear point
}
texture_unit blendTex
{
tex_address_mode clamp
filtering linear linear linear
}
}
}
}
Code: Select all
compositor SMAA
{
technique
{
texture previousscene target_width target_height PF_A8R8G8B8
texture edgeTex target_width target_height PF_FLOAT16_RGBA
texture blendTex target_width target_height PF_FLOAT16_RGBA
target previousscene
{
input previous
}
// Edge detection pass
target edgeTex
{
input none
pass clear
{
}
pass stencil
{
check on
ref_value 1
pass_op replace
}
pass render_quad
{
material SMAA/ColorEdgeDetection
input 0 previousscene
}
}
// Blending weights calculation pass
target blendTex
{
input none
pass clear
{
}
pass stencil
{
// Process only marked pixels
check on
pass_op keep
comp_func equal
ref_value 1
}
pass render_quad
{
material SMAA/BlendWeightCalculation
input 0 edgeTex
}
}
// Neighborhood blending pass
target_output
{
input none
pass stencil
{
// Process _all_ pixels
check off
}
pass render_quad
{
material SMAA/NeighborhoodBlending
input 0 previousscene
input 1 blendTex
}
}
}
}
Code: Select all
#define SMAA_PRESET_HIGH 1
//#define SMAA_PREDICATION 1
#define SMAA_CG 1
#include "SMAA.h"
void EdgeDetection_VS(in float4 position : POSITION,
out float4 oPosition : POSITION,
uniform float4x4 wvp,
inout float2 texcoord : TEXCOORD0,
out float4 offset[3] : TEXCOORD1,
uniform float4 viewportSize
) {
position.xy = sign(position.xy);
texcoord = (float2(position.x, -position.y) + 1.0f) * 0.5f;
SMAAEdgeDetectionVS(position, oPosition, texcoord, offset, viewportSize.zw);
oPosition = mul(wvp, position);
}
void BlendWeightCalculation_VS(in float4 position : POSITION,
out float4 oPosition : POSITION,
uniform float4x4 wvp,
inout float2 texcoord : TEXCOORD0,
out float2 pixcoord : TEXCOORD1,
out float4 offset[3] : TEXCOORD2,
uniform float4 viewportSize
) {
position.xy = sign(position.xy);
texcoord = (float2(position.x, -position.y) + 1.0f) * 0.5f;
SMAABlendingWeightCalculationVS(position, oPosition, texcoord, pixcoord, offset, viewportSize.zw);
oPosition = mul(wvp, position);
}
void NeighborhoodBlending_VS(in float4 position : POSITION,
out float4 oPosition : POSITION,
uniform float4x4 wvp,
inout float2 texcoord : TEXCOORD0,
out float4 offset[2] : TEXCOORD1,
uniform float4 viewportSize
) {
position.xy = sign(position.xy);
texcoord = (float2(position.x, -position.y) + 1.0f) * 0.5f;
SMAANeighborhoodBlendingVS(position, oPosition, texcoord, offset, viewportSize.zw);
oPosition = mul(wvp, position);
}
float4 LumaEdgeDetection_PS(float4 position : POSITION,
float2 texcoord : TEXCOORD0,
float4 offset[3] : TEXCOORD1,
#if SMAA_PREDICATION == 1
SMAATexture2D predicationTex : TEXUNIT1,
#endif
uniform SMAATexture2D colorGammaTex : TEXUNIT0,
uniform float4 viewportSize
) : COLOR {
//return SMAALumaEdgeDetectionPS(texcoord, offset, colorGammaTex, predicationTex);
return SMAALumaEdgeDetectionPS(texcoord, offset, colorGammaTex, viewportSize.zw);
}
float4 ColorEdgeDetection_PS(float4 position : POSITION,
float2 texcoord : TEXCOORD0,
float4 offset[3] : TEXCOORD1,
uniform float4 viewportSize,
#if SMAA_PREDICATION == 1
SMAATexture2D predicationTex : TEXUNIT1,
#endif
uniform SMAATexture2D colorGammaTex : TEXUNIT0) : COLOR {
//return SMAAColorEdgeDetectionPS(texcoord, offset, colorGammaTex, predicationTex);
return SMAAColorEdgeDetectionPS(texcoord, offset, colorGammaTex, viewportSize.zw);
}
float4 DepthEdgeDetection_PS(float4 position : POSITION,
float2 texcoord : TEXCOORD0,
float4 offset[3] : TEXCOORD1,
uniform float4 viewportSize,
uniform SMAATexture2D depthTex : TEXUNIT0) : COLOR {
return SMAADepthEdgeDetectionPS(texcoord, offset, depthTex, viewportSize.zw);
}
float4 BlendWeightCalculation_PS(float4 position : POSITION,
float2 texcoord : TEXCOORD0,
float2 pixcoord : TEXCOORD1,
float4 offset[3] : TEXCOORD2,
uniform float4 viewportSize,
uniform SMAATexture2D edgesTex : TEXUNIT0,
uniform SMAATexture2D areaTex : TEXUNIT1,
uniform SMAATexture2D searchTex : TEXUNIT2) : COLOR {
return SMAABlendingWeightCalculationPS(texcoord, pixcoord, offset, edgesTex, areaTex, searchTex, viewportSize.zw, 0);
}
float4 NeighborhoodBlending_PS(float4 position : POSITION,
float2 texcoord : TEXCOORD0,
float4 offset[2] : TEXCOORD1,
uniform float4 viewportSize,
uniform SMAATexture2D colorTex : TEXUNIT0,
uniform SMAATexture2D blendTex : TEXUNIT1) : COLOR {
return SMAANeighborhoodBlendingPS(texcoord, offset, colorTex, blendTex, viewportSize.zw);
}
Download here: https://github.com/scrawl/smaa/raw/master/SMAA.h
Then, download these 2 precomputed textures and put them in your resource path:
https://github.com/iryoku/smaa/raw/mast ... exDX10.dds
https://github.com/iryoku/smaa/raw/mast ... rchTex.dds