Merge branch 'master' into multithread_renderer
This commit is contained in:
commit
e4ab07b4c6
3 changed files with 61 additions and 27 deletions
|
@ -1,4 +1,5 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <cmath>
|
||||||
#include "light/light.h"
|
#include "light/light.h"
|
||||||
#include "scene/scene.h"
|
#include "scene/scene.h"
|
||||||
#include "shader/brdfshader.h"
|
#include "shader/brdfshader.h"
|
||||||
|
@ -8,6 +9,8 @@ BrdfShader::BrdfShader(char const *fileName, Color const &scale)
|
||||||
|
|
||||||
Color BrdfShader::shade(Scene const &scene, Ray const &ray) const {
|
Color BrdfShader::shade(Scene const &scene, Ray const &ray) const {
|
||||||
Color illuminationColor;
|
Color illuminationColor;
|
||||||
|
/*
|
||||||
|
* Arvids Code
|
||||||
static auto rebase = [](Vector3d const &axis_x,
|
static auto rebase = [](Vector3d const &axis_x,
|
||||||
Vector3d const &axis_y,
|
Vector3d const &axis_y,
|
||||||
Vector3d const &axis_z,
|
Vector3d const &axis_z,
|
||||||
|
@ -35,6 +38,9 @@ Color BrdfShader::shade(Scene const &scene, Ray const &ray) const {
|
||||||
for (auto &light: scene.lights()) {
|
for (auto &light: scene.lights()) {
|
||||||
|
|
||||||
auto illum = light->illuminate(scene, ray);
|
auto illum = light->illuminate(scene, ray);
|
||||||
|
if (dotProduct(ray.normal, illum.direction) <= EPSILON) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
auto axis = orthoNormalized(ray.normal, ray.direction, illum.direction);
|
auto axis = orthoNormalized(ray.normal, ray.direction, illum.direction);
|
||||||
auto axis_y = std::get<0>(axis);
|
auto axis_y = std::get<0>(axis);
|
||||||
|
@ -42,16 +48,50 @@ Color BrdfShader::shade(Scene const &scene, Ray const &ray) const {
|
||||||
auto axis_z = std::get<2>(axis);
|
auto axis_z = std::get<2>(axis);
|
||||||
|
|
||||||
auto N = normalized(rebase(axis_x, axis_y, axis_z, ray.normal));
|
auto N = normalized(rebase(axis_x, axis_y, axis_z, ray.normal));
|
||||||
auto D = normalized(rebase(axis_x, axis_y, axis_z, ray.direction));
|
auto D = normalized(rebase(axis_x, axis_y, axis_z, -ray.direction));
|
||||||
auto L = normalized(rebase(axis_x, axis_y, axis_z, illum.direction));
|
auto L = normalized(rebase(axis_x, axis_y, axis_z, -illum.direction));
|
||||||
D = axis_y * D.y + axis_z * D.z;
|
D = axis_y * D.y + axis_z * D.z;
|
||||||
L = axis_y * L.y + axis_z * L.z;
|
L = axis_y * L.y + axis_z * L.z;
|
||||||
|
|
||||||
illuminationColor += brdf->lookupBrdfValues(std::acos(dotProduct(illum.direction, ray.normal)),
|
illuminationColor += brdf->lookupBrdfValues(std::acos(dotProduct(ray.normal, -ray.direction)),
|
||||||
0,
|
0.0f,
|
||||||
std::acos(dotProduct(ray.direction, ray.normal)),
|
std::acos(dotProduct(illum.direction, ray.normal)),
|
||||||
std::acos(dotProduct(D, L)));
|
std::acos(dotProduct(D, L)));
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
// IMPLEMENT ME
|
// IMPLEMENT ME
|
||||||
|
|
||||||
|
for(auto& light : scene.lights()){
|
||||||
|
Light::Illumination illum = light->illuminate(scene, ray);
|
||||||
|
|
||||||
|
Vector3d invertedDirection = -ray.direction;
|
||||||
|
Vector3d invertedIllum = -illum.direction;
|
||||||
|
|
||||||
|
// the dot-product cant be negative otherwise the light ray would come from the inside
|
||||||
|
if(dotProduct(invertedIllum, ray.normal) < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Calculate coordinate System
|
||||||
|
Vector3d axisX = crossProduct(invertedDirection, ray.normal);
|
||||||
|
Vector3d axisY = crossProduct(axisX, ray.normal);
|
||||||
|
|
||||||
|
// Project ray.direction and illum.direction into plane
|
||||||
|
Vector2d projectedIllum = Vector2d(dotProduct(axisX, invertedIllum), dotProduct(axisY, invertedIllum));
|
||||||
|
Vector2d projectedDirection = Vector2d(dotProduct(axisX, invertedDirection), dotProduct(axisY, invertedDirection));
|
||||||
|
|
||||||
|
// get Z coordinate for theta angles
|
||||||
|
double coordinateZDirection = dotProduct(ray.normal, invertedDirection);
|
||||||
|
double coordinateZIllum = dotProduct(ray.normal, invertedIllum);
|
||||||
|
|
||||||
|
// calculate theta1 and 2
|
||||||
|
double theta1Correct = std::atan2(length(projectedDirection), coordinateZDirection);
|
||||||
|
double theta2Correct = std::atan2(length(projectedIllum), coordinateZIllum);
|
||||||
|
|
||||||
|
// calculate phi
|
||||||
|
double phi = std::atan2(projectedIllum.u, projectedIllum.v);
|
||||||
|
|
||||||
|
illuminationColor += brdf->lookupBrdfValues(theta1Correct, 0.0, theta2Correct, phi);
|
||||||
|
|
||||||
|
}
|
||||||
return illuminationColor;
|
return illuminationColor;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,36 +23,30 @@ Color CookTorranceShader::shade(Scene const &scene, Ray const &ray) const {
|
||||||
auto NH = dotProduct(N, H);
|
auto NH = dotProduct(N, H);
|
||||||
auto VH = dotProduct(V, H);
|
auto VH = dotProduct(V, H);
|
||||||
|
|
||||||
|
//Cook-Torrance diffuse Term
|
||||||
float rhoD = 1.0f / PI;
|
float rhoD = 1.0f / PI;
|
||||||
|
//Cook-Torrance Specular Term
|
||||||
|
//F = Fresnel; D = microfacet Distribution; G = Geometrical factor
|
||||||
|
float rhoS = F(VH) * D(NH) * G(NH, NV, VH, NL) / (4 * NV * NL);
|
||||||
|
//BRDF
|
||||||
|
Color rhoBD = diffuseColor * rhoD + ctColor * rhoS;
|
||||||
|
|
||||||
|
fragmentColor += illum.color * std::abs(NL) * rhoBD;
|
||||||
|
|
||||||
auto rhoS = F(VH) * D(NH) * G(NH, NV, VH, NL) / (4 * NV * NL);
|
|
||||||
auto rhoPD = diffuseColor * rhoD + ctColor * rhoS;
|
|
||||||
|
|
||||||
|
|
||||||
fragmentColor += illum.color * std::abs(NL) * rhoPD;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return diffuseColor * fragmentColor;
|
return diffuseColor * fragmentColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
float CookTorranceShader::D(float NdotH) const {
|
float CookTorranceShader::D(float NdotH) const {
|
||||||
float divisor = 4.0f * m * m * std::pow(cos(NdotH), 4);
|
float divisor = 4.0f * m * m * std::pow(NdotH, 4.0f);
|
||||||
float exponent = std::pow(tan(NdotH) / m, 2);
|
float exponent = (NdotH * NdotH - 1.0f) / (m * m * NdotH * NdotH);
|
||||||
return 1 / divisor * std::exp(- 1.0f * exponent);
|
return 1 / divisor * std::exp(exponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
float CookTorranceShader::F(float VdotH) const {
|
float CookTorranceShader::F(float VdotH) const {
|
||||||
return F0 + (1 - F0) * std::pow(1 - VdotH, 5);
|
return F0 + (1.0f - F0) * std::pow(1.0f - VdotH, 5.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
float CookTorranceShader::G(float NdotH, float NdotV, float VdotH, float NdotL) const {
|
float CookTorranceShader::G(float NdotH, float NdotV, float VdotH, float NdotL) const {
|
||||||
if (std::abs(NdotL) < 0.1f) {
|
|
||||||
return std::min(1.0f, std::min(2 * NdotH * NdotV / VdotH, 2 * NdotH * NdotL / VdotH));
|
return std::min(1.0f, std::min(2 * NdotH * NdotV / VdotH, 2 * NdotH * NdotL / VdotH));
|
||||||
} else if (std::abs(NdotV) < 0.1f) {
|
|
||||||
return 2 * NdotH * NdotL / VdotH;
|
|
||||||
} else {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,11 +14,11 @@ Color PhongShader::shade(Scene const &scene, Ray const &ray) const {
|
||||||
for (auto &light: scene.lights()) {
|
for (auto &light: scene.lights()) {
|
||||||
auto illum = light->illuminate(scene, ray);
|
auto illum = light->illuminate(scene, ray);
|
||||||
|
|
||||||
Vector3d omegaI = normalized(illum.direction);
|
Vector3d reflection = 2 * dotProduct(illum.direction, ray.normal) * ray.normal - illum.direction;
|
||||||
Vector3d omegaR = 2 * dotProduct(omegaI, ray.normal) * ray.normal - omegaI;
|
Color diffuse = diffuseCoefficient * dotProduct(illum.direction, -ray.normal) * diffuseColor;
|
||||||
float cosPsi = std::max(0.0f, dotProduct(ray.direction, omegaR));
|
Color specular = specularCoefficient * specularColor
|
||||||
fragmentColor += illum.color * diffuseCoefficient * diffuseColor / PI
|
* std::pow(dotProduct(ray.direction, reflection), shininessExponent);
|
||||||
+ illum.color * specularCoefficient * specularColor * std::pow(cosPsi, shininessExponent);
|
fragmentColor += illum.color * diffuse + illum.color * specular;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fragmentColor;
|
return fragmentColor;
|
||||||
|
|
Loading…
Reference in a new issue