AiMakeRay() is able to properly set the ray direction derivatives (ray->dDdx and ray->dDdy) for reflection rays, but since it is not given the indices of refraction, it cannot correctly compute the derivatives for refraction rays. Instead, it just passes on the previous ray derivatives. This will result in worse texture quality and performance as the textures might end up overly blurred or aliased. In order to compute the proper ray derivatives, after AiMakeRay() is called, AiRefractRay() should be called which will compute the correct ray derivatives in addition to also computing the refracted ray direction.
Here's how we use this in the standard shader:
AtRay ray; AiMakeRay(&ray, AI_RAY_REFRACTED, &sg->P, NULL, AI_BIG, sg); const bool refracted = AiRefractRay(&ray, &sg->Nf, n1, n2, sg); AiTrace(&ray, &sample);
Here is a simple example of what using AiRefractRay() provides. This was rendered with 2 AA_samples and where each sphere is a refractive material. The amount of texture data read in is listed below the rendered image:
With AiRefractRay(), we have the correct ray derivatives and so are able to read from the correct texture mipmap level. This allows us to both remove the aliasing seen in the refracted textures through the spheres and cut down substantially on texture data read in. This should make it quite clear why it is important to use AiRefractRay() when casting refraction rays!
Note that in the case of reflection rays, AiMakeRay() is able to compute the correct reflection derivatives, so it is not necessary to call AiReflectRay().
Here is a simple example for what using AiRefractRay() provides. This was rendered with 2 AA_samples and where each sphere is a refractive material. The amount of texture data read in is listed below the rendered image: