I'm trying to write an SSAO shader, basically by converting an OpenGL shader, but as we all know I'm not great with shaders. I need a depth texture for the SSAO to work, so I decided to try to create one in a separate pass (initially; I'll attempt to optimise later), but I just cannot get it to work.
As far as I can see, this shader should work fine for rendering a depth map to the screen....I don't know why it's not. It's just black. I can set the pixel shader's output to constants and make it render a solid colour, but it refuses to render the depth.
Any pointers?
// Based off www.gamerendering.com/2009/01/14/ssao/
//
static const float strength = 0.125;
static const float2 offset = float2( 1920.0 / 4.0, 1080.0 / 4.0 );
static const float falloff = 0.0000002;
static const float rad = 0.006;
float4x4 matWorld : World; //World and WVP are DBPro-specific semantics
float4x4 matWorldView : WorldView;
float4x4 matWorldViewProjection : WorldViewProjection;
float4x4 matViewProjection : ViewProjection;
#define NUM_SAMPLES 10
static const float invSamples = 1.0 / (float)NUM_SAMPLES;
// AO sampling directions
static const float3 AO_SAMPLES[ NUM_SAMPLES ] =
{
float3(-0.010735935, 0.0164701800, 0.0062425877),
float3(-0.065333690, 0.3647007000, -0.1374632100),
float3(-0.653923500, -0.0167263880, -0.5300095700),
float3( 0.409582850, 0.0052428036, -0.5591124000),
float3(-0.146536600, 0.0989926700, 0.1557167900),
float3(-0.441221120, -0.5458797000, 0.0491253200),
float3( 0.037555660, -0.1096134500, -0.3304027300),
float3( 0.019100213, 0.2965278300, 0.0662376660),
float3( 0.876532300, 0.0112360040, 0.2826596200),
float3( 0.292644350, -0.4079423800, 0.1596416700)
};
// Textures.
//
//Texture tex0; // Normal.xyz, z/w
//Texture tex1; // Random noise texture
texture frame : RENDERCOLORTARGET
<
string ResourceName = "";
float2 ViewportRatio = {1.0,1.0 };
>;
texture normDepth : COLORTARGET
<
string ResourceName="";
float2 ViewportRatio={1.0,1.0};
>;
sampler2D frameSamp=sampler_state
{
Texture=<frame>;
MinFilter=Linear; MagFilter=Linear; MipFilter=Linear;
AddressU=Clamp; AddressV=Clamp;
};
sampler2D normDepthSamp=sampler_state
{
Texture=<normDepth>;
MinFilter=Linear; MagFilter=Linear; MipFilter=Linear;
AddressU=Clamp; AddressV=Clamp;
};
/*
sampler2D defss0=sampler_state //normal=xyz and depth=w
{
//Filter = MIN_MAG_MIP_LINEAR;
MinFilter = Linear; MagFilter = Linear; MipFilter = Linear;
AddressU = Clamp;
AddressV = Clamp;
};
sampler2D defss1=sampler_state //random noise tex
{
//Filter = MIN_MAG_MIP_POINT;
MinFilter = Point; MagFilter = Point; MipFilter = Point;
AddressU = Wrap;
AddressV = Wrap;
};
*/
//--------------------
// PASS 0
//--------------------
struct VSInput0
{
float4 pos : POSITION;
float3 norm : NORMAL;
float uv : TEXCOORD0;
};
struct VSOutput0
{
float4 pos : POSITION; //xyz normal w depth
//float4 normDepth : TEXCOORD0;
float depth : TEXCOORD0;
};
VSOutput0 VSPass0(VSInput0 input)
{
VSOutput0 output;
float4 depth=mul(input.pos,matWorldViewProjection);
output.pos=input.pos;
output.depth=depth.z/depth.w;
//output.normDepth.w=depth.z/depth.w;
//output.normDepth.xyz=mul(input.norm,(float3x3)matWorldView);
return output;
}
float4 PSPass0(VSOutput0 input) : COLOR
{
//return float4(input.normDepth.w,input.normDepth.w,input.normDepth.w,1);
return float4(input.depth,input.depth,input.depth,1);
}
//--------------------
// PASS 1
//--------------------
struct VSInput1
{
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};
struct VSOutput1
{
float4 pos : POSITION;
float2 uv : TEXCOORD0;
};
/*
VSOutput1 VSPass1(VSInput1 input)
{
VSOutput1 output;
output.pos=input.pos;
output.uv=input.uv;
return output;
}
float4 PSPass1(VSOutput1 input) : COLOR
{
float3 fres = normalize( tex2D( defss1, input.uv * offset ).xyz * 2.0 - 1.0 );
float4 normal_depth = tex2D( defss0, input.uv );
float3 normal = normal_depth.xyz;
float depth = normal_depth.w;
float3 ep = float3( input.uv, depth );
float bl = 0.0;
float radD = rad / depth;
float3 ray;
float4 occFrag;
float depthDiff;
for( int i = 0; i < NUM_SAMPLES; ++i )
{
ray = radD * reflect( AO_SAMPLES[i], fres );
occFrag = tex2D(defss0, ep.xy + sign(dot(ray, normal)) * ray.xy);
depthDiff = depth - occFrag.a;
bl += step( falloff, depthDiff ) * (1.0 - dot( occFrag.xyz, normal )) *
(1.0 - smoothstep( falloff, strength, depthDiff ));
}
float ao = 1.0 - bl * invSamples;
return float4( ao, ao, ao, 1.0 );
}
*/
technique MainTechnique
<
//specify where we want the original image to be put
string RenderColorTarget="frame";
>
{
pass DepthMap
<
string RenderColorTarget="";
>
{
VertexShader = compile vs_3_0 VSPass0();
PixelShader = compile ps_3_0 PSPass0();
}
//pass Final
//{
// VertexShader = compile vs_3_0 VSPass1();
// PixelShader = compile ps_3_0 PSPass1();
//}
}
EDIT: Hangon, here's a more distilled version without all the commented SSAO code...purely depth rendering in this one (still doesn't work):
float4x4 matWorld : World; //World and WVP are DBPro-specific semantics
float4x4 matWorldView : WorldView;
float4x4 matWorldViewProjection : WorldViewProjection;
float4x4 matViewProjection : ViewProjection;
texture frame : RENDERCOLORTARGET
<
string ResourceName = "";
float2 ViewportRatio = {1.0,1.0 };
>;
texture normDepth : COLORTARGET
<
string ResourceName="";
float2 ViewportRatio={1.0,1.0};
>;
sampler2D normDepthSamp=sampler_state
{
Texture=<normDepth>;
MinFilter=Linear; MagFilter=Linear; MipFilter=Linear;
AddressU=Clamp; AddressV=Clamp;
};
//--------------------
// PASS 0
//--------------------
struct VSInput0
{
float4 pos : POSITION;
float3 norm : NORMAL;
float uv : TEXCOORD0;
};
struct VSOutput0
{
float4 pos : POSITION; //xyz normal w depth
//float4 normDepth : TEXCOORD0;
float depth : TEXCOORD0;
};
VSOutput0 VSPass0(VSInput0 input)
{
VSOutput0 output;
float4 depth=mul(input.pos,matWorldViewProjection);
output.pos=input.pos;
output.depth=depth.z/depth.w;
//output.normDepth.w=depth.z/depth.w;
//output.normDepth.xyz=mul(input.norm,(float3x3)matWorldView);
return output;
}
float4 PSPass0(VSOutput0 input) : COLOR
{
//return float4(input.normDepth.w,input.normDepth.w,input.normDepth.w,1);
return float4(input.depth,input.depth,input.depth,1);
}
technique MainTechnique
<
string RenderColorTarget="frame";
>
{
pass DepthMap
<
string RenderColorTarget="";
>
{
VertexShader = compile vs_3_0 VSPass0();
PixelShader = compile ps_3_0 PSPass0();
}
}