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
78NAMESPACE_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
3136This sensor plugin implements a simple radiance meter, which measures 
3237the 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> {
5056public: 
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[" 
150190            << "   world_transform = " " ," 
151191            << "   film = " " ," 
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
159202MTS_IMPLEMENT_CLASS_VARIANT (RadianceMeter, Sensor)
0 commit comments