Good evening,
I despair! I've found a tutorial how to create A Simple and Practical Approach to SSAO.

I think the basic preconditions are clear.
I created two views, which renders the POSITION and the NORMALS to the given targets (g_buffer_pos_bmap, g_buffer_norm_bmap).

Here is my edited SSAO-Shader:

SSAO.fx
Code:
float random_size = 64;
float g_sample_rad = 32;
float g_intensity = 1;
float g_scale = 5;
float g_bias = 0.1;
float2 g_screen_size = { 720,480 }; //I know, but for testreasons i didnt want to give them by the main-script :x
//float2 g_screen_size = { 800,600 }; //4:3

texture g_buffer_scene_bmap;
texture g_buffer_pos_bmap;
texture g_buffer_posb_bmap; //backfaces rendered with CULL_CW
texture g_buffer_norm_bmap;
texture g_random_bmap;

sampler sceneSampler = sampler_state { Texture = <g_buffer_scene_bmap>; };
sampler g_buffer_pos = sampler_state { Texture = <g_buffer_pos_bmap>; };
sampler g_buffer_posb = sampler_state { Texture = <g_buffer_posb_bmap>; };
sampler g_buffer_norm = sampler_state { Texture = <g_buffer_norm_bmap>; };
sampler g_random = sampler_state { Texture = <g_random_bmap>; };

struct PS_INPUT
{
	float4 pos : POSITION0;
	float2 uv : TEXCOORD0;
};

struct PS_OUTPUT
{
	float4 color : COLOR0;
};

float3 getPosition(in float2 uv)
{
	return tex2D(g_buffer_pos,uv).xyz;
}

float3 getNormal(in float2 uv)
{
	return normalize(tex2D(g_buffer_norm, uv).xyz * 2.0f - 1.0f);
}

float2 getRandom(in float2 uv)
{
	return normalize(tex2D(g_random, g_screen_size * uv / random_size).xy * 2.0f - 1.0f);
}

float3 getPositionBack(in float2 uv)
{
	return tex2D(g_buffer_posb,uv).xyz;
}

float doAmbientOcclusion(in float2 tcoord,in float2 uv, in float3 p, in float3 cnorm)
{
	float3 diff = getPosition(tcoord + uv) - p;
	const float3 v = normalize(diff);
	const float d = length(diff)*g_scale;
	return max(0.0,dot(cnorm,v)-g_bias)*(1.0/(1.0+d))*g_intensity;
}

float doAmbientOcclusionBack(in float2 tcoord,in float2 uv, in float3 p, in float3 cnorm)
{
	float3 diff = getPositionBack(tcoord + uv) - p;
	const float3 v = normalize(diff);
	const float d = length(diff)*g_scale;
	return max(0.0,dot(cnorm,v)-g_bias)*(1.0/(1.0+d));
}

float4 AOPixelShader(PS_INPUT i) : COLOR0
{

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

	float3 p = getPosition(i.uv);
	float3 n = getNormal(i.uv);
	float2 rand = getRandom(i.uv);

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

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

		ao += doAmbientOcclusion(i.uv,coord1*0.25, p, n);
		ao += doAmbientOcclusion(i.uv,coord2*0.5, p, n);
		ao += doAmbientOcclusion(i.uv,coord1*0.75, p, n);
		ao += doAmbientOcclusion(i.uv,coord2, p, n);
		//Backfaces
		ao += doAmbientOcclusionBack(i.uv,coord1*(0.25+0.125), p, n);
		ao += doAmbientOcclusionBack(i.uv,coord2*(0.5+0.125), p, n);
		ao += doAmbientOcclusionBack(i.uv,coord1*(0.75+0.125), p, n);
		ao += doAmbientOcclusionBack(i.uv,coord2*1.125, p, n);
	}
	ao/=(float)iterations*4.0;
	//**END**//
	
	float4 finalColor = tex2D(sceneSampler, i.uv);
	
	finalColor.xyz *= 1-ao; //This should be the combined version

	//Do stuff here with your occlusion value âaoâ: modulate ambient lighting, write it to a buffer for later //use, etc.
	return 1-ao; //< This will return only the AO ;)
	}

technique SSAO
{
	pass P0
    {
        PixelShader = compile ps_3_0 AOPixelShader();
    }
}



But the results are unusable! crazy

For thoseones who want to try it, here's the rest of my code:

main.c
Code:
#include <acknex.h>
#include <default.c>

#include "PP_Helper.c"

BMAP* camera_clean;
BMAP* depthtex;

