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
|
||||
// to light source (i.e. 1/(d^2)), the color of this light source and the
|
||||
// intensity
|
||||
if (!inShadow) {
|
||||
illum.color = (this->intensity / pow(length(this->position - intersectionPoint), 2)) * this->color;
|
||||
}
|
||||
if (!inShadow) {
|
||||
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;
|
||||
|
||||
// Set the normal
|
||||
if (acos(dotProduct(ray.direction, this->normal)) > 0) {
|
||||
ray.normal = this->normal;
|
||||
if (std::acos(dotProduct(ray.direction, this->normal)) > 0) {
|
||||
ray.normal = normalized(this->normal);
|
||||
} 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;
|
||||
|
||||
// Calculate the normal
|
||||
ray.normal = crossProduct(edge1, edge1);
|
||||
ray.normal = normalized(crossProduct(edge1, edge1));
|
||||
|
||||
// Calculate the surface position
|
||||
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 "shader/mirrorshader.h"
|
||||
|
||||
MirrorShader::MirrorShader() {}
|
||||
MirrorShader::MirrorShader() = default;
|
||||
|
||||
Color MirrorShader::shade(Scene const &scene, Ray const &ray) const {
|
||||
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;
|
||||
|
||||
//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);
|
||||
mirroredRay.setRemainingBounces(ray.getRemainingBounces() - 1);
|
||||
|
||||
|
|
|
@ -13,16 +13,70 @@ Color RefractionShader::shade(Scene const &scene, Ray const &ray) const {
|
|||
if (ray.getRemainingBounces() < 1) {
|
||||
return {0,0,0};
|
||||
}
|
||||
Vector3d n = ray.normal;
|
||||
float root = std::sqrt(1 - (indexOutside*indexOutside*(1 - dotProduct(ray.direction, n)
|
||||
*dotProduct(ray.direction, n)))/(indexInside*indexInside));
|
||||
|
||||
float eta1 = indexOutside;
|
||||
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);
|
||||
reflectionRay.setRemainingBounces(ray.getRemainingBounces()-1);
|
||||
Vector3d v = normalized(ray.direction);
|
||||
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; }
|
||||
|
|
Loading…
Reference in a new issue