# Tiled deferred rendering frustum calculation problem

I know there are plenty of tutorials how to create tiled frustum with compute shaders, but Im trying to understand the steps and want to build it on the cpu with pure C# code.

I translated a lof of Intels approach (which can be found at intels post: Deferred Rendering for Current and Future Rendering Pipelines, sorry I have to earn more reputation to link this) to c# code, which was a kinda hard work because I am not familiar with compute shaders.

So now I got some problems with the algorithm.

1. A single light is contained by a lot of tiles, even if the AttenuationEnd(or sphere radius) of the light is set < 0,1. It seems to have no effect. (the image below shows the rays of each tile with light info)

White: Tiles with no light | Red: Tiles with light 2. I dont get right results if calculating a frustum ray from its corners. The following image shows the partially rendered (from 5 to 5.1) rays with origin at 0, 0, 0. Shouldnt there be more space between each tile at 70 degree fov? This is the code Im using. I commented out a lof of stuff, also with debug info, if possible.

        vec4[] frustumPlanes = new vec4;

// There is 1 light with following properties:
// Position       : 5, 5, 5
// AttenuationEnd : 0.1 (should fit inside some frusta)

// Use a simple 70 fov (70 / 180 * PI) perspective setup.
// width = 486
// height = 279
// near = 0.1
// far = 10
mat4 projection = scene.Camera.ProjectionMatrix;
int TILES_COUNT = 16;

for (int tX = 0; tX < TILES_COUNT; tX++)
{
for (int tY = 0; tY < TILES_COUNT; tY++)
{
// tileBias lies between 1 and -1, decreases from 1 to -1
vec2 tileBias = new vec2(1 - tX / (TILES_COUNT - 1f), 1 - tY / (TILES_COUNT - 1f)) * 2f - 1f;

vec4 c1 = new vec4(-projection.m00, projection.m01, tileBias.x, projection.m03);
vec4 c2 = new vec4(projection.m10, -projection.m11, tileBias.y, projection.m13);
vec4 c4 = new vec4(projection.m30, projection.m31, 1.0f, projection.m33);
// c1 = { -0.82,     0, 1, 0 }  < 3rd index is tileBias.x for tX = 0
// c2 = {     0, -1.43, 1, 0 }  < 3rd index is tileBias.y for tY = 0
// c3 = {     0,     0, 1, 0 }

frustumPlanes = c4 - c1;
frustumPlanes = c4 + c1;
frustumPlanes = c4 - c2;
frustumPlanes = c4 + c2;

// The following 3rd and 4th index signs confuse me, why +/-?
frustumPlanes = new vec4(0f, 0f, 1f, -0.1f); // near
frustumPlanes = new vec4(0f, 0f, 1f,  10f); // far

// Normalizing corners
for (int i = 0; i < 4; i++)
frustumPlanes[i] *= 1f / frustumPlanes[i].xyz.Length;

// An attempt of converting the frustum into a ray.
vec3 rayDir = frustumPlanes.xyz + frustumPlanes.xyz + frustumPlanes.xyz + frustumPlanes.xyz;
rayDir = rayDir.Normalized;

// Calculates whether a light is inside the frustum
bool anyLightInFrustum = false;
for (int i = 0; i < lights.Count; i++)
{
Light light = lights[i];
vec4 lightPos = new vec4(light.Pos, 1.0f);
bool inFrustum = true;
for (int j = 0; j < 6; j++)
{
float dist = vec4.Dot(frustumPlanes[j], lightPos);
inFrustum = inFrustum && (dist >= -light.AttenuationEnd);
}
if (inFrustum) anyLightInFrustum = true;
}

// Set the color to red, if a light is contained
vec4 color = new vec4(1);
if (anyLightInFrustum)
color.rgb = vec3.UnitX;

// Draws a ray with a range from {4} to {5}, origin at {0, 0, 0}
DrawRayWithColor(tessellator, color, rayDir, 5.0f, 5.1f);
}
}


Maybe some of you can give me some hints for this. Even if I just did a translation mistake.

Try to use tileBias within a range of 0 to 2. You also have to use a cross product of two frustum corners.
For example, vec3 rayDir = vec3.Cross(frustumPlanes.xyz, frustumPlanes.xyz);`.