HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
TIL_AdaptiveImage.h
Go to the documentation of this file.
1 /*
2 * PROPRIETARY INFORMATION. This software is proprietary to
3 * Side Effects Software Inc., and is not to be reproduced,
4 * transmitted, or disclosed in any way without written permission.
5 *
6 * NAME: TIL_AdaptiveImage.h (TIL Library, C++)
7 *
8 * COMMENTS: A tree-based sparse image class
9 */
10 
11 #pragma once
12 
13 #ifndef __TIL_AdaptiveImage__
14 #define __TIL_AdaptiveImage__
15 
16 #include "TIL_API.h"
17 #include <SYS/SYS_Types.h>
18 #include <UT/UT_Array.h>
19 #include <UT/UT_Assert.h>
20 #include <UT/UT_UniquePtr.h>
21 
22 class TIL_PixelFilter;
23 class TIL_Raster;
24 
26 {
27 public:
29  int nplanes, const int *num_plane_components,
30  int adaptivity_plane = -1,
31  int levels_below_pixel = 0,
32  int min_samples_per_pixel = 1,
33  int max_samples_per_pixel = 1024,
34  float relative_noise_threshold = 0.005f);
35 
36  bool sample(uint64 seed, int &chosen_x, int &chosen_y, int &pixel_sample);
37 
38  void insert(int x, int y, int pixel_sample, const float *data);
39 
40  struct Level
41  {
42  /// Per-component sums for each pixel:
43  /// nComponents x width x height
45 
46  /// Sums for each pixel over all components of
47  /// squared clamped sample values:
48  /// width x height
50 
51  /// Number of samples "committed" for each pixel, i.e. the number of
52  /// times that sample() has chosen a pixel in the corresponding area.
53  /// width x height
55 
56  /// Number of samples actually inserted for each pixel:
57  /// width x height
59 
60  /// Unnormalized weights for adaptive sampling, before interpolating
61  /// between levels:
62  /// width x height
64 
65  /// Unnormalized weights for adaptive sampling, after interpolating
66  /// between levels:
67  /// width x height
69 
70  /// Width of this level in pixels
71  int myWidth;
72 
73  /// Height of this level in pixels
74  int myHeight;
75  };
76 
77  int getPixelLevelNum() const
78  {
79  return (myRootPowerOf2+1) - 1 - myLevelsBelowPixel;
80  }
81  const Level &getLevel(int leveli) const
82  {
83  return myLevels[leveli];
84  }
85 
86  bool isPriorityCircleOn() const
87  {
88  return myPriorityCircleOn;
89  }
90  void getPriorityCircle(float &x, float &y, float &radius) const
91  {
92  x = myPriorityCircleX;
93  y = myPriorityCircleY;
94  radius = myPriorityCircleRadius;
95  }
96  void setPriorityCircle(float x, float y, float radius)
97  {
98  myPriorityCircleX = x;
99  myPriorityCircleY = y;
100  if (radius < 0.5f)
101  radius = 0.5f;
102  myPriorityCircleRadius = radius;
103  myPriorityCircleOn = true;
104  }
106  {
107  myPriorityCircleOn = false;
108  }
109 
110  static exint pixelArea(
111  int x, int y, int level_width, int level_height, int leveli,
112  int pixel_width, int pixel_height, int pixel_leveli);
113 
114  /// Makes the image as if no samples had been inserted or sampled yet.
115  void clearSamples();
116 
118  {
119  return myInsertedCount;
120  }
121 
122  /// Filters the given plane into the specified raster.
123  void filterPlane(
124  TIL_Raster &raster,
125  int planei) const;
126 
127  const TIL_PixelFilter *getPixelFilter(int planei) const
128  {
129  UT_ASSERT(planei >= 0 && planei < myNumPlanes);
130  if (myPixelFilters && planei >= 0 && planei < myNumPlanes)
131  return myPixelFilters[planei];
132  return nullptr;
133  }
135  {
136  UT_ASSERT(myNumPlanes > 0);
137  if (myNumPlanes <= 0)
138  return;
139  myPixelFilters.reset(new const TIL_PixelFilter*[myNumPlanes]);
140  for (int i = 0; i < myNumPlanes; ++i)
141  myPixelFilters[i] = nullptr;
142  }
143  void setPixelFilter(int planei, const TIL_PixelFilter *filter);
144 
145 private:
146  void updateVarianceEntry(
147  const int cur_x, const int cur_y,
148  const exint cur_i, const int leveli);
149 private:
150  UT_UniquePtr<Level[]> myLevels;
151  exint mySampledCount;
152  exint myInsertedCount;
153  int myAdaptivityPlane;
154  int myRootPowerOf2;
155  int myWidth;
156  int myHeight;
157 
158  /// This is the number of levels that are below the level of the
159  /// final image pixels. These levels are so that extra detail can be
160  /// present for better pixel filtering later, instead of being
161  /// limited to one combined sample per pixel.
162  int myLevelsBelowPixel;
163 
164 #if 0
165  /// If every final image pixel (myLevelsBelowPixel above the lowest level),
166  /// has at least this many samples, and any pixel with more relative noise
167  /// than myRelativeNoiseThreshold has hit myMaxSamplesPerPixel, we can stop.
168  /// This is to ensure that at least enough samples are sent to detect
169  /// possible noise, e.g. in very indirectly lit regions, where most samples
170  /// are all black, but an occasional few are bright.
171  int myMinSamplesPerPixel;
172 #endif
173 
174  /// If every final image pixel (myLevelsBelowPixel above the lowest level),
175  /// has at least myMinSamplesPerPixel samples, and any pixel with more
176  /// relative noise than myRelativeNoiseThreshold has hit this many samples,
177  /// we can stop.
178  /// This is to avoid a few pixels that would effectively never converge
179  /// from preventing an otherwise good render from finishing.
180  int myMaxSamplesPerPixel;
181 
182 #if 0
183  /// If every final image pixel (myLevelsBelowPixel above the lowest level),
184  /// has at least myMinSamplesPerPixel samples, and any pixel with more
185  /// relative noise than this has hit myMaxSamplesPerPixel, we can stop.
186  /// This is effectively the target final relative noise.
187  float myRelativeNoiseThreshold;
188 #endif
189 
190  /// Variables indicating where any priority circle goes.
191  /// @{
192  bool myPriorityCircleOn;
193  float myPriorityCircleX;
194  float myPriorityCircleY;
195  float myPriorityCircleRadius;
196  /// @}
197 
198  int myNumPlanes;
199  UT_UniquePtr<int[]> myPlaneStartComponents;
200  UT_UniquePtr<int[]> myPlaneNumComponents;
202 };
203 
204 #endif
UT_UniquePtr< float[]> myWeights
const Level & getLevel(int leveli) const
UT_UniquePtr< exint[]> mySampledCounts
void setPriorityCircle(float x, float y, float radius)
const TIL_PixelFilter * getPixelFilter(int planei) const
int myWidth
Width of this level in pixels.
GLint y
Definition: glcorearb.h:102
exint getInsertedCount() const
png_uint_32 i
Definition: png.h:2877
UT_Array< UT_UniquePtr< float[]> > mySumsOfSquares
GLint GLsizei width
Definition: glcorearb.h:102
This is the super-duper-class for all pixel filters in TIL.
GLfloat f
Definition: glcorearb.h:1925
unsigned long long uint64
Definition: SYS_Types.h:101
#define UT_ASSERT(ZZ)
Definition: UT_Assert.h:102
int64 exint
Definition: SYS_Types.h:109
void getPriorityCircle(float &x, float &y, float &radius) const
GLboolean * data
Definition: glcorearb.h:130
bool isPriorityCircleOn() const
GLint GLsizei GLsizei height
Definition: glcorearb.h:102
UT_Array< UT_UniquePtr< float[]> > myComponentSums
GLint GLenum GLint x
Definition: glcorearb.h:408
int myHeight
Height of this level in pixels.
UT_UniquePtr< float[]> myAdjustedVariances
#define TIL_API
Definition: TIL_API.h:10
UT_UniquePtr< exint[]> myCounts
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glcorearb.h:1296
int getPixelLevelNum() const