Quantcast
Channel: Community | MonoGame - Latest topics
Viewing all articles
Browse latest Browse all 6821

SSAO Artifacts

$
0
0

@Sven_Garbe wrote:

Hey guys, it's me - again ...

I've some issues porting the SSAO implementation from XNA to mono. As you will see in the screenshot below, a weird banding does occur. Also there are some strange lines inside the image which will flicker as the camera moves.

The random normals for the SSAO effect are taken from a funk-tastic random normal texture - so there should be no banding?

Any suggestions about that? It might be the testing scene I am using, but I can not remember having such issues in the old implementation ...

The FAR plane is set to 1000.0f.

My depth map is set to "Single". SSAO params are::
bias = 0.5f;
intensity = 1.5f;
sampleRadius = 0.5f;
scale = 1.5f;

SSAO-HLSL::

float4x4 param_inverseViewProjectionMatrix;
float4x4 param_inverseViewMatrix;
float3 param_frustumCornersVS[4];
float param_randomSize;
float param_sampleRadius;
float param_intensity;
float param_scale;
float param_bias;
float2 param_screenSize;

texture param_normalMap;
texture param_depthMap;
texture param_randomMap;



sampler normalSampler = sampler_state
{
	Texture = (param_normalMap);
	AddressU = CLAMP;
	AddressV = CLAMP;
	MagFilter = POINT;
	MinFilter = POINT;
	Mipfilter = NONE;
};
sampler depthSampler = sampler_state
{
	Texture = (param_depthMap);
	AddressU = CLAMP;
	AddressV = CLAMP;
	MagFilter = POINT;
	MinFilter = POINT;
	MipFilter = NONE;
};
sampler randomSampler = sampler_state
{
	Texture = (param_randomMap);
	AddressU = WRAP;
	AddressV = WRAP;
	MagFilter = POINT;
	MinFilter = POINT;
	MipFilter = NONE;
};



// Define VS input
struct VSIn
{
	float3 Position	: POSITION0;
	float3 TexCoord : TEXCOORD0;
};

// Define VS output and therefor PS input
struct VSOut
{
	float4 Position : POSITION0;
	float2 TexCoord: TEXCOORD0;
	float3 FrustumCornerVS : TEXCOORD1;
};

// Define PS output
struct PSOut
{
	float4 Color : COLOR0;
};



// Reconstruct view-space position from the depth buffer
float3 getPosition(in float2 vTexCoord, in float3 in_vFrustumCornerVS)
{
    float fPixelDepth = tex2D(depthSampler, vTexCoord).r;
    return float3(fPixelDepth * in_vFrustumCornerVS);
}

// Calculate the occlusion term
float doAmbientOcclusion(in float2 tcoord, in float3 p, in float3 cnorm, in float3 in_vFrustumCornerVS)
{
	float3 diff = getPosition(tcoord, in_vFrustumCornerVS) - p;
	float3 v = normalize(diff);
	float d = length(diff) * param_scale;

	return max(0.0, dot(cnorm, v) - param_bias) * (1.0 / (1.0 + d)) * param_intensity;
}



/**************************************************
Vertex shader.
**************************************************/
VSOut MainVS(VSIn input)
{
	VSOut output;

	output.Position = float4(input.Position, 1);
	output.TexCoord = input.TexCoord.xy;
	output.FrustumCornerVS = param_frustumCornersVS[input.TexCoord.z];

	return output;
}



/**************************************************
Pixel shader.
**************************************************/
PSOut MainPS(VSOut input)
{
	PSOut output;

	const float2 vec[4] = {
		float2(1,0),
		float2(-1,0),
		float2(0,1),
		float2(0,-1)
	};

	float3 p = getPosition(input.TexCoord, input.FrustumCornerVS);
	float3 n = normalize(tex2D(normalSampler, input.TexCoord).xyz * 2.0f - 1.0f);
	float2 rand = normalize(tex2D(randomSampler, param_screenSize * input.TexCoord / param_randomSize).xy * 2.0f - 1.0f);

	float ao = 0.0f;
	float rad = param_sampleRadius / p.z;

	int numIterations = 4;
	for (int j = 0; j < numIterations; ++j) {
		float2 coord1 = reflect(vec[j], rand) * rad;
		float2 coord2 = float2(coord1.x - coord1.y, coord1.x + coord1.y) * 0.707f;

		ao += doAmbientOcclusion(input.TexCoord + coord1 * 0.25, p, n, input.FrustumCornerVS);
		ao += doAmbientOcclusion(input.TexCoord + coord2 * 0.50, p, n, input.FrustumCornerVS);
		ao += doAmbientOcclusion(input.TexCoord + coord1 * 0.75, p, n, input.FrustumCornerVS);
		ao += doAmbientOcclusion(input.TexCoord + coord2 * 1.00, p, n, input.FrustumCornerVS);
	}

	ao /= (float)numIterations * 4.0;
	ao = saturate(ao * param_intensity);

	output.Color = 1 - ao;

	return output;
}



technique Default
{
	pass SSAO
	{
		VertexShader = compile vs_4_0 MainVS();
		PixelShader = compile ps_4_0 MainPS();
	}	
}

BTW. The ambient light is cranked up to a ridiculous value for this image :wink:

Posts: 6

Participants: 3

Read full topic


Viewing all articles
Browse latest Browse all 6821

Trending Articles