
Ray lambertRay(hitInfo hit, Ray ray, GPUMaterial mat, inout uint rng_state)
{
	vec3 diffuse_dir = normalize(hit.normal + randomDirection(rng_state));
	vec3 specular_dir = reflect(ray.direction, hit.normal);

	bool is_specular = (mat.metallic >= randomValue(rng_state));

	ray.origin = hit.position + hit.normal * 0.001;
	ray.direction = normalize(mix(diffuse_dir, specular_dir, mat.roughness * float(is_specular)));

	return (ray);
}

Ray dieletricRay(hitInfo hit, Ray ray, GPUMaterial mat)
{
    float	refraction_ratio;
	vec3	unit_direction;

    refraction_ratio = 1.0f / mat.refraction;

	if (dot(ray.direction, hit.normal) > 0.0f)
	{
		hit.normal = -hit.normal;
		refraction_ratio = mat.refraction;
	}

	unit_direction = normalize(ray.direction);
	ray.origin = hit.position + hit.normal * -0.0001f;
	ray.direction = refract(unit_direction, hit.normal, refraction_ratio);
	
    return (ray);
}


Ray newRay(hitInfo hit, Ray ray, inout uint rng_state)
{
    GPUObject	obj;
	GPUMaterial	mat;

	obj = objects[hit.obj_index];
	mat = materials[obj.mat_index];

    if (mat.type == 0)
        return (lambertRay(hit, ray, mat, rng_state));
    else if (mat.type == 1)
        return (dieletricRay(hit, ray, mat));
    return (ray);
}