Gamestudio Links
Zorro Links
Newest Posts
Data from CSV not parsed correctly
by EternallyCurious. 04/18/24 10:45
StartWeek not working as it should
by Zheka. 04/18/24 10:11
folder management functions
by VoroneTZ. 04/17/24 06:52
lookback setting performance issue
by 7th_zorro. 04/16/24 03:08
zorro 64bit command line support
by 7th_zorro. 04/15/24 09:36
Zorro FIX plugin - Experimental
by flink. 04/14/24 07:48
Zorro FIX plugin - Experimental
by flink. 04/14/24 07:46
AUM Magazine
Latest Screens
The Bible Game
A psychological thriller game
SHADOW (2014)
DEAD TASTE
Who's Online Now
3 registered members (MadJack, AndrewAMD, Quad), 540 guests, and 1 spider.
Key: Admin, Global Mod, Mod
Newest Members
EternallyCurious, 11honza11, ccorrea, sakolin, rajesh7827
19046 Registered Users
Previous Thread
Next Thread
Print Thread
Rate Thread
Alternative SSAO #452489
06/13/15 20:08
06/13/15 20:08
Joined: Jan 2012
Posts: 14
1
1234David Offline OP
Newbie
1234David  Offline OP
Newbie
1

Joined: Jan 2012
Posts: 14
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.
Re: Alternative SSAO [Re: 1234David] #452498
06/14/15 11:19
06/14/15 11:19
Joined: Jun 2007
Posts: 1,337
Hiporope and its pain
txesmi Offline
Serious User
txesmi  Offline
Serious User

Joined: Jun 2007
Posts: 1,337
Hiporope and its pain
Hi,
In a fast check I can see several troubles on your rendering processes. Hard to explain them all but I will try with some.


Let's start with the view space normals buffer rendering shader:

1. The pixel shader input does not fit the vertex shader output. It should look like this:
Code:
float4 Shader_PS(VS_OUT input) : COLOR



2. The normals have to be converted to a 0<->1 range into the pixel shader. Otherway the normals with a negative component will fail. You will need to normalize the ponderated normals before converting them.
Code:
input.Norm = normalize ( input.Norm );
input.Norm *= 0.5f;
input.Norm += 0.5f;
return float4 ( inputNorm.xyz, 1.0f );



3. The alpha value of the returning vector of the pixel shader has to be 1.0f instead of 0. Otherway it will save nothing into the buffer.

4. You should delete the WorldPos member of the vertex shader output struct.

5. You will save a little rendering time by casting the matWorldView matrix to a float3x3 matrix, so it only rotates the normal with no traslating and scaling computations.
Code:
Out.Norm = mul ( Normal, (float3x3)matWorldView );



6. The TargetMap bitmap sampler is not needed at all.

7. The shader has no support for alpha channeled textures such leaves and so. You will need to check the texture alpha value in order to safe the opaque pixels only. These textures need to set 'AlphaBlendEnable=True;' into the technique pass to be correctly rendered.


Tips for the view space position buffer rendering shader:

1. This buffer needs more accuracy than 8bits per channel. You will need set at least a 4x16bits bitmap to the view. Otherway it will generate terribly noticeable steps. Be afraid of this kind of bitmaps because are very expensive and slow on lowend machines.
Code:
g_buffer_pos = bmap_createblack ( screen_size.x, screen_size.y, 12222 ); // 14444 for 4x32bits bitmap



2. Save the position values straight. No further computations are needed.
Code:
return float4 ( input.viewpos.xyz, 1.0f );



3. The third and the seventh tip of the normals buffer are also applicable for this buffer.


3dgs views have the stage member that lets you use the CHILD flag in order to share the transformation matrix and view fustrum clipping. The way you wrote the code will compute the visible entities for each view with its performance lost.
Code:
camera->bmap = bmap_createblack ( screen_size.x, screen_size.y, 24 ); // save the main render on a bitmap to sample it on the last stage (the ssao shader).
set ( position_buffer, CHILD | SHOW );
set ( positionb_buffer, CHILD | SHOW );
set ( normal_buffer, CHILD | SHOW );
camera->stage = position_buffer;
position_buffer->stage = positionb_buffer;
positionb_buffer->stage = normal_buffer;



On this fast try the SSAO shader did not work properly as it is. I don't know why. The screen is cut on 4 squares by the center and no one of those is correct. I will take a deeper look.

Salud!

Last edited by txesmi; 06/14/15 11:23.
Re: Alternative SSAO [Re: txesmi] #452499
06/14/15 12:49
06/14/15 12:49
Joined: Jun 2007
Posts: 1,337
Hiporope and its pain
txesmi Offline
Serious User
txesmi  Offline
Serious User

Joined: Jun 2007
Posts: 1,337
Hiporope and its pain
Ok, I solved the problem.

The position has to be the projected space position, no the view space one.

Hope it helps,
Salud!

Re: Alternative SSAO [Re: txesmi] #452500
06/14/15 13:54
06/14/15 13:54
Joined: Jan 2012
Posts: 14
1
1234David Offline OP
Newbie
1234David  Offline OP
Newbie
1

Joined: Jan 2012
Posts: 14
YOU ARE AWSOME!!!

Thank you a lot! grin grin grin
I will add a litte blur shader and it should look great.

Re: Alternative SSAO [Re: 1234David] #452506
06/14/15 20:14
06/14/15 20:14
Joined: Jun 2007
Posts: 1,337
Hiporope and its pain
txesmi Offline
Serious User
txesmi  Offline
Serious User

Joined: Jun 2007
Posts: 1,337
Hiporope and its pain
Glad to help!

Re: Alternative SSAO [Re: txesmi] #468335
09/30/17 18:37
09/30/17 18:37
Joined: Sep 2003
Posts: 6,861
Kiel (Germany)
Superku Offline
Senior Expert
Superku  Offline
Senior Expert

Joined: Sep 2003
Posts: 6,861
Kiel (Germany)
Thanks for sharing, to the both of you!


"Falls das Resultat nicht einfach nur dermassen gut aussieht, sollten Sie nochmal von vorn anfangen..." - Manual

Check out my new game: Pogostuck: Rage With Your Friends

Moderated by  Blink, Hummel, Superku 

Gamestudio download | chip programmers | Zorro platform | shop | Data Protection Policy

oP group Germany GmbH | Birkenstr. 25-27 | 63549 Ronneburg / Germany | info (at) opgroup.de

Powered by UBB.threads™ PHP Forum Software 7.7.1