mitsuba/include/mitsuba/render/sampler.h

175 lines
6.5 KiB
C++

/*
This file is part of Mitsuba, a physically based rendering system.
Copyright (c) 2007-2011 by Wenzel Jakob and others.
Mitsuba is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License Version 3
as published by the Free Software Foundation.
Mitsuba is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#if !defined(__SAMPLER_H)
#define __SAMPLER_H
#include <mitsuba/mitsuba.h>
#include <mitsuba/core/random.h>
#include <mitsuba/core/properties.h>
MTS_NAMESPACE_BEGIN
/**
* \brief Base class of all sample generators.
*
* For each sample in a pixel, a sample generator produces a (hypothetical)
* point in the infinite dimensional random number cube. A rendering
* algorithm can then request subsequent 1D or 2D components of this point
* using the \ref next1D() and \ref next2D() functions. Some implementations
* make certain guarantees about the stratification of the first n components
* with respect to the other points that are sampled within a pixel. (the
* low-discrepancy and stratified samplers do this for instance).
*
* The general interaction between a sampler and a rendering algorithm is as
* follows: Before beginning to render a pixel, the rendering algorithm calls
* \ref generate(). The first pixel sample can now be computed, after which
* \ref advance() needs to be invoked. This repeats until all pixel samples have
* been generated. Note that some implementations need to be configured for a
* certain number of pixel samples, and exceeding these will lead to an
* exception being thrown. While computing a pixel sample, the rendering
* algorithm usually requests batches of (pseudo-) random numbers using
* the \ref next1D(), \ref next2D(), \ref next1DArray() and
* \ref next2DArray() functions.
*
* The difference between calling \ref next1D(), \ref next2D() a number of
* times versus using the array variants \ref next1DArray() and
* \ref next2DArray() is that the latter can provide stratification
* not only with respect to random numbers obtained within another pixel
* sample, but also within the array itself. This is useful e.g. in the
* direct illumination strategy, which spawns several rays after hitting
* a surface when computing a pixel sample. Since this is done over and
* over again for each one of the pixel samples, it makes sense to
* stratify over all of the rays that are ultimately generated, and the
* \ref next1DArray() and \ref next2DArray() methods allow to do this.
* See the file \c direct.cpp for an example.
*/
class MTS_EXPORT_RENDER Sampler : public ConfigurableObject {
public:
/**
* Create a clone of this sampler. The clone is allowed to be different
* to some extent, e.g. a pseudorandom generator should be based on a
* different random seed compared to the original. All other parameters,
* are copied exactly.
*/
virtual ref<Sampler> clone() = 0;
/**
* Generate new samples - called initially and every time the generated
* samples have been exhausted. When used in conjunction with a
* SampleIntegrator, this will be called before starting to render
* each pixel.
*/
virtual void generate();
/// Advance to the next sample
virtual void advance();
/// Manually set the current sample index
virtual void setSampleIndex(size_t sampleIndex);
/// Retrieve the next component value from the current sample
virtual Float next1D() = 0;
/// Retrieve the next two component values from the current sample
virtual Point2 next2D() = 0;
/**
* Retrieve the next 2D array of values from the current sample.
* Note that this is different from just calling <tt>next2D()</tt>
* repeatedly - this function will generally return a set of 2D vectors,
* which are not only well-laid out over all samples at the current pixel,
* but also with respect to each other. Note that this 2D array has to be
* requested initially using <tt>request2DArray</tt> and later, they have
* to be retrieved in the same same order and size configuration as the
* requests. An exception is thrown when a mismatch is detected.
*
* This function is useful to support things such as a direct illumination
* rendering technique with "n" pixel samples and "m" shading samples,
* while ensuring that the "n*m" sampled positions on an area light source
* are all well-stratified with respect to each other.
*/
Point2 *next2DArray(unsigned int size);
/// Same as above, but 1D
Float *next1DArray(unsigned int size);
/**
* Request that a 2D array will be made available for
* later consumption by next2DArray(). This must be called
* before generate(). See 'next2DArray' for a description
* of this feature.
*/
virtual void request2DArray(unsigned int size);
/// Same as above, but 1D
virtual void request1DArray(unsigned int size);
/**
* Return an uniformly distributed number on [0, 1).
* Throws an error when the underlying implementation is
* fully deterministic (e.g. QMC).
*/
virtual Float independent1D() = 0;
/**
* Return an uniformly distributed 2D vector on [0, 1)x[0, 1).
* Throws an error when the underlying implementation is
* fully deterministic (e.g. QMC).
*/
virtual Point2 independent2D() = 0;
/// Return total number of samples
inline size_t getSampleCount() const { return m_sampleCount; }
/// Return the current sample index
inline size_t getSampleIndex() const { return m_sampleIndex; }
/// Serialize this sampler to a binary data stream
virtual void serialize(Stream *stream, InstanceManager *manager) const;
/// Return the properties of this sampler
inline const Properties &getProperties() const { return m_properties; }
/// Return a string description
virtual std::string toString() const = 0;
MTS_DECLARE_CLASS()
protected:
/// Construct a new sampler
Sampler(const Properties &props);
/// Unserialize a sampler
Sampler(Stream *stream, InstanceManager *manager);
/// Virtual destructor
virtual ~Sampler();
protected:
size_t m_sampleCount;
size_t m_sampleIndex;
std::vector<unsigned int> m_req1D, m_req2D;
std::vector<Float *> m_sampleArrays1D;
std::vector<Point2 *> m_sampleArrays2D;
int m_sampleDepth1DArray, m_sampleDepth2DArray;
Properties m_properties;
};
MTS_NAMESPACE_END
#endif /* __SAMPLER_H */