BMAP* g_buffer_pos;
BMAP* g_buffer_posb;
BMAP* g_buffer_norm;
BMAP* g_random = "g_random.pcx";

MATERIAL* matPosition_buffer_view =
{
	effect = "Position_buffer_view.fx";
}

MATERIAL* matNormal_buffer_view =
{
	effect = "Normal_buffer_view.fx";
}

MATERIAL* matSSAO =
{
	effect = "SSAO.fx";
}

#define PRAGMA_PATH "scene";

void main()
{
	level_load("atrium.wmb");
	
	VIEW* position_buffer = view_create(-3);
	set(position_buffer, VISIBLE);
	g_buffer_pos = bmap_createblack(screen_size.x, screen_size.y, 24);
	position_buffer.bmap = g_buffer_pos;
	position_buffer.material = matPosition_buffer_view;
	
	VIEW* positionb_buffer = view_create(-2);
	set(positionb_buffer, VISIBLE);
	g_buffer_posb = bmap_createblack(screen_size.x, screen_size.y, 24);
	positionb_buffer.bmap = g_buffer_posb;
	set(positionb_buffer,CULL_CW);
	positionb_buffer.material = matPosition_buffer_view;
	
	VIEW* normal_buffer = view_create(-1);
	set(normal_buffer, VISIBLE);
	g_buffer_norm = bmap_createblack(screen_size.x, screen_size.y, 24);
	normal_buffer.bmap = g_buffer_norm;
	normal_buffer.material = matNormal_buffer_view;
	
	PP_Add(matSSAO, camera, NULL); //Start the SSAO
	while(1)
	{
		vec_set(position_buffer.x,camera.x);
		vec_set(position_buffer.pan,camera.pan);
		vec_set(normal_buffer.x,camera.x);
		vec_set(normal_buffer.pan,camera.pan);
		wait (1);
	}
}



Position_buffer_view.fx
Code:
#define FarZ 1000.0f

float4x4 matWorld;
float4x4 matWorldView;
float4x4 matWorldViewProj;

struct VS_INPUT
{
 float4 position : POSITION;
};

struct VS_OUTPUT
{
 float4 position : POSITION;
 float3 viewpos : TEXCOORD;
};

VS_OUTPUT vertexShader(VS_INPUT input)
{
	VS_OUTPUT output;

	output.position=mul(input.position,matWorldViewProj);
	output.viewpos=mul(input.position,matWorldView).xyz;

	return output;
}

float4 pixelShader(VS_OUTPUT input) : COLOR
{
	return float4((input.viewpos.x/250)*(input.viewpos.z/FarZ),(input.viewpos.y/250)*(input.viewpos.z/FarZ),1-input.viewpos.z/FarZ,0); //I thried much versions, but here is my actual
}

technique tech_00
{
	pass pass_00
	{
		VertexShader = compile vs_3_0 vertexShader();
		PixelShader = compile ps_3_0 pixelShader();
	}
}



Normal_buffer_view.fx
Code:
float4x4 matWorldView;
float4x4 matWorldViewProj;

texture TargetMap;

sampler2D smpScreen = sampler_state
{
	Texture = <TargetMap>;
	
	MinFilter	= linear;
	MagFilter	= linear;
	MipFilter	= linear;
	
	AddressU		= Wrap;
	AddressV		= Wrap;
};

struct VS_OUT
{
	float4 Pos : POSITION;
	float4 WorldPos : TEXCOORD0;
	float3 Norm : TEXCOORD1;
};

VS_OUT Shader_VS(float4 inPos : POSITION, float3 Normal : NORMAL)
{
	VS_OUT Out = (VS_OUT)0;
	
	Out.Pos = mul(inPos, matWorldViewProj);
	Out.Norm = mul(Normal, matWorldView);
	
	return Out;
}

float4 Shader_PS(float3 Norm : TEXCOORD1) : COLOR
{
	return float4(Norm.x,Norm.y,Norm.z,0);
}

technique tech_00
{
	pass pass_00
	{
		VertexShader = compile vs_3_0 Shader_VS();
		PixelShader = compile ps_3_0 Shader_PS();
	}
}



Good Luck! And have fun.
But please, if there is a solution, let me know.

Good night. sleep

P.S.: For any questions, post here. laugh

Edit: What the result and POSITION/NORMALS SHOULD look like!
[video:youtube]https://www.youtube.com/watch?v=a45hUtn_GyM[/video]

Last edited by 1234David; 06/13/15 20:19.