i was try to get ssao. but get the bad result .please tell me where the wrong is,thank you.
(~~forgive my poor English spelling)
here is the screen shot
ssao: (if i changed some parameters ,the screen divided to 4x4 part)
[attachment=17840:texS.jpg]
normal
[attachment=17838:SN.jpg]
tex
[attachment=17839:tex.jpg]
////////////////////////////////////////////////////////////////
//here is the main ps code:
float4 main(PS_IN pIn):SV_TARGET
{
//view space position
float3 posInView=GetViewPos(pIn.texCoor);
//view space deepth
float deep=posInView.z;
// vectors in a sphere,we get the scaler by deepth
float SphereR=GetSamRadius(deep);
//view space normal,
//(when render to G buffer ,i did not uniform normal to 0.0-1.0)
float3 n=gBuff_1.Sample(Sam_Point_Warp,pIn.texCoor).xyz;
int sampleCount=32;
float ssaoRate=0;
for(int idx=0;idx<sampleCount;++idx)
{
//Get a random vector
float3 ranVec3=randVec[idx];
//reflect the random vector by a noise texture
ranVec3=normalize(RefByNoise(pIn.texCoor,ranVec3));
//flip the vector if it is in the down sphere
if(dot(n,ranVec3)<0)
{
ranVec3=-ranVec3;
}
//scale the vector
ranVec3=ranVec3*SphereR;
//find the pos witch need to be sampled
float3 posForSample=posInView+ranVec3;
//get UV
float2 uvForSample=viewPosToUV(posForSample);
//get Real pos
float3 viewPosInScene=GetViewPos(uvForSample);
ssaoRate+=SSAO(posForSample,viewPosInScene,posInView,SphereR);
}
ssaoRate/=sampleCount;
ssaoRate=1-ssaoRate;
return float4(ssaoRate,ssaoRate,ssaoRate,1);
}
///////////////////////////
here are some decls and functions(in the shader file ,these codes are on the top)
//AOScanDis means the rate of screen wide
//for example : AOScanDis=0.1 ,screen wide=1024 ,we will sample within 102 pixel
float GetSamRadius(float distance)
{
return tanH_FOV*distance*2.0*AOScanDis;
}
float3 GetRefVec3(in float3 ray,in float3 n)
{
return ray-2*n*dot(n,ray);
}
float3 RefByNoise(float2 UV,float3 vec)
{
float2 targUV=(float2) 0;
targUV.x=UV.x*GBufferWH.x/NorTexSize;
targUV.y=UV.y*GBufferWH.y/NorTexSize;
float3 noiseVec=gRefNosize.Sample(Sam_Point_Warp,targUV).xyz*2-1;
return GetRefVec3(vec,noiseVec);
}
float3 GetViewPosFromZ(float2 UV)
{
float p=zBuffer.Sample(Sam_Point_Warp,UV).x;
}
float3 GetViewPos(float2 UV)
{
return gBuff_2.Sample(Sam_Point_Warp,UV).xyz;
}
//convert view pos to uv coord
float2 viewPosToUV(float3 p)
{
//1. convert projection to the plane where z=1
p.xy=p.xy/p.z;
//get half size of wide and height, tanH_FOV=tan(half size of camera horizontal angle)
float w=tanH_FOV;
float h=BackBufferWH.y/BackBufferWH.x*w;
//Get Length rate
p.x=p.x/w;
p.y=p.y/h;
//transform camera xy to texture uv
float2 UV=(float2)0;
UV.x=p.x*0.5+0.5;
UV.y=-p.y*0.5+0.5;
return UV;
}
//1st prama : pos for sample
//2nd: the real view pos
//3rd: center pos
//4th: Radius
float SSAO(float3 pS,float3 pR,float3 pC,float sphereR)
{
if(pS.z>pR.z)
{
float occDis=length(pR-pC);
if(occDis<=AOep)
{
return 0;
}
else
{
return max((1-pow((occDis-AOep)/sphereR,AOIntensity)),0);
}
}
else
{
return 0;
}
}
///////////////////////////////////////////////
cbuffer texPP:register(b1)
{
float2 UVBlurBufferWH;
float2 BackBufferWH;
float2 GBufferWH;
float2 fTimeMtime;
float2 value;
float AOScanDis;
float tanH_FOV;
float AOEp;//if distance less than AOEp ,no AO occured
float AOIntensity;
float NorTexSize;
}
struct PS_IN
{
float4 pos:SV_POSITION;
float2 texCoor:TEXCOORD0;
};
Texture2D gBuff_0 : register( t0 );//Texture
Texture2D gBuff_1 : register( t1 );//Normal
Texture2D gBuff_2 : register( t2 );//Position
Texture2D zBuffer : register( t3 );//Depth
Texture2D gRefNosize: register( t4 );
SamplerState Sam_Point_Warp: register(s0);