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
@@ -46,13 +47,23 @@ priority.
4647
4748*/ 
4849
49- MTS_VARIANT class RadianceMeter final  : public Sensor<Float, Spectrum> {
50+ template <typename Float, typename Spectrum>
51+ class RadianceMeter final  : public Sensor<Float, Spectrum> {
5052public: 
5153    MTS_IMPORT_BASE (Sensor, m_film, m_world_transform, m_needs_sample_2,
5254                    m_needs_sample_3)
53-     MTS_IMPORT_TYPES ()
55+     MTS_IMPORT_TYPES (Texture)
56+ 
57+     RadianceMeter (const  Properties &props) : Base (props), m_srf (nullptr ) {
58+         if  (props.has_property (" srf"  )) {
59+             if  constexpr (is_spectral_v<Spectrum>) {
60+                 m_srf = props.texture <Texture>(" srf"  );
61+             } else  {
62+                 Log (Warn, " Ignoring spectral response function " 
63+                           " (not supported for non-spectral variants)"  );
64+             }
65+         }
5466
55-     RadianceMeter (const  Properties &props) : Base (props) {
5667        if  (props.has_property (" to_world"  )) {
5768            //  if direction and origin are present but overridden by
5869            //  to_world, they must still be marked as queried
@@ -93,22 +104,34 @@ MTS_VARIANT class RadianceMeter final : public Sensor<Float, Spectrum> {
93104                                          const  Point2f & /* aperture_sample*/  ,
94105                                          Mask active) const  override  {
95106        MTS_MASKED_FUNCTION (ProfilerPhase::EndpointSampleRay, active);
107+         
108+         //  1. Sample spectrum
109+         Wavelength wavelengths;
110+         Spectrum wav_weight;
111+         
112+         if  (m_srf == nullptr ) {
113+             std::tie (wavelengths, wav_weight) = 
114+                 sample_wavelength<Float, Spectrum>(wavelength_sample);
115+         } else  {
116+             std::tie (wavelengths, wav_weight) = 
117+                 m_srf->sample_spectrum (
118+                     zero<SurfaceInteraction3f>(), 
119+                     math::sample_shifted<Wavelength>(wavelength_sample)
120+                 );
121+         }
122+ 
123+         //  2. Set ray origin and direction
96124        Ray3f ray;
97125        ray.time  = time;
98- 
99-         //  1. Sample spectrum
100-         auto  [wavelengths, wav_weight] =
101-             sample_wavelength<Float, Spectrum>(wavelength_sample);
102126        ray.wavelengths  = wavelengths;
103127
104-         //  2. Set ray origin and direction
105128        auto  trafo = m_world_transform->eval (time, active);
106129        ray.o       = trafo.transform_affine (Point3f{ 0 .f , 0 .f , 0 .f  });
107130        ray.d       = trafo.transform_affine (Vector3f{ 0 .f , 0 .f , 1 .f  });
108131
109132        ray.update ();
110133
111-         return  std::make_pair ( ray, wav_weight) ;
134+         return  {  ray, wav_weight } ;
112135    }
113136
114137    std::pair<RayDifferential3f, Spectrum>
@@ -117,15 +140,26 @@ MTS_VARIANT class RadianceMeter final : public Sensor<Float, Spectrum> {
117140                            const  Point2f & /* aperture_sample*/  ,
118141                            Mask active) const  override  {
119142        MTS_MASKED_FUNCTION (ProfilerPhase::EndpointSampleRay, active);
143+         //  1. Sample spectrum
144+         Wavelength wavelengths;
145+         Spectrum wav_weight;
146+         
147+         if  (m_srf == nullptr ) {
148+             std::tie (wavelengths, wav_weight) = 
149+                 sample_wavelength<Float, Spectrum>(wavelength_sample);
150+         } else  {
151+             std::tie (wavelengths, wav_weight) = 
152+                 m_srf->sample_spectrum (
153+                     zero<SurfaceInteraction3f>(), 
154+                     math::sample_shifted<Wavelength>(wavelength_sample)
155+                 );
156+         }
157+ 
158+         //  2. Set ray origin and direction
120159        RayDifferential3f ray;
121160        ray.time  = time;
122- 
123-         //  1. Sample spectrum
124-         auto  [wavelengths, wav_weight] =
125-             sample_wavelength<Float, Spectrum>(wavelength_sample);
126161        ray.wavelengths  = wavelengths;
127162
128-         //  2. Set ray origin and direction
129163        auto  trafo = m_world_transform->eval (time, active);
130164        ray.o       = trafo.transform_affine (Point3f{ 0 .f , 0 .f , 0 .f  });
131165        ray.d       = trafo.transform_affine (Vector3f{ 0 .f , 0 .f , 1 .f  });
@@ -136,7 +170,7 @@ MTS_VARIANT class RadianceMeter final : public Sensor<Float, Spectrum> {
136170
137171        ray.update ();
138172
139-         return  std::make_pair ( ray, wav_weight) ;
173+         return  {  ray, wav_weight } ;
140174    }
141175
142176    ScalarBoundingBox3f bbox () const  override  {
@@ -145,15 +179,20 @@ MTS_VARIANT class RadianceMeter final : public Sensor<Float, Spectrum> {
145179    }
146180
147181    std::string to_string () const  override  {
182+         using  string::indent;
183+         
148184        std::ostringstream oss;
149185        oss << " RadianceMeter["   << std::endl
150186            << "   world_transform = "   << m_world_transform << " ,"   << std::endl
151187            << "   film = "   << m_film << " ,"   << std::endl
188+             << "   srf = "   << indent (m_srf)  << std::endl
152189            << " ]"  ;
153190        return  oss.str ();
154191    }
155192
156193    MTS_DECLARE_CLASS ()
194+ private: 
195+     ref<Texture> m_srf;
157196};
158197
159198MTS_IMPLEMENT_CLASS_VARIANT (RadianceMeter, Sensor)
0 commit comments