44 const Light* e =
nullptr)
54 return d != 0 ? n / d : 0.0f;
89 template <
bool below_surface = false>
92 return pdf > 0 && ((below_surface && sign < 0) || (!below_surface && sign > 0))
104 :
Bsdf(Type::Diffuse)
109 return tex(surf.
uv.x, surf.
uv.y) * kd;
113 auto sample = sample_cosine_hemisphere(surf.
coords, sampler(), sampler());
114 auto color = tex(surf.
uv.x, surf.
uv.y) * (std::max(dot(sample.dir, surf.
coords.
n), 0.0f) * kd);
115 return make_sample(sample.dir, sample.pdf,
color, surf);
119 return cosine_hemisphere_pdf(dot(in, surf.
coords.
n));
123 static constexpr
float kd = 1.0f / pi;
135 , ks((ns + 2) / (2.0f * pi))
139 return tex(surf.
uv.x, surf.
uv.y) * std::pow(reflect_cosine(in, surf, out), ns) * ks;
143 auto coords = gen_local_coords(reflect(out, surf.
coords.
n));
144 auto sample = sample_cosine_power_hemisphere(coords, ns, sampler(), sampler());
145 auto p = reflect_cosine(sample.dir, surf, out);
146 return make_sample(sample.dir, sample.pdf, tex(surf.
uv.x, surf.
uv.y) * (std::max(dot(sample.dir, surf.
coords.
n), 0.0f) * std::pow(p, ns) * ks), surf);
150 return cosine_power_hemisphere_pdf(reflect_cosine(in, surf, out), ns);
155 return std::max(dot(in, reflect(out, surf.
coords.
n)), 0.0f);
168 return make_sample(reflect(out, surf.
coords.
n), 1.0f,
rgb(1.0f, 1.0f, 1.0f), surf);
176 :
Bsdf(Type::Specular)
182 auto k = surf.
entering ? eta : 1.0f / eta;
183 auto cos_i = dot(out, surf.
coords.
n);
184 auto cos2_t = 1.0f - k * k * (1.0f - cos_i * cos_i);
187 auto cos_t = std::sqrt(cos2_t);
188 auto F = fresnel_factor(k, cos_i, cos_t);
190 auto t = (k * cos_i - cos_t) * surf.
coords.
n - k * out;
191 auto adjoint_term = adjoint ? k * k : 1.0f;
192 return make_sample<true>(t, 1.0f,
color * adjoint_term, surf);
197 return make_sample(reflect(out, surf.
coords.
n), 1.0f,
color, surf);
202 static float fresnel_factor(
float k,
float cos_i,
float cos_t) {
203 const float R_s = (k * cos_i - cos_t) / (k * cos_i + cos_t);
204 const float R_p = (cos_i - k * cos_t) / (cos_i + k * cos_t);
205 return (R_s * R_s + R_p * R_p) * 0.5f;
216 :
Bsdf(ty), a(a), b(b), k(k)
220 return lerp(a->
eval(in, surf, out), b->
eval(in, surf, out), k);
224 auto use_b = sampler() < k;
225 auto sample = use_b ? b->
sample(sampler, surf, out, adjoint) : a->
sample(sampler, surf, out, adjoint);
226 sample.
pdf = lerp(use_b ? a->
pdf (sample.in, surf, out) : sample.pdf, use_b ? sample.pdf : b->
pdf (sample.in, surf, out), k);
227 sample.color = lerp(use_b ? a->
eval(sample.in, surf, out) : sample.color, use_b ? sample.color : b->
eval(sample.in, surf, out), k);
232 return lerp(a->
pdf(in, surf, out), b->
pdf(in, surf, out), k);
236 std::unique_ptr<const Bsdf> a, b;
240 #endif // MATERIALS_H static BsdfSample make_sample(const float3 &dir, float pdf, const rgb &color, const SurfaceParams &surf)
Definition: materials.h:90
Base class for all lights.
Definition: lights.h:50
BsdfSample sample(Sampler &sampler, const SurfaceParams &surf, const float3 &, bool) const override final
Samples the material given a surface point and an outgoing direction. The contribution DOES include t...
Definition: materials.h:112
float3 n
Normal.
Definition: random.h:11
Sampler object, used at the level of the integrator to control how the random number generation is do...
Definition: samplers.h:12
Type
Classification of BSDF shapes.
Definition: materials.h:61
Base class for BSDFs.
Definition: materials.h:58
virtual BsdfSample sample(Sampler &, const SurfaceParams &surf, const float3 &, bool=false) const
Samples the material given a surface point and an outgoing direction. The contribution DOES include t...
Definition: materials.h:79
Base class for all textures.
Definition: textures.h:8
float pdf
Probability density function, evaluated for the direction.
Definition: materials.h:18
LocalCoords coords
Local coordinates at the hit point, w.r.t shading normal.
Definition: materials.h:31
Sample returned by a BSDF, including direction, pdf, and color.
Definition: materials.h:16
BsdfSample sample(Sampler &sampler, const SurfaceParams &surf, const float3 &out, bool adjoint) const override final
Samples the material given a surface point and an outgoing direction. The contribution DOES include t...
Definition: materials.h:223
Type type() const
Returns the type of the BSDF, useful to make sampling decisions.
Definition: materials.h:74
bool entering
True if entering the surface.
Definition: materials.h:27
const Light * emitter
BSDF associated with the material (if any)
Definition: materials.h:40
float3 in
Sampled direction.
Definition: materials.h:17
A BSDF that combines two materials.
Definition: materials.h:213
float3 face_normal
Geometric normal.
Definition: materials.h:30
A material is a combination of a BSDF and an optional light emitter.
Definition: materials.h:38
BSDF that can represent glass or any separation between two mediums.
Definition: materials.h:173
Specular part of the modified (physically correct) Phong.
Definition: materials.h:129
Purely Lambertian material.
Definition: materials.h:101
BsdfSample sample(Sampler &sampler, const SurfaceParams &surf, const float3 &out, bool adjoint) const override final
Samples the material given a surface point and an outgoing direction. The contribution DOES include t...
Definition: materials.h:181
float3 point
Hit point in world coordinates.
Definition: materials.h:28
Local coordinates for shading.
Definition: random.h:10
rgb eval(const float3 &, const SurfaceParams &surf, const float3 &) const override final
Evaluates the material for the given pair of directions and surface point. Does NOT include the cosin...
Definition: materials.h:108
rgb color
Color of the sample (BSDF value)
Definition: materials.h:19
virtual float pdf(const float3 &, const SurfaceParams &, const float3 &) const
Returns the probability to sample the given input direction (sampled using the sample function)...
Definition: materials.h:83
Purely specular mirror.
Definition: materials.h:163
float2 uv
Texture coordinates.
Definition: materials.h:29
float pdf(const float3 &in, const SurfaceParams &surf, const float3 &) const override final
Returns the probability to sample the given input direction (sampled using the sample function)...
Definition: materials.h:118
rgb eval(const float3 &in, const SurfaceParams &surf, const float3 &out) const override final
Evaluates the material for the given pair of directions and surface point. Does NOT include the cosin...
Definition: materials.h:138
virtual rgb eval(const float3 &, const SurfaceParams &, const float3 &) const
Evaluates the material for the given pair of directions and surface point. Does NOT include the cosin...
Definition: materials.h:77
BsdfSample sample(Sampler &sampler, const SurfaceParams &surf, const float3 &out, bool) const override final
Samples the material given a surface point and an outgoing direction. The contribution DOES include t...
Definition: materials.h:142
Surface parameters for a given point.
Definition: materials.h:26
BsdfSample sample(Sampler &, const SurfaceParams &surf, const float3 &out, bool) const override final
Samples the material given a surface point and an outgoing direction. The contribution DOES include t...
Definition: materials.h:167
float pdf(const float3 &in, const SurfaceParams &surf, const float3 &out) const override final
Returns the probability to sample the given input direction (sampled using the sample function)...
Definition: materials.h:149
float pdf(const float3 &in, const SurfaceParams &surf, const float3 &out) const override final
Returns the probability to sample the given input direction (sampled using the sample function)...
Definition: materials.h:231
rgb eval(const float3 &in, const SurfaceParams &surf, const float3 &out) const override final
Evaluates the material for the given pair of directions and surface point. Does NOT include the cosin...
Definition: materials.h:219
Material()
Light associated with the material (if any)
Definition: materials.h:42