DX9.0c HLSL SSAO

Started by
24 comments, last by Bonbon 13 years ago

Can you show us the code in question and tell what line triggers the error ?

Just a guess: SM 2 is rather restrictive in the pixel shader on what you can do with the texcoords before you sample. If hardware allows, check if you can run it with SM 3.


Here's my version of the entire shader, I've also highlighted the line that throws the error. I should also point out I've commented out the use of "* g_intensity; " and I still get the error, however commenting out "max1" instead and I don't get the error.

P.S. Please excuse the poor naming conventions, I've thrown a lot of temporary names around for the purposes of debugging.


texture normalTex;
texture positionTex;
texture randomTex;
float random_size;
float g_sample_rad;
float g_intensity;
float g_scale;
float g_bias;
float2 g_screen_size;

sampler g_buffer_norm : register(s0) = sampler_state
{
Texture = (normalTex);

MinFilter = Linear;
MagFilter = Linear;

AddressU = Clamp;
AddressV = Clamp;
};

sampler g_buffer_pos: register(s0) = sampler_state
{
Texture = (positionTex);

MinFilter = Linear;
MagFilter = Linear;

AddressU = Clamp;
AddressV = Clamp;
};

sampler g_random: register(s0) = sampler_state
{
Texture = (randomTex);

MinFilter = Linear;
MagFilter = Linear;

AddressU = Clamp;
AddressV = Clamp;
};

struct PS_INPUT
{
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);
}

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;
float dot1 = (dot(cnorm,v)-g_bias)*(1.0/(1.0+d));
float max1 = max(0.0, dot1);
return max1*g_intensity; ///<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
}

PS_OUTPUT main(PS_INPUT i)
{
PS_OUTPUT o = (PS_OUTPUT)0;

o.color.rgb = 1.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);
}
ao/=(float)iterations*4.0;
//**END**//

o.color.rgb = ao;
//Do stuff here with your occlusion value “ao”: modulate ambient lighting, write it to a buffer for later //use, etc.
return o;
}

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



Advertisement
Tried it. Funnily the compiler pointed me to different lines. You set the s0 register for all your textures. Change them to e.g. s0, s1, s2. Compiles fine here then. Actually, since you use effect files, you don't need to set them manually.

But my guess still holds. Switching back to SM 2 will give you this:

ssao.fx(56,9): error X5426: Shader uses texture addresssing operations in a dependency chain that is too complex for the target shader model (ps_2_0) to handle

Pity. You definitively hit a SM 2 limit.

Tried it. Funnily the compiler pointed me to different lines. You set the s0 register for all your textures. Change them to e.g. s0, s1, s2. Compiles fine here then. Actually, since you use effect files, you don't need to set them manually.

But my guess still holds. Switching back to SM 2 will give you this:

ssao.fx(56,9): error X5426: Shader uses texture addresssing operations in a dependency chain that is too complex for the target shader model (ps_2_0) to handle

Pity. You definitively hit a SM 2 limit.


Oh man, thanks. Hadn't even realised that I was using the same register.


What exactly is it I'm supposed to do after running the SSAO shader I posted? Right now I'm storing the "ao" value in the R channel, presumably I should write a shader that takes in my scene rendered to a texture and multiples the colour value of each pixel on that by the AO value in the R channel of my SSAO texture?
Quick update, I've fixed some compatibility errors with SM3.0 (code below) and now powering on towards finishing the SSAO. The last remaining error is with ViewSpace positional data. The image in my earlier post is incorrect. I'm now going to have to figure out why. If anyone has any suggestions please share them.

[attachment=1437:cross.png]

