0

I have tried to add refraction to raytracer (javascript) from my textbook. But I have problem whith my sphere which should be transparent but is black, and every try to fix it didn't work.

Below is image what my raytracer looks like on canvas and my raytracer's code:

Image pf my spheres

and below is my code

// A Sphere.
var Sphere = function(center, radius, color, specular, reflective, refractive, refractive_index) {
  this.center = center;
  this.radius = radius;
  this.color = color;
  this.specular = specular;
  this.reflective = reflective;
  this.refractive = refractive;
  this.refractive_index = refractive_index;  // add this
}

// Your spheres
var spheres = [new Sphere([0, -1, 3], 1, [255, 0, 0], 500, 0.2, false, 1.0),  // last two parameters are refractive and refractive_index
           new Sphere([2, 0, 4], 1, [0, 0, 255], 500, 0.3, false, 1.0),
           new Sphere([-2, 0, 4], 1, [0, 255, 0], 10, 0.4, true, 1.5),  // make this sphere transparent with refractive index 1.5
           new Sphere([0, -5001, 0], 5000, [255, 255, 0], 1000, 0.5, false, 1.0)];

// Traces a ray against the set of spheres in the scene.
var TraceRay = function(origin, direction, min_t, max_t, depth) {
  var intersection = ClosestIntersection(origin, direction, min_t, max_t);
  if (!intersection) {
    return background_color;
  }

  var closest_sphere = intersection[0];
  var closest_t = intersection[1];

  var point = Add(origin, MultiplySV(closest_t, direction));
  var normal = Subtract(point, closest_sphere.center);
  normal = MultiplySV(1.0 / Length(normal), normal);

  var view = MultiplySV(-1, direction);
  var lighting = ComputeLighting(point, normal, view, closest_sphere.specular);
  var local_color = MultiplySV(lighting, closest_sphere.color);

  if (depth <= 0) {
    return local_color;
  }

  var reflected_color = [0, 0, 0];
  if (closest_sphere.reflective > 0) {
    var reflected_ray = ReflectRay(view, normal);
    reflected_color = TraceRay(point, reflected_ray, EPSILON, Infinity, depth - 1);
  }

  var refracted_color = [0, 0, 0];
  if (closest_sphere.refractive) {
    var refracted_ray = RefractRay(view, normal, closest_sphere.refractive_index);  // you need to implement this
    refracted_color = TraceRay(point, refracted_ray, EPSILON, Infinity, depth - 1);
  }

  return Add(MultiplySV(1 - closest_sphere.reflective - closest_sphere.refractive, local_color),
             Add(MultiplySV(closest_sphere.reflective, reflected_color),
                 MultiplySV(closest_sphere.refractive, refracted_color)));
}

Edit: since I can't upload my full code here, you can find it on https://pastebin.com/gUhYCUkz

Spektre
  • 49,595
  • 11
  • 110
  • 380
  • @Cerbrus It is here now, I needed to refactor it to terms of stackoverlow – user779537 Jun 26 '23 at 10:10
  • I do not see `RefractRay` and too lazy too look in outside SO/SE link . Check this out: [Reflection and refraction impossible without recursive ray tracing?](https://stackoverflow.com/a/45140313/2521214) its a proof of concept you just need to add vector version of Snell's law into it (was too lazy to add it yet) so you need intersection point, surface normal and ray direction from that you compute refracted ray (similar to rerflect) you just scale perpendicular part to surface normal by `n1/n2` no need for goniometrics ... simple dot product will do – Spektre Jun 27 '23 at 07:04

0 Answers0