2

I am currently implementing a custom ray tracing renderer and I am stick with problem of direct illumination Here my result :

normalOnLight enter image description here

sphereNormal enter image description here

max(normalOnLight.dot(sphereNormal), 0.0) enter image description here

I do not understand the last result, i think the first and the second are right but not the last (the dot..) the light is a point light.

    const Vec4<double> LambertianSampler::radiance(const Ray& ray, const Scene& scene) const
  {
     Context ctx;
     ctx.setCamtoWorld(scene.getCamera()->getLookAt());
     Vec4<double> maxColor(1.0, 1.0, 1.0, 1.0);
     Vec4<double> ambient(0.4, 0.4, 0.4, 1.0);

     Vec4<double> finaleRadiance = ambient;
     for(const auto & light : scene.getLights())
     {
       for(const auto & shape : scene.getShapes())
       {
          shape->intersect(ray, ctx);
       }

      if(ctx.intersectionFound())
      {
      Vec3<double> lightPosition = light->getPos();
      Vec4<double> lightColor    = light->getRadiance();
      Vec3<double> lightNormal   = ctx.getPoint() - lightPosition;
      lightNormal = Vec3<double>(std::fabs(lightNormal.x()), std::fabs(lightNormal.y()), std::fabs(lightNormal.z()));
      lightNormal.normalize();

      Vec3<double> sphereNormal = ctx.getNormal();
      sphereNormal   = Vec3<double>(std::fabs(sphereNormal.x()), std::fabs(sphereNormal.y()), std::fabs(sphereNormal.z())) ;
      sphereNormal.normalize();

      double dot     = lightNormal.dot(sphereNormal);
      finaleRadiance = maxColor*std::max(0.0,dot);
      finaleRadiance = Vec4<double>(finaleRadiance.x(), finaleRadiance.y(), finaleRadiance.z(), 1.0);

      //finaleRadiance = Vec4<double>(sphereNormal.x(), sphereNormal.y(), sphereNormal.z(), 1.0);
      //finaleRadiance = Vec4<double>(lightNormal.x(), lightNormal.y(), lightNormal.z(), 1.0);

    }
  }
  return finaleRadiance;
}

Do my dot result is right ? because i think my lightNormalOnSphere and sphereNormal are right i think ..

Benzait Sofiane
  • 107
  • 1
  • 12

2 Answers2

1

I fix my problem by remplace the :

lightNormal = Vec3<double>(std::fabs(lightNormal.x()), std::fabs(lightNormal.y()), std::fabs(lightNormal.z()));

by

lightNormal = Vec3<double>((lightNormal.x()+1)*0.5, (lightNormal.y()+1)*0.5, (lightNormal.z()+1)*0.5);
Benzait Sofiane
  • 107
  • 1
  • 12
0

The main problem is here:

  Vec3<double> sphereNormal = ctx.getNormal();
  sphereNormal   = Vec3<double>(std::fabs(sphereNormal.x()), std::fabs(sphereNormal.y()), std::fabs(sphereNormal.z())) ;
  sphereNormal.normalize();

But the solution above doesn't seem quite right. First of all, you shouldn't have to re-normalize the sphere normal. The fabs calls are going to change some of the signs, but none of the magnitudes, so the extra normalize is just wasting time.

But why the fabs calls. My guess you added that because the sphere normals seemed to be pointing the wrong direction. Thus, when you took the dot product, you were getting negative values on the light side. You added fabs, which happened to turn all the sphere normals toward the light, even the ones on the dark side. That's why you see the shading beginning, but then the light ramps back up instead of going completely dark.

This also explains why your proposed solution appears to work. You're biasing the normals toward where (I think) you've placed the light.

If my theory is correct, then you need to flip the sphere normals so that they're pointing out rather than into the sphere. A quick way to check is the subtract the center of the sphere from the intersection point, which should give you a vector pointing out, and you can then normalize that. If that doesn't match the sphere normals you're currently computing (specifically, if the signs are all flipped), my theory would be confirmed.

In that case, the solution is just to flip the sphere normal before computing the dot product.

Finally, you're looping over the lights, but using only the contribution from the last light in the list. (It's hard to tell exactly, because you've got some mismatched braces in the question.)

Adrian McCarthy
  • 45,555
  • 16
  • 123
  • 175