diff options
author | sotech117 <michael_foiani@brown.edu> | 2023-12-07 16:23:20 -0500 |
---|---|---|
committer | sotech117 <michael_foiani@brown.edu> | 2023-12-07 16:23:20 -0500 |
commit | caa765bff49d54217b75aaf0e7acf4e5392a11e4 (patch) | |
tree | 9b92914dfb88b99599e8e60e4512e9e9ea9a25db /src/illuminate/reflect.cpp | |
parent | a9274459443f1d560d7580a162deb581549980cb (diff) |
upload base code
Diffstat (limited to 'src/illuminate/reflect.cpp')
-rw-r--r-- | src/illuminate/reflect.cpp | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/src/illuminate/reflect.cpp b/src/illuminate/reflect.cpp new file mode 100644 index 0000000..c7fea98 --- /dev/null +++ b/src/illuminate/reflect.cpp @@ -0,0 +1,115 @@ +// +// Created by Michael Foiani on 11/4/23. +// + +#include "raytracer/raytracer.h" + +// helper that reflects vectors +glm::vec3 reflectVector( + glm::vec3 incidentDir, + glm::vec3 normal) +{ + return incidentDir - 2.f * glm::dot(incidentDir, normal) * normal; +} + +glm::vec4 RayTracer::reflect( + glm::vec3 intersectionWorld, + glm::vec3 normalWorld, + glm::vec3 incidentDir, + const RenderShapeData &shape, + const RayTraceScene &scene, + int depth) +{ + auto material = shape.primitive.material; + // check if the material is reflective + if (material.cReflective == glm::vec4(0.f)) + { + return glm::vec4(0.f); + } + auto reflectedDir = reflectVector(incidentDir, normalWorld); + + // shoot a ray from the intersection point in the reflected direction + auto reflectColors = getPixelFromRay(glm::vec4(intersectionWorld + .001f * reflectedDir, 1.f), glm::vec4(reflectedDir, 0.f), scene, depth + 1); + return scene.getGlobalData().ks * material.cReflective * reflectColors; +} + +// EXTRA CREDIT -> refracting + +// TRUE REFRACTING +// get the reflection coefficient from fresnel's equations +bool REAL_REFRACTING = false; +float fresnels( + float currentMediumIor, + float otherMediumIor, + float cosAngleIncident, + float cosAngleTransmitted) +{ + float rPerp = (currentMediumIor * cosAngleIncident - otherMediumIor * cosAngleTransmitted) / + (currentMediumIor * cosAngleIncident + otherMediumIor * cosAngleTransmitted); + rPerp *= rPerp; + float rPara = (otherMediumIor * cosAngleIncident - currentMediumIor * cosAngleTransmitted) / + (otherMediumIor * cosAngleIncident + currentMediumIor * cosAngleTransmitted); + rPara *= rPara; + return (rPerp + rPara) / 2.f; +} + +// Your refracting +glm::vec4 RayTracer::refract( + glm::vec3 intersectionWorld, + glm::vec3 normalWorld, + glm::vec3 incidentDir, + const RenderShapeData& shape, + const RayTraceScene &scene, + int depth +) +{ + auto material = shape.primitive.material; + // check if the material is transparent + if (material.cTransparent == glm::vec4(0.f)) + { + return glm::vec4(0.f); + } + + // apply snells law to find the sin of refracted angle (squared) + incidentDir = glm::normalize(incidentDir); + float cosAngleIncident = glm::dot(incidentDir, normalWorld); + float currentMediumIor = mediumIor; + float otherMediumIor = material.ior; + + if (cosAngleIncident < 0) + { + // outside the object + cosAngleIncident = -cosAngleIncident; + } + else + { + // inside the object, invert the normal and swap the Iors + normalWorld = -normalWorld; + std::swap(currentMediumIor, otherMediumIor); + } + + float iorRatio = currentMediumIor / otherMediumIor; + float sinAngleTransmittedSquared = iorRatio * iorRatio * (1 - cosAngleIncident * cosAngleIncident); + if (sinAngleTransmittedSquared > 1.f) // total internal reflection, not considered + { + return glm::vec4(0.f); + } + + auto cosAngleTransmitted = glm::sqrt(1 - sinAngleTransmittedSquared); + + // compute refracted ray according to snell's law + auto refractedDir = glm::normalize( + incidentDir * iorRatio + + (iorRatio * cosAngleIncident - cosAngleTransmitted) * normalWorld); + + // send a ray in the refracted direction to get the colors + auto refractedColors = getPixelFromRay( + glm::vec4(intersectionWorld + .001f * refractedDir, 1.f), + glm::vec4(refractedDir, 0.f), + scene, + depth + 1); + + float fresnel = fresnels(currentMediumIor, otherMediumIor, cosAngleIncident, cosAngleTransmitted); + auto color = scene.getGlobalData().kt * material.cTransparent * refractedColors * (1 - fresnel); + return color; +}
\ No newline at end of file |