Skip to content

Commit 17bbfcd

Browse files
committed
Updated test_perspective.py
Ported test_irradiancemeter.py Ported test_radiancemeter.py Ported test_thinlens.py Partially revert "Updated test_perspective.py" This reverts formatting changes in commit caf2198. Autopep8 and isort pass Updated perspective plugin and tests with SRF support Added flexible spectral range and default value to uniform spectrum plugin Fixes after rebase and ported tests to dict API Fixed perspective camera Added SRF to radiancemeter Added SRF to irradiancemeter plugin Updated plugin docs Docs update and minor fixes to uniform spectrum plugin Minor fix to uniform spectrum
1 parent 87364d9 commit 17bbfcd

File tree

10 files changed

+416
-53
lines changed

10 files changed

+416
-53
lines changed

src/sensors/irradiancemeter.cpp

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <mitsuba/core/warp.h>
55
#include <mitsuba/render/fwd.h>
66
#include <mitsuba/render/sensor.h>
7+
#include <mitsuba/render/texture.h>
78

89
NAMESPACE_BEGIN(mitsuba)
910

@@ -16,7 +17,10 @@ Irradiance meter (:monosp:`irradiancemeter`)
1617
1718
.. pluginparameters::
1819
19-
* - none
20+
* - srf
21+
- |spectrum|
22+
- If set, sensor response function used to sample wavelengths from. This
23+
parameter is ignored if used with nonspectral variants.
2024
2125
This sensor plugin implements an irradiance meter, which measures
2226
the incident power per unit area over a shape which it is attached to.
@@ -43,9 +47,18 @@ simply instantiate the desired sensor shape and specify an
4347
MTS_VARIANT class IrradianceMeter final : public Sensor<Float, Spectrum> {
4448
public:
4549
MTS_IMPORT_BASE(Sensor, m_film, m_world_transform, m_shape)
46-
MTS_IMPORT_TYPES(Shape)
47-
48-
IrradianceMeter(const Properties &props) : Base(props) {
50+
MTS_IMPORT_TYPES(Shape, Texture)
51+
52+
IrradianceMeter(const Properties &props) : Base(props), m_srf(nullptr) {
53+
if (props.has_property("srf")) {
54+
if constexpr(is_spectral_v<Spectrum>) {
55+
m_srf = props.texture<Texture>("srf");
56+
} else {
57+
Log(Warn, "Ignoring spectral response function "
58+
"(not supported for non-spectral variants)");
59+
}
60+
}
61+
4962
if (props.has_property("to_world"))
5063
Throw("Found a 'to_world' transformation -- this is not allowed. "
5164
"The irradiance meter inherits this transformation from its parent "
@@ -75,7 +88,19 @@ MTS_VARIANT class IrradianceMeter final : public Sensor<Float, Spectrum> {
7588
Vector3f local = warp::square_to_cosine_hemisphere(sample3);
7689

7790
// 3. Sample spectrum
78-
auto [wavelengths, wav_weight] = sample_wavelength<Float, Spectrum>(wavelength_sample);
91+
Wavelength wavelengths;
92+
Spectrum wav_weight;
93+
94+
if (m_srf == nullptr) {
95+
std::tie(wavelengths, wav_weight) =
96+
sample_wavelength<Float, Spectrum>(wavelength_sample);
97+
} else {
98+
std::tie(wavelengths, wav_weight) =
99+
m_srf->sample_spectrum(
100+
zero<SurfaceInteraction3f>(),
101+
math::sample_shifted<Wavelength>(wavelength_sample)
102+
);
103+
}
79104

80105
return std::make_pair(
81106
RayDifferential3f(ps.p, Frame3f(ps.n).to_world(local), time, wavelengths),
@@ -109,6 +134,8 @@ MTS_VARIANT class IrradianceMeter final : public Sensor<Float, Spectrum> {
109134
}
110135

111136
MTS_DECLARE_CLASS()
137+
private:
138+
ref<Texture> m_srf;
112139
};
113140

114141
MTS_IMPLEMENT_CLASS_VARIANT(IrradianceMeter, Sensor)

src/sensors/perspective.cpp

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <mitsuba/core/properties.h>
33
#include <mitsuba/core/transform.h>
44
#include <mitsuba/core/bbox.h>
5+
#include <mitsuba/render/texture.h>
56

67
NAMESPACE_BEGIN(mitsuba)
78

@@ -47,6 +48,10 @@ Perspective pinhole camera (:monosp:`perspective`)
4748
- |float|
4849
- Distance to the near/far clip planes. (Default: :monosp:`near_clip=1e-2` (i.e. :monosp:`0.01`)
4950
and :monosp:`far_clip=1e4` (i.e. :monosp:`10000`))
51+
* - srf
52+
- |spectrum|
53+
- If set, sensor response function used to sample wavelengths from. This parameter is ignored if
54+
used with nonspectral variants.
5055
5156
.. subfigstart::
5257
.. subfigure:: ../../resources/data/docs/images/render/sensor_perspective.jpg
@@ -56,7 +61,7 @@ Perspective pinhole camera (:monosp:`perspective`)
5661
.. subfigend::
5762
:label: fig-perspective
5863
59-
This plugin implements a simple idealizied perspective camera model, which
64+
This plugin implements a simple idealized perspective camera model, which
6065
has an infinitely small aperture. This creates an infinite depth of field,
6166
i.e. no optical blurring occurs.
6267
@@ -89,19 +94,27 @@ class PerspectiveCamera final : public ProjectiveCamera<Float, Spectrum> {
8994
MTS_IMPORT_BASE(ProjectiveCamera, m_world_transform, m_needs_sample_3,
9095
m_film, m_sampler, m_resolution, m_shutter_open,
9196
m_shutter_open_time, m_near_clip, m_far_clip)
92-
MTS_IMPORT_TYPES()
97+
MTS_IMPORT_TYPES(Texture)
9398

9499
// =============================================================
95100
//! @{ \name Constructors
96101
// =============================================================
97102

98-
PerspectiveCamera(const Properties &props) : Base(props) {
103+
PerspectiveCamera(const Properties &props) : Base(props), m_srf(nullptr) {
99104
ScalarVector2i size = m_film->size();
100105
m_x_fov = parse_fov(props, size.x() / (float) size.y());
101106

102107
if (m_world_transform->has_scale())
103108
Throw("Scale factors in the camera-to-world transformation are not allowed!");
104109

110+
if (props.has_property("srf")) {
111+
if constexpr(is_spectral_v<Spectrum>) {
112+
m_srf = props.texture<Texture>("srf");
113+
} else {
114+
Log(Warn, "Ignoring spectral response function (not supported for non-spectral variants)");
115+
}
116+
}
117+
105118
update_camera_transforms();
106119
}
107120

@@ -143,7 +156,21 @@ class PerspectiveCamera final : public ProjectiveCamera<Float, Spectrum> {
143156
Mask active) const override {
144157
MTS_MASKED_FUNCTION(ProfilerPhase::EndpointSampleRay, active);
145158

146-
auto [wavelengths, wav_weight] = sample_wavelength<Float, Spectrum>(wavelength_sample);
159+
// Sample spectrum
160+
Wavelength wavelengths;
161+
Spectrum wav_weight;
162+
163+
if (m_srf == nullptr) {
164+
std::tie(wavelengths, wav_weight) =
165+
sample_wavelength<Float, Spectrum>(wavelength_sample);
166+
} else {
167+
std::tie(wavelengths, wav_weight) =
168+
m_srf->sample_spectrum(
169+
zero<SurfaceInteraction3f>(),
170+
math::sample_shifted<Wavelength>(wavelength_sample)
171+
);
172+
}
173+
147174
Ray3f ray;
148175
ray.time = time;
149176
ray.wavelengths = wavelengths;
@@ -171,8 +198,22 @@ class PerspectiveCamera final : public ProjectiveCamera<Float, Spectrum> {
171198
sample_ray_differential(Float time, Float wavelength_sample, const Point2f &position_sample,
172199
const Point2f & /*aperture_sample*/, Mask active) const override {
173200
MTS_MASKED_FUNCTION(ProfilerPhase::EndpointSampleRay, active);
174-
175-
auto [wavelengths, wav_weight] = sample_wavelength<Float, Spectrum>(wavelength_sample);
201+
202+
// Sample spectrum
203+
Wavelength wavelengths;
204+
Spectrum wav_weight;
205+
206+
if (m_srf == nullptr) {
207+
std::tie(wavelengths, wav_weight) =
208+
sample_wavelength<Float, Spectrum>(wavelength_sample);
209+
} else {
210+
std::tie(wavelengths, wav_weight) =
211+
m_srf->sample_spectrum(
212+
zero<SurfaceInteraction3f>(),
213+
math::sample_shifted<Wavelength>(wavelength_sample)
214+
);
215+
}
216+
176217
RayDifferential3f ray;
177218
ray.time = time;
178219
ray.wavelengths = wavelengths;
@@ -291,6 +332,7 @@ class PerspectiveCamera final : public ProjectiveCamera<Float, Spectrum> {
291332
<< " shutter_open = " << m_shutter_open << "," << std::endl
292333
<< " shutter_open_time = " << m_shutter_open_time << "," << std::endl
293334
<< " world_transform = " << indent(m_world_transform) << std::endl
335+
<< " srf = " << indent(m_srf) << std::endl
294336
<< "]";
295337
return oss.str();
296338
}
@@ -303,6 +345,7 @@ class PerspectiveCamera final : public ProjectiveCamera<Float, Spectrum> {
303345
ScalarFloat m_normalization;
304346
ScalarFloat m_x_fov;
305347
ScalarVector3f m_dx, m_dy;
348+
ref<Texture> m_srf;
306349
};
307350

308351
MTS_IMPLEMENT_CLASS_VARIANT(PerspectiveCamera, ProjectiveCamera)

src/sensors/radiancemeter.cpp

Lines changed: 58 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <mitsuba/core/transform.h>
44
#include <mitsuba/render/fwd.h>
55
#include <mitsuba/render/sensor.h>
6+
#include <mitsuba/render/texture.h>
67

78
NAMESPACE_BEGIN(mitsuba)
89

@@ -27,6 +28,10 @@ Radiance meter (:monosp:`radiancemeter`)
2728
- |vector|
2829
- Alternative (and exclusive) to `to_world`. Direction in which the
2930
sensor is pointing in world coordinates. Must be used with `origin`.
31+
* - srf
32+
- |spectrum|
33+
- If set, sensor response function used to sample wavelengths from. This
34+
parameter is ignored if used with nonspectral variants.
3035
3136
This sensor plugin implements a simple radiance meter, which measures
3237
the incident power per unit area per unit solid angle along a
@@ -46,13 +51,23 @@ priority.
4651
4752
*/
4853

49-
MTS_VARIANT class RadianceMeter final : public Sensor<Float, Spectrum> {
54+
template <typename Float, typename Spectrum>
55+
class RadianceMeter final : public Sensor<Float, Spectrum> {
5056
public:
5157
MTS_IMPORT_BASE(Sensor, m_film, m_world_transform, m_needs_sample_2,
5258
m_needs_sample_3)
53-
MTS_IMPORT_TYPES()
59+
MTS_IMPORT_TYPES(Texture)
60+
61+
RadianceMeter(const Properties &props) : Base(props), m_srf(nullptr) {
62+
if (props.has_property("srf")) {
63+
if constexpr(is_spectral_v<Spectrum>) {
64+
m_srf = props.texture<Texture>("srf");
65+
} else {
66+
Log(Warn, "Ignoring spectral response function "
67+
"(not supported for non-spectral variants)");
68+
}
69+
}
5470

55-
RadianceMeter(const Properties &props) : Base(props) {
5671
if (props.has_property("to_world")) {
5772
// if direction and origin are present but overridden by
5873
// to_world, they must still be marked as queried
@@ -93,22 +108,34 @@ MTS_VARIANT class RadianceMeter final : public Sensor<Float, Spectrum> {
93108
const Point2f & /*aperture_sample*/,
94109
Mask active) const override {
95110
MTS_MASKED_FUNCTION(ProfilerPhase::EndpointSampleRay, active);
111+
112+
// 1. Sample spectrum
113+
Wavelength wavelengths;
114+
Spectrum wav_weight;
115+
116+
if (m_srf == nullptr) {
117+
std::tie(wavelengths, wav_weight) =
118+
sample_wavelength<Float, Spectrum>(wavelength_sample);
119+
} else {
120+
std::tie(wavelengths, wav_weight) =
121+
m_srf->sample_spectrum(
122+
zero<SurfaceInteraction3f>(),
123+
math::sample_shifted<Wavelength>(wavelength_sample)
124+
);
125+
}
126+
127+
// 2. Set ray origin and direction
96128
Ray3f ray;
97129
ray.time = time;
98-
99-
// 1. Sample spectrum
100-
auto [wavelengths, wav_weight] =
101-
sample_wavelength<Float, Spectrum>(wavelength_sample);
102130
ray.wavelengths = wavelengths;
103131

104-
// 2. Set ray origin and direction
105132
auto trafo = m_world_transform->eval(time, active);
106133
ray.o = trafo.transform_affine(Point3f{ 0.f, 0.f, 0.f });
107134
ray.d = trafo.transform_affine(Vector3f{ 0.f, 0.f, 1.f });
108135

109136
ray.update();
110137

111-
return std::make_pair(ray, wav_weight);
138+
return { ray, wav_weight };
112139
}
113140

114141
std::pair<RayDifferential3f, Spectrum>
@@ -117,15 +144,26 @@ MTS_VARIANT class RadianceMeter final : public Sensor<Float, Spectrum> {
117144
const Point2f & /*aperture_sample*/,
118145
Mask active) const override {
119146
MTS_MASKED_FUNCTION(ProfilerPhase::EndpointSampleRay, active);
147+
// 1. Sample spectrum
148+
Wavelength wavelengths;
149+
Spectrum wav_weight;
150+
151+
if (m_srf == nullptr) {
152+
std::tie(wavelengths, wav_weight) =
153+
sample_wavelength<Float, Spectrum>(wavelength_sample);
154+
} else {
155+
std::tie(wavelengths, wav_weight) =
156+
m_srf->sample_spectrum(
157+
zero<SurfaceInteraction3f>(),
158+
math::sample_shifted<Wavelength>(wavelength_sample)
159+
);
160+
}
161+
162+
// 2. Set ray origin and direction
120163
RayDifferential3f ray;
121164
ray.time = time;
122-
123-
// 1. Sample spectrum
124-
auto [wavelengths, wav_weight] =
125-
sample_wavelength<Float, Spectrum>(wavelength_sample);
126165
ray.wavelengths = wavelengths;
127166

128-
// 2. Set ray origin and direction
129167
auto trafo = m_world_transform->eval(time, active);
130168
ray.o = trafo.transform_affine(Point3f{ 0.f, 0.f, 0.f });
131169
ray.d = trafo.transform_affine(Vector3f{ 0.f, 0.f, 1.f });
@@ -136,7 +174,7 @@ MTS_VARIANT class RadianceMeter final : public Sensor<Float, Spectrum> {
136174

137175
ray.update();
138176

139-
return std::make_pair(ray, wav_weight);
177+
return { ray, wav_weight };
140178
}
141179

142180
ScalarBoundingBox3f bbox() const override {
@@ -145,15 +183,20 @@ MTS_VARIANT class RadianceMeter final : public Sensor<Float, Spectrum> {
145183
}
146184

147185
std::string to_string() const override {
186+
using string::indent;
187+
148188
std::ostringstream oss;
149189
oss << "RadianceMeter[" << std::endl
150190
<< " world_transform = " << m_world_transform << "," << std::endl
151191
<< " film = " << m_film << "," << std::endl
192+
<< " srf = " << indent(m_srf) << std::endl
152193
<< "]";
153194
return oss.str();
154195
}
155196

156197
MTS_DECLARE_CLASS()
198+
private:
199+
ref<Texture> m_srf;
157200
};
158201

159202
MTS_IMPLEMENT_CLASS_VARIANT(RadianceMeter, Sensor)

0 commit comments

Comments
 (0)