Prevents unnecessary rays from being traced, that often caused faulty black pixels
This commit is contained in:
parent
eeed0e23a7
commit
cf9e9175c2
1 changed files with 34 additions and 13 deletions
|
@ -6,20 +6,24 @@
|
||||||
|
|
||||||
Vector3d
|
Vector3d
|
||||||
tangentToWorldSpace(const Vector3d &surfaceNormal, const Vector3d &surfaceTangent, const Vector3d &surfaceBitangent,
|
tangentToWorldSpace(const Vector3d &surfaceNormal, const Vector3d &surfaceTangent, const Vector3d &surfaceBitangent,
|
||||||
const Vector3d &textureNormal) {
|
const Vector3d &textureNormal)
|
||||||
|
{
|
||||||
return textureNormal.x * surfaceTangent + textureNormal.y * surfaceBitangent + textureNormal.z * surfaceNormal;
|
return textureNormal.x * surfaceTangent + textureNormal.y * surfaceBitangent + textureNormal.z * surfaceNormal;
|
||||||
}
|
}
|
||||||
|
|
||||||
MaterialShader::MaterialShader() : opacity(1.0f), normalCoefficient(1.0f), diffuseCoefficient(0.5f), reflectance(0.0f),
|
MaterialShader::MaterialShader() : opacity(1.0f), normalCoefficient(1.0f), diffuseCoefficient(0.5f), reflectance(0.0f),
|
||||||
specularCoefficient(0.5f), shininessExponent(8) {}
|
specularCoefficient(0.5f), shininessExponent(8)
|
||||||
|
{}
|
||||||
|
|
||||||
Color MaterialShader::shade(Scene const &scene, Ray const &ray) const {
|
Color MaterialShader::shade(Scene const &scene, Ray const &ray) const
|
||||||
|
{
|
||||||
Color fragmentColor;
|
Color fragmentColor;
|
||||||
// IMPLEMENT ME
|
// IMPLEMENT ME
|
||||||
|
|
||||||
// (Normal Map) Calculate the new normal vector
|
// (Normal Map) Calculate the new normal vector
|
||||||
Vector3d surfaceNormal = ray.normal;
|
Vector3d surfaceNormal = ray.normal;
|
||||||
if (this->normalMap != nullptr) {
|
if (this->normalMap != nullptr)
|
||||||
|
{
|
||||||
auto surfaceNormalMapColor = this->normalMap->color(ray.surface, true);
|
auto surfaceNormalMapColor = this->normalMap->color(ray.surface, true);
|
||||||
Vector3d textureNormal = {surfaceNormalMapColor.r, surfaceNormalMapColor.g, surfaceNormalMapColor.b};
|
Vector3d textureNormal = {surfaceNormalMapColor.r, surfaceNormalMapColor.g, surfaceNormalMapColor.b};
|
||||||
textureNormal = textureNormal * 2.0f - Vector3d{1, 1, 1};
|
textureNormal = textureNormal * 2.0f - Vector3d{1, 1, 1};
|
||||||
|
@ -30,12 +34,14 @@ Color MaterialShader::shade(Scene const &scene, Ray const &ray) const {
|
||||||
|
|
||||||
// (Diffuse-/Specular Map) Accumulate the light over all light sources
|
// (Diffuse-/Specular Map) Accumulate the light over all light sources
|
||||||
Color surfaceDiffuseColor(0, 0, 0);
|
Color surfaceDiffuseColor(0, 0, 0);
|
||||||
if (this->diffuseMap != nullptr) {
|
if (this->diffuseMap != nullptr)
|
||||||
|
{
|
||||||
surfaceDiffuseColor = this->diffuseMap->color(ray.surface, true);
|
surfaceDiffuseColor = this->diffuseMap->color(ray.surface, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Color surfaceSpecularColor(0, 0, 0);
|
Color surfaceSpecularColor(0, 0, 0);
|
||||||
if (this->specularMap != nullptr) {
|
if (this->specularMap != nullptr)
|
||||||
|
{
|
||||||
surfaceSpecularColor = this->specularMap->color(ray.surface, true);
|
surfaceSpecularColor = this->specularMap->color(ray.surface, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +49,8 @@ Color MaterialShader::shade(Scene const &scene, Ray const &ray) const {
|
||||||
// (Reflection Map) Calculate the reflectance, create a reflection ray
|
// (Reflection Map) Calculate the reflectance, create a reflection ray
|
||||||
Vector3d const reflection = ray.direction - 2 * dotProduct(surfaceNormal, ray.direction) * ray.normal;
|
Vector3d const reflection = ray.direction - 2 * dotProduct(surfaceNormal, ray.direction) * ray.normal;
|
||||||
float surfaceReflectanceCoefficient = this->reflectance;
|
float surfaceReflectanceCoefficient = this->reflectance;
|
||||||
if (this->reflectionMap != nullptr) {
|
if (this->reflectionMap != nullptr)
|
||||||
|
{
|
||||||
auto surfaceReflectiveMapColor = this->reflectionMap->color(ray.surface, true);
|
auto surfaceReflectiveMapColor = this->reflectionMap->color(ray.surface, true);
|
||||||
surfaceReflectanceCoefficient = surfaceReflectiveMapColor.r;
|
surfaceReflectanceCoefficient = surfaceReflectiveMapColor.r;
|
||||||
}
|
}
|
||||||
|
@ -55,7 +62,8 @@ Color MaterialShader::shade(Scene const &scene, Ray const &ray) const {
|
||||||
|
|
||||||
// (Alpha Map) Calculate the opacity, create a background ray
|
// (Alpha Map) Calculate the opacity, create a background ray
|
||||||
float surfaceAlphaCoefficient(1);
|
float surfaceAlphaCoefficient(1);
|
||||||
if (this->alphaMap != nullptr) {
|
if (this->alphaMap != nullptr)
|
||||||
|
{
|
||||||
auto surfaceAlphaMapColor = this->alphaMap->color(ray.surface, true);
|
auto surfaceAlphaMapColor = this->alphaMap->color(ray.surface, true);
|
||||||
surfaceAlphaCoefficient = surfaceAlphaMapColor.r;
|
surfaceAlphaCoefficient = surfaceAlphaMapColor.r;
|
||||||
}
|
}
|
||||||
|
@ -66,7 +74,8 @@ Color MaterialShader::shade(Scene const &scene, Ray const &ray) const {
|
||||||
propagatedRay.primitive = nullptr;
|
propagatedRay.primitive = nullptr;
|
||||||
|
|
||||||
// Iterate over light sources
|
// Iterate over light sources
|
||||||
for (const auto &light: scene.lights()) {
|
for (const auto &light: scene.lights())
|
||||||
|
{
|
||||||
Light::Illumination const illum = light->illuminate(scene, ray);
|
Light::Illumination const illum = light->illuminate(scene, ray);
|
||||||
|
|
||||||
// Diffuse term (lambertian)
|
// Diffuse term (lambertian)
|
||||||
|
@ -76,7 +85,8 @@ Color MaterialShader::shade(Scene const &scene, Ray const &ray) const {
|
||||||
|
|
||||||
// Specular term (phong)
|
// Specular term (phong)
|
||||||
float const cosine = dotProduct(-illum.direction, reflection);
|
float const cosine = dotProduct(-illum.direction, reflection);
|
||||||
if (cosine > 0) {
|
if (cosine > 0)
|
||||||
|
{
|
||||||
Color const specular = this->specularCoefficient * surfaceSpecularColor // highlight
|
Color const specular = this->specularCoefficient * surfaceSpecularColor // highlight
|
||||||
* powf(cosine, this->shininessExponent); // shininess factor
|
* powf(cosine, this->shininessExponent); // shininess factor
|
||||||
fragmentColor += specular * illum.color;
|
fragmentColor += specular * illum.color;
|
||||||
|
@ -85,10 +95,21 @@ Color MaterialShader::shade(Scene const &scene, Ray const &ray) const {
|
||||||
|
|
||||||
}
|
}
|
||||||
// Reflected ray
|
// Reflected ray
|
||||||
fragmentColor += scene.traceRay(reflectionRay) * surfaceReflectanceCoefficient * reflectance;
|
if (surfaceReflectanceCoefficient > 0)
|
||||||
|
{
|
||||||
|
Color const reflectionColor = scene.traceRay(reflectionRay);
|
||||||
|
fragmentColor += surfaceReflectanceCoefficient * reflectionColor * reflectance;
|
||||||
|
}
|
||||||
|
|
||||||
// Opacity
|
// Opacity
|
||||||
return fragmentColor * surfaceAlphaCoefficient + scene.traceRay(propagatedRay) * (1 - surfaceAlphaCoefficient);
|
if (surfaceAlphaCoefficient < 1)
|
||||||
|
{
|
||||||
|
Color const background = scene.traceRay(propagatedRay);
|
||||||
|
fragmentColor = (1 - surfaceAlphaCoefficient) * background + surfaceAlphaCoefficient * fragmentColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fragmentColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MaterialShader::isTransparent() const { return this->opacity < 1.0f || this->alphaMap; }
|
bool MaterialShader::isTransparent() const
|
||||||
|
{ return this->opacity < 1.0f || this->alphaMap; }
|
||||||
|
|
Loading…
Reference in a new issue