-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBRDFs.h
More file actions
100 lines (86 loc) · 3.15 KB
/
BRDFs.h
File metadata and controls
100 lines (86 loc) · 3.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#pragma once
#include "Math.h"
namespace dae
{
namespace BRDF
{
/**
* \param kd Diffuse Reflection Coefficient
* \param cd Diffuse Color
* \return Lambert Diffuse Color
*/
static ColorRGB Lambert(float kd, const ColorRGB& cd)
{
return cd * kd / PI;
}
static ColorRGB Lambert(const ColorRGB& kd, const ColorRGB& cd)
{
return cd * kd / PI;
}
/**
* \brief
* \param ks Specular Reflection Coefficient
* \param exp Phong Exponent
* \param l Incoming (incident) Light Direction
* \param v View Direction
* \param n Normal of the Surface
* \return Phong Specular Color
*/
static ColorRGB Phong(float ks, float exp, const Vector3& l, const Vector3& v, const Vector3& n)
{
const auto reflectedLightVector{ Vector3::Reflect(l,n) };
const auto reflectedViewDot{ std::max(Vector3::Dot(reflectedLightVector, v), 0.0f) };
const auto phong{ ks * powf(reflectedViewDot, exp) };
return ColorRGB{ phong, phong, phong };;
}
/**
* \brief BRDF Fresnel Function >> Schlick
* \param h Normalized Halfvector between View and Light directions
* \param v Normalized View direction
* \param f0 Base reflectivity of a surface based on IOR (Indices Of Refrection), this is different for Dielectrics (Non-Metal) and Conductors (Metal)
* \return
*/
static ColorRGB FresnelFunction_Schlick(const Vector3& h, const Vector3& v, const ColorRGB& f0)
{
return ColorRGB::Lerp(f0, ColorRGB{ 1.0f, 1.0f, 1.0f }, powf(1.0f - Vector3::Dot(h, v), 5.0f));
}
/**
* \brief BRDF NormalDistribution >> Trowbridge-Reitz GGX (UE4 implemetation - squared(roughness))
* \param n Surface normal
* \param h Normalized half vector
* \param roughness Roughness of the material
* \return BRDF Normal Distribution Term using Trowbridge-Reitz GGX
*/
static float NormalDistribution_GGX(const Vector3& n, const Vector3& h, float roughness)
{
const float alpha{ Square(roughness) };
return Square(alpha) / (PI * Square(Square(Vector3::Dot(n, h)) * (Square(alpha) - 1.0f) + 1.0f));
}
/**
* \brief BRDF Geometry Function >> Schlick GGX (Direct Lighting + UE4 implementation - squared(roughness))
* \param n Normal of the surface
* \param v Normalized view direction
* \param roughness Roughness of the material
* \return BRDF Geometry Term using SchlickGGX
*/
static float GeometryFunction_SchlickGGX(const Vector3& n, const Vector3& v, float roughness)
{
const float alpha{ Square(roughness) };
const float k{ Square(alpha + 1.0f) / 8.0f };
const float dot{ std::max(Vector3::Dot(n,v), 0.0f) };
return dot / (dot * (1.0f - k) + k);
}
/**
* \brief BRDF Geometry Function >> Smith (Direct Lighting)
* \param n Normal of the surface
* \param v Normalized view direction
* \param l Normalized light direction
* \param roughness Roughness of the material
* \return BRDF Geometry Term using Smith (> SchlickGGX(n,v,roughness) * SchlickGGX(n,l,roughness))
*/
static float GeometryFunction_Smith(const Vector3& n, const Vector3& v, const Vector3& l, float roughness)
{
return GeometryFunction_SchlickGGX(n, v, roughness) * GeometryFunction_SchlickGGX(n, l, roughness);
}
}
}