Well, I had been working on improving the scene representation, and I managed to increase performance by about 20% - 25% with just a 3 % increase in memory usage and a small increase in the GBuffer stage, but I believe I could tune it up to 30% - 35%. Also now reflections take into account the sky, and I added specular lighting to the GI calculation.
I'm having a problem though, and I wanted to ask you guys. I can't get the blur to work correctly. I'm implementing a Gaussian blur, separated on two passes, with the weights calculated on the fly, as I like to be able to tune the number of samples of the filter. Also, the Gaussian weight is multiplied by 1 / (epsilon + abs(z - depth[sample])) to take into account depth discontinuities. It works, but instead of producing a nice smooth blur, it creates a black cross in the middle. Below is a screen. Rays where reduced to 1 per pixel and strength upped to better display the problem. The blur is using 8 samples and a sigma of 4.3.
And here is the code for the horizontal pass. The vertical one is exactly the same, changing float2(1, 0) for float2(0, 1). I read two images, do the horizontal blur to two temp images, do the vertical blur sampling the temp images, and output to the original images.
Texture2D<float> tCoarseDepth : register(t0);
Texture2D<float4> tCoarseNormal : register(t1);
Texture2D<float4> tGI : register(t2);
Texture2D<float4> tRFL : register(t3);
RWTexture2D<float4> output : register(u0);
RWTexture2D<float4> outputRFL : register(u1);
static const float samples = 8;
static const float g_epsilon = 0.0001f;
static const float sigma = 4.3f * 4.3f;
[numthreads(256, 1, 1)]
void BlurH( uint3 DTid : SV_DispatchThreadID )
{
float z = tCoarseDepth[DTid.xy];
float4 gi = tGI[DTid.xy];
float4 rfl = tRFL[DTid.xy];
float acc = 1;
float2 spos = float2(1, 0);
for (float i = 1; i <= samples; i++)
{
// Sample right
// Calculate weights
float zWeightR = 1.0f / (g_epsilon + abs(z - tCoarseDepth[DTid.xy + spos*i]));
float WeightR = zWeightR * GaussianWeight(i, sigma);
// Sample
gi += tGI[DTid.xy + spos*i]* WeightR;
rfl += tRFL[DTid.xy + spos*i] * WeightR;
acc += WeightR;
// Sample left
// Calculate weights
float zWeightL = 1.0f / (g_epsilon + abs(z - tCoarseDepth[DTid.xy - spos*i]));
float WeightL = zWeightL * GaussianWeight(i, sigma);
// Sample
gi += tGI[DTid.xy - spos*i] * WeightL;
rfl += tRFL[DTid.xy - spos*i] * WeightL;
acc += WeightL;
}
output[DTid.xy] = gi / acc;
outputRFL[DTid.xy] = rfl / acc;
}
If someone can shed some light, I would be grateful.
There's other thing I want / need to add to my blur shader, and that is to take into account the distance of the pixel, so everything gets the same amount of blur. Right now, things that are too far get too much blur, and things that are to close don't get enough.
I need suggestion on how to do that, I suppose someone here has done it before.
Well, that's it for now, I'll try to keep this thread with some more regular updates, maybe a screen every two or three days.
EDIT: Here's the code for the GaussianWeight function
float GaussianWeight(float x,float sigmaSquared)
{
float alpha = 1.0f / sqrt(2.0f * 3.1416f * sigmaSquared);
float beta = (x*x) / (2*sigmaSquared);
return alpha*exp(-beta);
}