Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 32 additions & 5 deletions src/sensors/irradiancemeter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <mitsuba/core/warp.h>
#include <mitsuba/render/fwd.h>
#include <mitsuba/render/sensor.h>
#include <mitsuba/render/texture.h>

NAMESPACE_BEGIN(mitsuba)

Expand All @@ -16,7 +17,10 @@ Irradiance meter (:monosp:`irradiancemeter`)

.. pluginparameters::

* - none
* - srf
- |spectrum|
- If set, sensor response function used to sample wavelengths from. This
parameter is ignored if used with nonspectral variants.

This sensor plugin implements an irradiance meter, which measures
the incident power per unit area over a shape which it is attached to.
Expand All @@ -43,9 +47,18 @@ simply instantiate the desired sensor shape and specify an
MTS_VARIANT class IrradianceMeter final : public Sensor<Float, Spectrum> {
public:
MTS_IMPORT_BASE(Sensor, m_film, m_world_transform, m_shape)
MTS_IMPORT_TYPES(Shape)

IrradianceMeter(const Properties &props) : Base(props) {
MTS_IMPORT_TYPES(Shape, Texture)

IrradianceMeter(const Properties &props) : Base(props), m_srf(nullptr) {
if (props.has_property("srf")) {
if constexpr(is_spectral_v<Spectrum>) {
m_srf = props.texture<Texture>("srf");
} else {
Log(Warn, "Ignoring spectral response function "
"(not supported for non-spectral variants)");
}
}

if (props.has_property("to_world"))
Throw("Found a 'to_world' transformation -- this is not allowed. "
"The irradiance meter inherits this transformation from its parent "
Expand Down Expand Up @@ -75,7 +88,19 @@ MTS_VARIANT class IrradianceMeter final : public Sensor<Float, Spectrum> {
Vector3f local = warp::square_to_cosine_hemisphere(sample3);

// 3. Sample spectrum
auto [wavelengths, wav_weight] = sample_wavelength<Float, Spectrum>(wavelength_sample);
Wavelength wavelengths;
Spectrum wav_weight;

if (m_srf == nullptr) {
std::tie(wavelengths, wav_weight) =
sample_wavelength<Float, Spectrum>(wavelength_sample);
} else {
std::tie(wavelengths, wav_weight) =
m_srf->sample_spectrum(
zero<SurfaceInteraction3f>(),
math::sample_shifted<Wavelength>(wavelength_sample)
);
}

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

MTS_DECLARE_CLASS()
private:
ref<Texture> m_srf;
};

MTS_IMPLEMENT_CLASS_VARIANT(IrradianceMeter, Sensor)
Expand Down
55 changes: 49 additions & 6 deletions src/sensors/perspective.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <mitsuba/core/properties.h>
#include <mitsuba/core/transform.h>
#include <mitsuba/core/bbox.h>
#include <mitsuba/render/texture.h>

NAMESPACE_BEGIN(mitsuba)

Expand Down Expand Up @@ -47,6 +48,10 @@ Perspective pinhole camera (:monosp:`perspective`)
- |float|
- Distance to the near/far clip planes. (Default: :monosp:`near_clip=1e-2` (i.e. :monosp:`0.01`)
and :monosp:`far_clip=1e4` (i.e. :monosp:`10000`))
* - srf
- |spectrum|
- If set, sensor response function used to sample wavelengths from. This parameter is ignored if
used with nonspectral variants.

.. subfigstart::
.. subfigure:: ../../resources/data/docs/images/render/sensor_perspective.jpg
Expand All @@ -56,7 +61,7 @@ Perspective pinhole camera (:monosp:`perspective`)
.. subfigend::
:label: fig-perspective

This plugin implements a simple idealizied perspective camera model, which
This plugin implements a simple idealized perspective camera model, which
has an infinitely small aperture. This creates an infinite depth of field,
i.e. no optical blurring occurs.

Expand Down Expand Up @@ -89,19 +94,27 @@ class PerspectiveCamera final : public ProjectiveCamera<Float, Spectrum> {
MTS_IMPORT_BASE(ProjectiveCamera, m_world_transform, m_needs_sample_3,
m_film, m_sampler, m_resolution, m_shutter_open,
m_shutter_open_time, m_near_clip, m_far_clip)
MTS_IMPORT_TYPES()
MTS_IMPORT_TYPES(Texture)

// =============================================================
//! @{ \name Constructors
// =============================================================

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

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

if (props.has_property("srf")) {
if constexpr(is_spectral_v<Spectrum>) {
m_srf = props.texture<Texture>("srf");
} else {
Log(Warn, "Ignoring spectral response function (not supported for non-spectral variants)");
}
}

update_camera_transforms();
}

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

auto [wavelengths, wav_weight] = sample_wavelength<Float, Spectrum>(wavelength_sample);
// Sample spectrum
Wavelength wavelengths;
Spectrum wav_weight;

if (m_srf == nullptr) {
std::tie(wavelengths, wav_weight) =
sample_wavelength<Float, Spectrum>(wavelength_sample);
} else {
std::tie(wavelengths, wav_weight) =
m_srf->sample_spectrum(
zero<SurfaceInteraction3f>(),
math::sample_shifted<Wavelength>(wavelength_sample)
);
}

Ray3f ray;
ray.time = time;
ray.wavelengths = wavelengths;
Expand Down Expand Up @@ -171,8 +198,22 @@ class PerspectiveCamera final : public ProjectiveCamera<Float, Spectrum> {
sample_ray_differential(Float time, Float wavelength_sample, const Point2f &position_sample,
const Point2f & /*aperture_sample*/, Mask active) const override {
MTS_MASKED_FUNCTION(ProfilerPhase::EndpointSampleRay, active);

auto [wavelengths, wav_weight] = sample_wavelength<Float, Spectrum>(wavelength_sample);

// Sample spectrum
Wavelength wavelengths;
Spectrum wav_weight;

if (m_srf == nullptr) {
std::tie(wavelengths, wav_weight) =
sample_wavelength<Float, Spectrum>(wavelength_sample);
} else {
std::tie(wavelengths, wav_weight) =
m_srf->sample_spectrum(
zero<SurfaceInteraction3f>(),
math::sample_shifted<Wavelength>(wavelength_sample)
);
}

RayDifferential3f ray;
ray.time = time;
ray.wavelengths = wavelengths;
Expand Down Expand Up @@ -291,6 +332,7 @@ class PerspectiveCamera final : public ProjectiveCamera<Float, Spectrum> {
<< " shutter_open = " << m_shutter_open << "," << std::endl
<< " shutter_open_time = " << m_shutter_open_time << "," << std::endl
<< " world_transform = " << indent(m_world_transform) << std::endl
<< " srf = " << indent(m_srf) << std::endl
<< "]";
return oss.str();
}
Expand All @@ -303,6 +345,7 @@ class PerspectiveCamera final : public ProjectiveCamera<Float, Spectrum> {
ScalarFloat m_normalization;
ScalarFloat m_x_fov;
ScalarVector3f m_dx, m_dy;
ref<Texture> m_srf;
};

MTS_IMPLEMENT_CLASS_VARIANT(PerspectiveCamera, ProjectiveCamera)
Expand Down
73 changes: 58 additions & 15 deletions src/sensors/radiancemeter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <mitsuba/core/transform.h>
#include <mitsuba/render/fwd.h>
#include <mitsuba/render/sensor.h>
#include <mitsuba/render/texture.h>

NAMESPACE_BEGIN(mitsuba)

Expand All @@ -27,6 +28,10 @@ Radiance meter (:monosp:`radiancemeter`)
- |vector|
- Alternative (and exclusive) to `to_world`. Direction in which the
sensor is pointing in world coordinates. Must be used with `origin`.
* - srf
- |spectrum|
- If set, sensor response function used to sample wavelengths from. This
parameter is ignored if used with nonspectral variants.

This sensor plugin implements a simple radiance meter, which measures
the incident power per unit area per unit solid angle along a
Expand All @@ -46,13 +51,23 @@ priority.

*/

MTS_VARIANT class RadianceMeter final : public Sensor<Float, Spectrum> {
template <typename Float, typename Spectrum>
class RadianceMeter final : public Sensor<Float, Spectrum> {
public:
MTS_IMPORT_BASE(Sensor, m_film, m_world_transform, m_needs_sample_2,
m_needs_sample_3)
MTS_IMPORT_TYPES()
MTS_IMPORT_TYPES(Texture)

RadianceMeter(const Properties &props) : Base(props), m_srf(nullptr) {
if (props.has_property("srf")) {
if constexpr(is_spectral_v<Spectrum>) {
m_srf = props.texture<Texture>("srf");
} else {
Log(Warn, "Ignoring spectral response function "
"(not supported for non-spectral variants)");
}
}

RadianceMeter(const Properties &props) : Base(props) {
if (props.has_property("to_world")) {
// if direction and origin are present but overridden by
// to_world, they must still be marked as queried
Expand Down Expand Up @@ -93,22 +108,34 @@ MTS_VARIANT class RadianceMeter final : public Sensor<Float, Spectrum> {
const Point2f & /*aperture_sample*/,
Mask active) const override {
MTS_MASKED_FUNCTION(ProfilerPhase::EndpointSampleRay, active);

// 1. Sample spectrum
Wavelength wavelengths;
Spectrum wav_weight;

if (m_srf == nullptr) {
std::tie(wavelengths, wav_weight) =
sample_wavelength<Float, Spectrum>(wavelength_sample);
} else {
std::tie(wavelengths, wav_weight) =
m_srf->sample_spectrum(
zero<SurfaceInteraction3f>(),
math::sample_shifted<Wavelength>(wavelength_sample)
);
}

// 2. Set ray origin and direction
Ray3f ray;
ray.time = time;

// 1. Sample spectrum
auto [wavelengths, wav_weight] =
sample_wavelength<Float, Spectrum>(wavelength_sample);
ray.wavelengths = wavelengths;

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

ray.update();

return std::make_pair(ray, wav_weight);
return { ray, wav_weight };
}

std::pair<RayDifferential3f, Spectrum>
Expand All @@ -117,15 +144,26 @@ MTS_VARIANT class RadianceMeter final : public Sensor<Float, Spectrum> {
const Point2f & /*aperture_sample*/,
Mask active) const override {
MTS_MASKED_FUNCTION(ProfilerPhase::EndpointSampleRay, active);
// 1. Sample spectrum
Wavelength wavelengths;
Spectrum wav_weight;

if (m_srf == nullptr) {
std::tie(wavelengths, wav_weight) =
sample_wavelength<Float, Spectrum>(wavelength_sample);
} else {
std::tie(wavelengths, wav_weight) =
m_srf->sample_spectrum(
zero<SurfaceInteraction3f>(),
math::sample_shifted<Wavelength>(wavelength_sample)
);
}

// 2. Set ray origin and direction
RayDifferential3f ray;
ray.time = time;

// 1. Sample spectrum
auto [wavelengths, wav_weight] =
sample_wavelength<Float, Spectrum>(wavelength_sample);
ray.wavelengths = wavelengths;

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

ray.update();

return std::make_pair(ray, wav_weight);
return { ray, wav_weight };
}

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

std::string to_string() const override {
using string::indent;

std::ostringstream oss;
oss << "RadianceMeter[" << std::endl
<< " world_transform = " << m_world_transform << "," << std::endl
<< " film = " << m_film << "," << std::endl
<< " srf = " << indent(m_srf) << std::endl
<< "]";
return oss.str();
}

MTS_DECLARE_CLASS()
private:
ref<Texture> m_srf;
};

MTS_IMPLEMENT_CLASS_VARIANT(RadianceMeter, Sensor)
Expand Down
Loading