Merge refractionshader
This commit is contained in:
commit
55355ad68d
5 changed files with 72 additions and 18 deletions
|
@ -23,9 +23,10 @@ Light::Illumination PointLight::illuminate(Scene const &scene, Ray const &ray) c
|
||||||
// Compute the brightness-color of this light using inverse squared distance
|
// Compute the brightness-color of this light using inverse squared distance
|
||||||
// to light source (i.e. 1/(d^2)), the color of this light source and the
|
// to light source (i.e. 1/(d^2)), the color of this light source and the
|
||||||
// intensity
|
// intensity
|
||||||
if (!inShadow) {
|
if (!inShadow) {
|
||||||
illum.color = (this->intensity / pow(length(this->position - intersectionPoint), 2)) * this->color;
|
illum.color = this->intensity / std::pow(length(this->position - intersectionPoint), 2) * this->color;
|
||||||
}
|
}
|
||||||
|
|
||||||
return illum;
|
|
||||||
|
return illum;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,10 +27,10 @@ bool InfinitePlane::intersect(Ray &ray) const {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Set the normal
|
// Set the normal
|
||||||
if (acos(dotProduct(ray.direction, this->normal)) > 0) {
|
if (std::acos(dotProduct(ray.direction, this->normal)) > 0) {
|
||||||
ray.normal = this->normal;
|
ray.normal = normalized(this->normal);
|
||||||
} else {
|
} else {
|
||||||
ray.normal = -1.0f * this->normal;
|
ray.normal = normalized((-1.0f * this->normal));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -101,7 +101,7 @@ bool Triangle::intersect(Ray &ray) const {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Calculate the normal
|
// Calculate the normal
|
||||||
ray.normal = crossProduct(edge1, edge1);
|
ray.normal = normalized(crossProduct(edge1, edge1));
|
||||||
|
|
||||||
// Calculate the surface position
|
// Calculate the surface position
|
||||||
ray.surface = u * this->surface[1] + v * this->surface[2] + (1 - u - v) * this->surface[0];
|
ray.surface = u * this->surface[1] + v * this->surface[2] + (1 - u - v) * this->surface[0];
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
#include "scene/scene.h"
|
#include "scene/scene.h"
|
||||||
#include "shader/mirrorshader.h"
|
#include "shader/mirrorshader.h"
|
||||||
|
|
||||||
MirrorShader::MirrorShader() {}
|
MirrorShader::MirrorShader() = default;
|
||||||
|
|
||||||
Color MirrorShader::shade(Scene const &scene, Ray const &ray) const {
|
Color MirrorShader::shade(Scene const &scene, Ray const &ray) const {
|
||||||
if (ray.getRemainingBounces() <= 0) {
|
if (ray.getRemainingBounces() <= 0) {
|
||||||
return Color(0, 0, 0);
|
return {0, 0, 0};
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3d newDirection = ray.direction - 2 * dotProduct(ray.normal, ray.direction) * ray.normal;
|
Vector3d newDirection = ray.direction - 2 * dotProduct(ray.normal, ray.direction) * ray.normal;
|
||||||
|
|
||||||
//TODO: should we reset the ray or use a new ray? Regarding the count of bounces
|
|
||||||
Ray mirroredRay = Ray(ray.origin + ray.length * ray.direction, newDirection);
|
Ray mirroredRay = Ray(ray.origin + ray.length * ray.direction, newDirection);
|
||||||
mirroredRay.setRemainingBounces(ray.getRemainingBounces() - 1);
|
mirroredRay.setRemainingBounces(ray.getRemainingBounces() - 1);
|
||||||
|
|
||||||
|
|
|
@ -13,16 +13,70 @@ Color RefractionShader::shade(Scene const &scene, Ray const &ray) const {
|
||||||
if (ray.getRemainingBounces() < 1) {
|
if (ray.getRemainingBounces() < 1) {
|
||||||
return {0,0,0};
|
return {0,0,0};
|
||||||
}
|
}
|
||||||
Vector3d n = ray.normal;
|
|
||||||
float root = std::sqrt(1 - (indexOutside*indexOutside*(1 - dotProduct(ray.direction, n)
|
float eta1 = indexOutside;
|
||||||
*dotProduct(ray.direction, n)))/(indexInside*indexInside));
|
float eta2 = indexInside;
|
||||||
|
|
||||||
Vector3d t = (indexOutside/indexInside)*(ray.direction - dotProduct(ray.direction, n) * n)- n * root;
|
|
||||||
|
|
||||||
Ray reflectionRay = Ray(ray.origin + ray.length * ray.direction, t);
|
Vector3d v = normalized(ray.direction);
|
||||||
reflectionRay.setRemainingBounces(ray.getRemainingBounces()-1);
|
Vector3d n = normalized(ray.normal);
|
||||||
|
|
||||||
return scene.traceRay(reflectionRay);
|
// Check whether we are entering or leaving the object
|
||||||
|
if (dotProduct(v, n) > 0) {
|
||||||
|
eta1 = indexInside;
|
||||||
|
eta2 = indexOutside;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate refraction percentage
|
||||||
|
float denominator = 1.0f -
|
||||||
|
(std::pow(eta1, 2) * (1 - std::pow(dotProduct(v, n), 2)) /
|
||||||
|
std::pow(eta2, 2));
|
||||||
|
|
||||||
|
// Check whether there is any refracted ray at all or whether we have total internal reflection
|
||||||
|
if (denominator <= 0) {
|
||||||
|
Vector3d newDirection = v - 2.0f * dotProduct(n, v) * n;
|
||||||
|
|
||||||
|
Ray mirroredRay = Ray(ray.origin + ray.length * v, newDirection);
|
||||||
|
mirroredRay.setRemainingBounces(ray.getRemainingBounces() - 1);
|
||||||
|
|
||||||
|
return scene.traceRay(mirroredRay);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate refracted ray direction t
|
||||||
|
Vector3d t = normalized(
|
||||||
|
eta1 / eta2 *
|
||||||
|
(v - dotProduct(v, n) * n) -
|
||||||
|
n * std::sqrt(denominator));
|
||||||
|
|
||||||
|
// Calculate reflected ray direction
|
||||||
|
Vector3d cosTheta1 = crossProduct(v, n);
|
||||||
|
Vector3d cosTheta2 = -1.0f * crossProduct(n, t);
|
||||||
|
|
||||||
|
Vector3d polarizationParallel = (eta2 * cosTheta1 - eta1 * cosTheta2) /
|
||||||
|
(eta2 * cosTheta1 + eta1 * cosTheta2);
|
||||||
|
Vector3d polarizationOrthogonal = (eta1 * cosTheta1 - eta2 * cosTheta2) /
|
||||||
|
(eta1 * cosTheta1 + eta2 * cosTheta2);
|
||||||
|
|
||||||
|
Vector3d reflectionVector = normalized(
|
||||||
|
0.5f * (polarizationParallel * polarizationParallel + polarizationOrthogonal * polarizationOrthogonal));
|
||||||
|
|
||||||
|
// Calculate rays
|
||||||
|
Vector3d rayOrigin = ray.origin + ray.length * ray.direction;
|
||||||
|
Ray refractionRay = Ray(rayOrigin, t);
|
||||||
|
Ray reflectionRay = Ray(rayOrigin, reflectionVector);
|
||||||
|
|
||||||
|
int remainingBounces = ray.getRemainingBounces() - 1;
|
||||||
|
|
||||||
|
refractionRay.setRemainingBounces(remainingBounces);
|
||||||
|
reflectionRay.setRemainingBounces(remainingBounces);
|
||||||
|
|
||||||
|
// Calculate Color
|
||||||
|
Color refractionColor = scene.traceRay(refractionRay);
|
||||||
|
Color reflectionColor = scene.traceRay(reflectionRay);
|
||||||
|
|
||||||
|
Color resultingColor = denominator * refractionColor + (1-denominator) * reflectionColor;
|
||||||
|
|
||||||
|
return resultingColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RefractionShader::isTransparent() const { return true; }
|
bool RefractionShader::isTransparent() const { return true; }
|
||||||
|
|
Loading…
Reference in a new issue