With attempt #3529 on G.I. I tried to store light data (as voxels) in 3D-textures and raycast through them in several ways. It "works", but in order to keep it realtime, I need to reduce the raycasting loops as little as possible. Less voxels, short-range rays, less rays... All in all, the quality suffers and its still pretty damn slow. To give an idea what's going on:
// for ~25.000 voxels (rendered as points into a 64x64x64 3D texture)
// the fragment shader sends out 9 rays in several directions, to see where they collide with
// the environment (stored as SH values into another 64x64x64 3D texture)
for (int i=0; i < RAYCOUNT; i++)
{
float3 direction = RAY_DIR[i];
float3 rayPos = startPos;
// Check where the ray hits a surface
while !occluded && steps++ < 25
{
rayPos += direction * stepsize;
float4 occl = tex3D( shTexOccl, rayPos );
// decode Spherical Harmonics, and check if we collided
...
}
// Get GI data from ray end position
...
}
The raycasts are killing here. But at the same time, other effects that test rays over 2D textures don't seem to be very slow (RLR reflections for example can easily do hundreds of checks per pixel over a fullscreen image)...- Is tex3D really that slow?
- Or is it just because the rays fly in all directions, making it very hard for the GPU to do things in parallel / texture caching?
- And/or is the loop coded in a dumb way?
Of course, there are multiple ways to store data. I could splat down everything into a 2D texture, or put it in a buffer for example. Not figured out how Crassin exactly stored his Voxel Octrees for techniques like "Voxel Cone Tracing", but it seems to be a mixture of 3D textures, data-buffers, and moreover, fast enough to achieve awesome things in realtime... Any hints on effective raytracing on a GPU?
Cheers,
Rick






