material.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. /*
  2. * DoRayMe - a quick and dirty Raytracer
  3. * Material implementation
  4. *
  5. * Created by Manoël Trapier
  6. * Copyright (c) 2020 986-Studio.
  7. *
  8. */
  9. #include <tuple.h>
  10. #include <material.h>
  11. #include <colour.h>
  12. #include <shape.h>
  13. Colour Material::lighting(Light light, Tuple point, Tuple eyeVector, Tuple normalVector, Shape *hitObject,
  14. double lightIntensity)
  15. {
  16. Colour pointColor = this->colour;
  17. if (this->pattern != nullptr)
  18. {
  19. pointColor = this->pattern->patternAtObject(hitObject, point);
  20. }
  21. Tuple lightVector = (light.position - point).normalise();
  22. Tuple reflectVector = Tuple(0, 0, 0, 0);
  23. Tuple effectiveColour = pointColor * light.intensity;
  24. Tuple ambientColour = Colour(0, 0, 0);
  25. Tuple emissiveColour = Colour(0, 0, 0);
  26. Tuple diffuseColour = Colour(0, 0, 0);
  27. Tuple specularColour = Colour(0, 0, 0);
  28. Tuple finalColour = Colour(0, 0, 0);
  29. double lightDotNormal, reflectDotEye;
  30. ambientColour = effectiveColour * this->ambient;
  31. emissiveColour = pointColor * this->emissive;
  32. lightDotNormal = lightVector.dot(normalVector);
  33. if (lightDotNormal < 0)
  34. {
  35. diffuseColour = Colour(0, 0, 0);
  36. specularColour = Colour(0, 0, 0);
  37. }
  38. else
  39. {
  40. diffuseColour = effectiveColour * this->diffuse * lightDotNormal;
  41. reflectVector = -lightVector.reflect(normalVector);
  42. reflectDotEye = reflectVector.dot(eyeVector);
  43. if (reflectDotEye < 0)
  44. {
  45. specularColour = Colour(0, 0, 0);
  46. }
  47. else
  48. {
  49. double factor = pow(reflectDotEye, this->shininess);
  50. specularColour = light.intensity * this->specular * factor;
  51. }
  52. }
  53. diffuseColour = diffuseColour * lightIntensity;
  54. specularColour = specularColour * lightIntensity;
  55. finalColour = emissiveColour + ambientColour + diffuseColour + specularColour;
  56. return Colour(finalColour.x, finalColour.y, finalColour.z);
  57. }
  58. void Material::dumpMe(FILE *fp)
  59. {
  60. fprintf(fp, "\"Colour\": {\"red\": %f, \"green\": %f, \"blue\": %f},\n", this->colour.x, this->colour.y, this->colour.z);
  61. fprintf(fp, "\"Ambient\": %f,\n", this->ambient);
  62. fprintf(fp, "\"Diffuse\": %f,\n", this->diffuse);
  63. fprintf(fp, "\"Specular\": %f,\n", this->specular);
  64. fprintf(fp, "\"Shininess\": %f,\n", this->shininess);
  65. fprintf(fp, "\"Reflective\": %f,\n", this->reflective);
  66. fprintf(fp, "\"Transparency\": %f,\n", this->transparency);
  67. fprintf(fp, "\"Emissive\": %f,\n", this->emissive);
  68. fprintf(fp, "\"RefractiveIndex\": %f,\n", this->refractiveIndex);
  69. if (this->pattern)
  70. {
  71. fprintf(fp, "\"Pattern\": {\n");
  72. this->pattern->dumpMe(fp);
  73. fprintf(fp, "},\n");
  74. }
  75. }