#include "RayTypes.h"

StructuredBuffer<Sphere> Spheres : register(t0, space0);
StructuredBuffer<SphereRay> Rays : register(t1, space0);
StructuredBuffer<SphereHit> Hits : register(t2, space0);
RWStructuredBuffer<SphereRay> SecondariesReflection : register(u0, space1);
RWStructuredBuffer<SphereRay> SecondariesForward : register(u1, space1);

cbuffer UBO : register(b0, space2)
{
    int4 ubo_size : packoffset(c0);
    int spheresCount : packoffset(c1.x);
};


[numthreads(64, 1, 1)]
void main(uint3 GlobalInvocationID : SV_DispatchThreadID)
{
    uint n = GlobalInvocationID.x;

    SphereRay ray = Rays[n];
    SphereHit hit = Hits[n];

    if (hit.SphereId < spheresCount)
    {
        float3 heading = ray.Heading.xyz;
        float3 spot = ray.Position.xyz + heading * hit.RayDistance;
        Sphere sphere = Spheres[hit.SphereId];
        float3 normal = normalize(spot - sphere.PositionAndRadius.xyz);
        float3 reflection = heading - (normal * 2.0 * dot(heading, normal));
        SphereRay sr = (SphereRay)0;
        sr.Position.xyz = spot + reflection * 0.0001;
        sr.Heading.xyz = reflection;
        SecondariesReflection[n] = sr;
        sr = (SphereRay) 0;
        sr.Position.xyz = spot + heading * 0.0001;
        sr.Heading.xyz = heading;
        SecondariesForward[n] = sr;
    }
}
