WIP reflection implementation
This commit is contained in:
parent
b2788a2291
commit
1d7e01f424
4 changed files with 66 additions and 13 deletions
|
@ -28,9 +28,9 @@ bool InfinitePlane::intersect(Ray &ray) const {
|
|||
|
||||
// Set the normal
|
||||
if (acos(dotProduct(ray.direction, this->normal)) > 0) {
|
||||
ray.normal = this->normal;
|
||||
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];
|
||||
|
|
|
@ -5,12 +5,11 @@ MirrorShader::MirrorShader() {}
|
|||
|
||||
Color MirrorShader::shade(Scene const &scene, Ray const &ray) const {
|
||||
if (ray.getRemainingBounces() <= 0) {
|
||||
return Color(0, 0, 0);
|
||||
return Color(0, 255, 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);
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include <iostream>
|
||||
#include "scene/scene.h"
|
||||
#include "shader/refractionshader.h"
|
||||
|
||||
|
@ -11,19 +12,72 @@ Color RefractionShader::shade(Scene const &scene, Ray const &ray) const {
|
|||
// Send out a new refracted ray into the scene; recursively call traceRay()
|
||||
|
||||
if (ray.getRemainingBounces() < 1) {
|
||||
return Color(0,0,0);
|
||||
return Color(0,255,0);
|
||||
}
|
||||
|
||||
auto eta1 = indexOutside;
|
||||
auto eta2 = indexInside;
|
||||
|
||||
|
||||
Vector3d v = normalized(ray.direction);
|
||||
Vector3d n = normalized(ray.normal);
|
||||
|
||||
// Check whether we are entering or leaving the object
|
||||
if (acos(dotProduct(v, n)) < PI/2.0f) {
|
||||
eta1 = indexInside;
|
||||
eta2 = indexOutside;
|
||||
}
|
||||
|
||||
Vector3d n = ray.normal;
|
||||
double root = sqrt(1 - (indexOutside*indexOutside*(1 - dotProduct(ray.direction, n)
|
||||
*dotProduct(ray.direction, n)))/(indexInside*indexInside));
|
||||
// Calculate refraction percentage
|
||||
float denominator = 1.0f -
|
||||
(pow(eta1, 2) * (1 - pow(dotProduct(v, n), 2)) /
|
||||
pow(eta2, 2));
|
||||
|
||||
Vector3d t = (indexOutside/indexInside)*(ray.direction - dotProduct(ray.direction, n) * n)- n * root;
|
||||
// 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 reflectionRay = Ray(ray.origin + ray.length * ray.direction, t);
|
||||
reflectionRay.setRemainingBounces(ray.getRemainingBounces()-1);
|
||||
Ray mirroredRay = Ray(ray.origin + ray.length * v, newDirection);
|
||||
mirroredRay.setRemainingBounces(ray.getRemainingBounces() - 1);
|
||||
|
||||
return scene.traceRay(reflectionRay);
|
||||
return scene.traceRay(mirroredRay);
|
||||
}
|
||||
|
||||
// Calculate refracted ray direction t
|
||||
Vector3d t = normalized(
|
||||
eta1 / eta2 *
|
||||
(v - dotProduct(v, n) * n) -
|
||||
n * 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