The below code produces this, the problem is the position data though. No idea how to fix it. From the last post on this thread (http://archive.gamed...=25&WhichPage=2) I can see the same problem, and then the solution but not an explanation.


texture normalTex;
texture positionTex;
texture randomTex;
texture sceneTexture;
float random_size;
float g_sample_rad;
float g_intensity;
float g_scale;
float g_bias;
float2 g_screen_size;

sampler g_buffer_norm : register(s0) = sampler_state
{
Texture = (normalTex);

//MinFilter = Linear;
//MagFilter = Linear;

//AddressU = Clamp;
//AddressV = Clamp;
};

sampler g_buffer_pos : register(s1) = sampler_state
{
Texture = (positionTex);

//MipFilter = LINEAR;
//MinFilter = LINEAR;
//MagFilter = LINEAR;

//AddressU = Clamp;
//AddressV = Clamp;
};

sampler g_random : register(s2) = sampler_state
{
Texture = (randomTex);

//MinFilter = Linear;
//MagFilter = Linear;

//AddressU = Clamp;
//AddressV = Clamp;
};

sampler sceneSampler : register(s3) = sampler_state
{
Texture = (sceneTexture);

//MinFilter = Linear;
//MagFilter = Linear;

//AddressU = Clamp;
//AddressV = Clamp;
};

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

struct PS_OUTPUT
{
float4 color : COLOR;
};

float3 getPosition(in float2 uv)
{
//vec3 point = vec3(uv.x * in_FarPlaneWidth - HalfWidth, uv.y * in_FarPlaneHeight - HalfHeight, -in_FarPlane) * texture(Buffer0, uv).w;
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);
}

float doAmbientOcclusion(float2 tcoord , float2 uv, float3 p, 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;
}


PS_INPUT AOVertexShader(float4 position : POSITION0, float2 TexCoord : TEXCOORD0)
{
PS_INPUT o = (PS_INPUT)0;

o.pos = position;
o.uv = TexCoord;

return o;
}

PS_OUTPUT AOPixelShader(PS_INPUT i)
{
PS_OUTPUT o = (PS_OUTPUT)0;

o.color.rgb = 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;

//float finalColor = 0.0f;

//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);
}
ao/=(float)iterations*4.0;
//END

//o.color.rgb = ao;

float4 finalColor = tex2D(sceneSampler, i.uv);

finalColor.xyz *= ao;

o.color = finalColor;

//o.color.rgb = ao;

//Do stuff here with your occlusion value “ao”: modulate ambient lighting, write it to a buffer for later //use, etc.
return o;
}

technique SSAO
{
pass P0
{
VertexShader = compile vs_3_0 AOVertexShader();
PixelShader = compile ps_3_0 AOPixelShader();
}
}
Got a quick update, I have it working!

Given the difficulty I had getting it working I intend on writing a tutorial which details the process I went through. However given the nature of my project I can't write a tutorial until my thesis has been finished and graded. So I won't be able to do this until late May.

Thanks very much for your help everyone. =D

P.S. Sorry for anyone looking for details on what I did to fix it. I will provide details later.

Thanks. I look forward to reading your tutorial. Congratulations and good luck with your thesis.
Hey guys, resurrecting this thread as not to clutter the forums. One small problem that I've been unable to squash since the process sprang to live. On the lower right corner of my SSAO output texture I can see a strange linear artifact. I've included a couple of images that demonstrate the problem. If anyone's seen this, and knows a solution then I'd appreciate it.

P.S. There's also a self occlusion problem in the images, this has since been resolved.

[attachment=1638:example1.PNG]
[attachment=1639:example2.PNG]
Hello Davidc14,

I'm glad to see that someone has had problems but got out with good results in the end. I have been trying to follow the steps that you have gone through but unfortunatley I'm still having issues myself and was wondering whether you had encountered them.
I have attached the results I'm getting at the moment. Strangley, the model is completely black until zoomed in, and then when you move the cam around the results change.

There are a couple things I'm a little confused about. When you are rendering your position and normal textures, do you create a projection matrix that fits to the texture dimensions, or do you leave it as is.

Any help would be greatly appreciated and if you need any more info I'll gladly provide it.

thanks
Hello,

Still having problems here
Attached are two pics rendering my final output from the SSAO shader, the second zoomed in slightly on the model. It seems there is some kind of wrapping going on with my output.
Can anyone deduce the problem that I'm having as I'm at abit of a loss?

Thanks

This topic is closed to new replies.

Advertisement