forked from AcademySoftwareFoundation/OpenShadingLanguage
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmicrofacet_tools_decl.h
More file actions
140 lines (110 loc) · 4.56 KB
/
Copy pathmicrofacet_tools_decl.h
File metadata and controls
140 lines (110 loc) · 4.56 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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// Copyright Contributors to the Open Shading Language project.
// SPDX-License-Identifier: BSD-3-Clause
// https://github.com/AcademySoftwareFoundation/OpenShadingLanguage
#pragma once
#include <BSDL/config.h>
#include <BSDL/tools.h>
#include <Imath/ImathVec.h>
BSDL_ENTER_NAMESPACE
struct GGXDist {
BSDL_INLINE_METHOD GGXDist() : ax(0), ay(0) {}
BSDL_INLINE_METHOD GGXDist(float rough, float aniso,
bool flip_aniso = false)
: ax(SQR(rough)), ay(ax)
{
assert(rough >= 0 && rough <= 1);
assert(aniso >= 0 && aniso <= 1);
if (flip_aniso)
aniso = -aniso;
constexpr float ALPHA_MIN = 1e-5f;
ax = std::max(ax * (1 + aniso), ALPHA_MIN);
ay = std::max(ay * (1 - aniso), ALPHA_MIN);
}
BSDL_INLINE_METHOD float D(const Imath::V3f& Hr) const;
BSDL_INLINE_METHOD float G1(Imath::V3f w) const;
BSDL_INLINE_METHOD float G2_G1(Imath::V3f wi, Imath::V3f wo) const;
BSDL_INLINE_METHOD Imath::V3f sample(const Imath::V3f& wo, float randu,
float randv) const;
BSDL_INLINE_METHOD float roughness() const { return std::max(ax, ay); }
private:
float ax, ay;
};
template<typename BSDF> struct TabulatedEnergyCurve {
BSDL_INLINE_METHOD TabulatedEnergyCurve(const float roughness,
const float fresnel_index)
: roughness(roughness), fresnel_index(fresnel_index)
{
}
BSDL_INLINE_METHOD float interpolate_emiss(int i) const;
BSDL_INLINE_METHOD float get_Emiss_avg() const;
BSDL_INLINE_METHOD float Emiss_eval(float c) const;
private:
float roughness, fresnel_index;
};
// Not a full BxDF, just enough implemented to allow baking tables
template<typename Dist> struct MiniMicrofacet {
// describe how tabulation should be done
static constexpr int Nc = 16;
static constexpr int Nr = 16;
static constexpr int Nf = 1;
static constexpr float get_cosine(int i)
{
// we don't use a uniform spacing of cosines because we want a bit more resolution near 0
// where the energy compensation tables tend to vary more quickly
return std::max(SQR(float(i) * (1.0f / (Nc - 1))), 1e-6f);
}
explicit MiniMicrofacet(float rough, float) : d(rough, 0.0f) {}
BSDL_INLINE_METHOD Sample sample(Imath::V3f wo, float randu, float randv,
float randw) const;
private:
Dist d;
};
namespace spi {
struct MiniMicrofacetGGX : public MiniMicrofacet<GGXDist> {
explicit MiniMicrofacetGGX(float, float rough, float)
: MiniMicrofacet<GGXDist>(rough, 0.0f)
{
}
struct Energy {
float data[Nf * Nr * Nc];
};
static BSDL_INLINE_METHOD Energy& get_energy();
static const char* lut_header() { return "microfacet_tools_luts.h"; }
static const char* struct_name() { return "MiniMicrofacetGGX"; }
};
} // namespace spi
template<typename Fresnel> struct MicrofacetMS {
// describe how tabulation should be done
static constexpr int Nc = 16;
static constexpr int Nr = 16;
static constexpr int Nf = 32;
static constexpr float get_cosine(int i)
{
// we don't use a uniform spacing of cosines because we want a bit more resolution near 0
// where the energy compensation tables tend to vary more quickly
return std::max(SQR(float(i) * (1.0f / (Nc - 1))), 1e-6f);
}
static constexpr const char* name() { return "MicrofacetMS"; }
BSDL_INLINE_METHOD MicrofacetMS() {}
explicit BSDL_INLINE_METHOD MicrofacetMS(float cosNO, float roughness_index,
float fresnel_index);
BSDL_INLINE_METHOD MicrofacetMS(const GGXDist& dist, const Fresnel& fresnel,
float cosNO, float roughness);
BSDL_INLINE_METHOD Sample eval(Imath::V3f wo, Imath::V3f wi) const;
BSDL_INLINE_METHOD Sample sample(Imath::V3f wo, float randu, float randv,
float randw) const;
BSDL_INLINE_METHOD const Fresnel& getFresnel() const { return f; }
private:
BSDL_INLINE_METHOD Power computeFmiss() const;
GGXDist d;
Fresnel f;
float Eo;
float Eo_avg;
};
// Turquin style microfacet with multiple scattering
template<typename Dist, typename Fresnel>
BSDL_INLINE Sample
eval_turquin_microms_reflection(const Dist& dist, const Fresnel& fresnel,
float E_ms, const Imath::V3f& wo,
const Imath::V3f& wi);
BSDL_LEAVE_NAMESPACE