I have been working on recreating some of the scenes from Peter Shirley's raytracing books using compute shaders and the new Metal raytracing API. It is going well but I am having some trouble with the glass material.
I've read Pete's blog post on this - http://psgraphics.blogspot.com/2020/04/deugging-refraction-in-sphre.html
But I am still unsure as to what is the cause of the issue that you can see in the pictures I have attached.
The glass appears grainy and you get an effect similar to z-fighting when you move the camera around.
This is the code for the glass material:
else if (instances.materials[instanceIndex] == glass)
{
bool front_face = dot(normalize(ray.direction), worldSpaceSurfaceNormal) < 0.0 ? true : false;
float kEtaRatio = front_face ? kEtaAir / kEtaGlass
: kEtaGlass / kEtaAir;
ray.origin = worldSpaceIntersectionPoint;
ray.direction = refract(normalize(ray.direction), worldSpaceSurfaceNormal, kEtaRatio);
}
I have implemented all the code for the full material with Schlick approximation etc, however it appears that it is this first step shown here that is causing the issue.
I am only using one sample per pixel at the moment but I'm unsure why that would only cause problems with the glass and not the other materials?
Any advice would be greatly appreciated.
worldSpaceSurfaceNormal * 1e-3f
to the worldSpaceIntersectionPoint when updating the ray origin to avoid re-intersecting the same triangle again. This worked well for the diffuse and metallic materials but failed completely for the glass. I just realised after your comment about it being spawned inside of the sphere that I should instead subtract this epsilon value and now it is working great! $\endgroup$