Skip to content

Commit 31e637a

Browse files
committed
Merge pull request PixarAnimationStudios#3183 from pmolodo/pr/hdEmbree-random-seed
[hdEmbree] add HDEMBREE_RANDOM_NUMBER_SEED (hdEmbree-UsdLux-PR01) (Internal change: 2341333)
2 parents c219fcf + f53d3e6 commit 31e637a

File tree

7 files changed

+110
-34
lines changed

7 files changed

+110
-34
lines changed

pxr/imaging/plugin/hdEmbree/config.cpp

+43-17
Original file line numberDiff line numberDiff line change
@@ -20,26 +20,49 @@ TF_INSTANTIATE_SINGLETON(HdEmbreeConfig);
2020
// Each configuration variable has an associated environment variable.
2121
// The environment variable macro takes the variable name, a default value,
2222
// and a description...
23-
TF_DEFINE_ENV_SETTING(HDEMBREE_SAMPLES_TO_CONVERGENCE, 100,
24-
"Samples per pixel before we stop rendering (must be >= 1)");
23+
TF_DEFINE_ENV_SETTING(
24+
HDEMBREE_SAMPLES_TO_CONVERGENCE,
25+
HdEmbreeDefaultSamplesToConvergence,
26+
"Samples per pixel before we stop rendering (must be >= 1)");
2527

26-
TF_DEFINE_ENV_SETTING(HDEMBREE_TILE_SIZE, 8,
27-
"Size (per axis) of threading work units (must be >= 1)");
28+
TF_DEFINE_ENV_SETTING(
29+
HDEMBREE_TILE_SIZE,
30+
HdEmbreeDefaultTileSize,
31+
"Size (per axis) of threading work units (must be >= 1)");
2832

29-
TF_DEFINE_ENV_SETTING(HDEMBREE_AMBIENT_OCCLUSION_SAMPLES, 16,
30-
"Ambient occlusion samples per camera ray (must be >= 0; a value of 0 disables ambient occlusion)");
33+
TF_DEFINE_ENV_SETTING(
34+
HDEMBREE_AMBIENT_OCCLUSION_SAMPLES,
35+
HdEmbreeDefaultAmbientOcclusionSamples,
36+
"Ambient occlusion samples per camera ray (must be >= 0;"
37+
" a value of 0 disables ambient occlusion)");
3138

32-
TF_DEFINE_ENV_SETTING(HDEMBREE_JITTER_CAMERA, 1,
33-
"Should HdEmbree jitter camera rays while rendering? (values >0 are true)");
39+
TF_DEFINE_ENV_SETTING(
40+
HDEMBREE_JITTER_CAMERA,
41+
HdEmbreeDefaultJitterCamera,
42+
"Should HdEmbree jitter camera rays while rendering?");
3443

35-
TF_DEFINE_ENV_SETTING(HDEMBREE_USE_FACE_COLORS, 1,
36-
"Should HdEmbree use face colors while rendering? (values > 0 are true)");
44+
TF_DEFINE_ENV_SETTING(
45+
HDEMBREE_USE_FACE_COLORS,
46+
HdEmbreeDefaultUseFaceColors,
47+
"Should HdEmbree use face colors while rendering?");
3748

38-
TF_DEFINE_ENV_SETTING(HDEMBREE_CAMERA_LIGHT_INTENSITY, 300,
39-
"Intensity of the camera light, specified as a percentage of <1,1,1>.");
49+
TF_DEFINE_ENV_SETTING(
50+
HDEMBREE_CAMERA_LIGHT_INTENSITY,
51+
HdEmbreeDefaultCameraLightIntensity,
52+
"Intensity of the camera light, specified as a percentage of <1,1,1>.");
4053

41-
TF_DEFINE_ENV_SETTING(HDEMBREE_PRINT_CONFIGURATION, 0,
42-
"Should HdEmbree print configuration on startup? (values > 0 are true)");
54+
TF_DEFINE_ENV_SETTING(
55+
HDEMBREE_RANDOM_NUMBER_SEED,
56+
HdEmbreeDefaultRandomNumberSeed,
57+
"Seed to give to the random number generator. A value of anything other"
58+
" than -1, combined with setting PXR_WORK_THREAD_LIMIT=1, should"
59+
" give deterministic / repeatable results. A value of -1 (the"
60+
" default) will allow the implementation to set a value that varies"
61+
" from invocation to invocation and thread to thread.");
62+
63+
TF_DEFINE_ENV_SETTING(HDEMBREE_PRINT_CONFIGURATION,
64+
false,
65+
"Should HdEmbree print configuration on startup?");
4366

4467
HdEmbreeConfig::HdEmbreeConfig()
4568
{
@@ -50,12 +73,13 @@ HdEmbreeConfig::HdEmbreeConfig()
5073
TfGetEnvSetting(HDEMBREE_TILE_SIZE));
5174
ambientOcclusionSamples = std::max(0,
5275
TfGetEnvSetting(HDEMBREE_AMBIENT_OCCLUSION_SAMPLES));
53-
jitterCamera = (TfGetEnvSetting(HDEMBREE_JITTER_CAMERA) > 0);
54-
useFaceColors = (TfGetEnvSetting(HDEMBREE_USE_FACE_COLORS) > 0);
76+
jitterCamera = (TfGetEnvSetting(HDEMBREE_JITTER_CAMERA));
77+
useFaceColors = (TfGetEnvSetting(HDEMBREE_USE_FACE_COLORS));
5578
cameraLightIntensity = (std::max(100,
5679
TfGetEnvSetting(HDEMBREE_CAMERA_LIGHT_INTENSITY)) / 100.0f);
80+
randomNumberSeed = TfGetEnvSetting(HDEMBREE_RANDOM_NUMBER_SEED);
5781

58-
if (TfGetEnvSetting(HDEMBREE_PRINT_CONFIGURATION) > 0) {
82+
if (TfGetEnvSetting(HDEMBREE_PRINT_CONFIGURATION)) {
5983
std::cout
6084
<< "HdEmbree Configuration: \n"
6185
<< " samplesToConvergence = "
@@ -70,6 +94,8 @@ HdEmbreeConfig::HdEmbreeConfig()
7094
<< useFaceColors << "\n"
7195
<< " cameraLightIntensity = "
7296
<< cameraLightIntensity << "\n"
97+
<< " randomNumberSeed = "
98+
<< randomNumberSeed << "\n"
7399
;
74100
}
75101
}

pxr/imaging/plugin/hdEmbree/config.h

+32-10
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,16 @@
1212

1313
PXR_NAMESPACE_OPEN_SCOPE
1414

15+
// NOTE: types here restricted to bool/int/string, as also used for
16+
// TF_DEFINE_ENV_SETTING
17+
constexpr int HdEmbreeDefaultSamplesToConvergence = 100;
18+
constexpr int HdEmbreeDefaultTileSize = 8;
19+
constexpr int HdEmbreeDefaultAmbientOcclusionSamples = 16;
20+
constexpr bool HdEmbreeDefaultJitterCamera = true;
21+
constexpr bool HdEmbreeDefaultUseFaceColors = true;
22+
constexpr int HdEmbreeDefaultCameraLightIntensity = 300;
23+
constexpr int HdEmbreeDefaultRandomNumberSeed = -1;
24+
1525
/// \class HdEmbreeConfig
1626
///
1727
/// This class is a singleton, holding configuration parameters for HdEmbree.
@@ -27,45 +37,57 @@ PXR_NAMESPACE_OPEN_SCOPE
2737
///
2838
class HdEmbreeConfig {
2939
public:
40+
3041
/// \brief Return the configuration singleton.
3142
static const HdEmbreeConfig &GetInstance();
3243

3344
/// How many samples do we need before a pixel is considered
3445
/// converged?
3546
///
3647
/// Override with *HDEMBREE_SAMPLES_TO_CONVERGENCE*.
37-
unsigned int samplesToConvergence;
48+
unsigned int samplesToConvergence = HdEmbreeDefaultSamplesToConvergence;
3849

3950
/// How many pixels are in an atomic unit of parallel work?
4051
/// A work item is a square of size [tileSize x tileSize] pixels.
4152
///
4253
/// Override with *HDEMBREE_TILE_SIZE*.
43-
unsigned int tileSize;
54+
unsigned int tileSize = HdEmbreeDefaultTileSize;
4455

4556
/// How many ambient occlusion rays should we generate per
4657
/// camera ray?
4758
///
4859
/// Override with *HDEMBREE_AMBIENT_OCCLUSION_SAMPLES*.
49-
unsigned int ambientOcclusionSamples;
60+
unsigned int ambientOcclusionSamples = HdEmbreeDefaultAmbientOcclusionSamples;
5061

5162
/// Should the renderpass jitter camera rays for antialiasing?
5263
///
53-
/// Override with *HDEMBREE_JITTER_CAMERA*. Integer values greater than
54-
/// zero are considered "true".
55-
bool jitterCamera;
64+
/// Override with *HDEMBREE_JITTER_CAMERA*. The case-insensitive strings
65+
/// "true", "yes", "on", and "1" are considered true; an empty value uses
66+
/// the default, and all other values are false.
67+
bool jitterCamera = HdEmbreeDefaultJitterCamera;
5668

5769
/// Should the renderpass use the color primvar, or flat white colors?
5870
/// (Flat white shows off ambient occlusion better).
5971
///
60-
/// Override with *HDEMBREE_USE_FACE_COLORS*. Integer values greater than
61-
/// zero are considered "true".
62-
bool useFaceColors;
72+
/// Override with *HDEMBREE_USE_FACE_COLORS*. The case-insensitive strings
73+
/// "true", "yes", "on", and "1" are considered true; an empty value uses
74+
/// the default, and all other values are false.
75+
bool useFaceColors = HdEmbreeDefaultUseFaceColors;
6376

6477
/// What should the intensity of the camera light be, specified as a
6578
/// percent of <1, 1, 1>. For example, 300 would be <3, 3, 3>.
6679
///
6780
/// Override with *HDEMBREE_CAMERA_LIGHT_INTENSITY*.
68-
float cameraLightIntensity;
81+
float cameraLightIntensity = HdEmbreeDefaultCameraLightIntensity;
82+
83+
/// Seed to give to the random number generator. A value of anything other
84+
/// than -1, combined with setting PXR_WORK_THREAD_LIMIT=1, should give
85+
/// deterministic / repeatable results. A value of -1 (the default) will
86+
/// allow the implementation to set a value that varies from invocation to
87+
/// invocation and thread to thread.
88+
///
89+
/// Override with *HDEMBREE_RANDOM_NUMBER_SEED*.
90+
int randomNumberSeed = HdEmbreeDefaultRandomNumberSeed;
6991

7092
private:
7193
// The constructor initializes the config variables with their

pxr/imaging/plugin/hdEmbree/renderDelegate.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ void
9999
HdEmbreeRenderDelegate::_Initialize()
100100
{
101101
// Initialize the settings and settings descriptors.
102-
_settingDescriptors.resize(4);
102+
_settingDescriptors.resize(5);
103103
_settingDescriptors[0] = { "Enable Scene Colors",
104104
HdEmbreeRenderSettingsTokens->enableSceneColors,
105105
VtValue(HdEmbreeConfig::GetInstance().useFaceColors) };
@@ -112,6 +112,9 @@ HdEmbreeRenderDelegate::_Initialize()
112112
_settingDescriptors[3] = { "Samples To Convergence",
113113
HdRenderSettingsTokens->convergedSamplesPerPixel,
114114
VtValue(int(HdEmbreeConfig::GetInstance().samplesToConvergence)) };
115+
_settingDescriptors[4] = { "Random Number Seed",
116+
HdEmbreeRenderSettingsTokens->randomNumberSeed,
117+
VtValue(HdEmbreeConfig::GetInstance().randomNumberSeed) };
115118
_PopulateDefaultSettings(_settingDescriptors);
116119

117120
// Initialize the embree library handle (_rtcDevice).

pxr/imaging/plugin/hdEmbree/renderDelegate.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ class HdEmbreeRenderParam;
2323
#define HDEMBREE_RENDER_SETTINGS_TOKENS \
2424
(enableAmbientOcclusion) \
2525
(enableSceneColors) \
26-
(ambientOcclusionSamples)
26+
(ambientOcclusionSamples) \
27+
(randomNumberSeed)
2728

2829
// Also: HdRenderSettingsTokens->convergedSamplesPerPixel
2930

pxr/imaging/plugin/hdEmbree/renderPass.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ HdEmbreeRenderPass::_Execute(HdRenderPassStateSharedPtr const& renderPassState,
113113
renderDelegate->GetRenderSetting<bool>(
114114
HdEmbreeRenderSettingsTokens->enableSceneColors, true));
115115

116+
_renderer->SetRandomNumberSeed(
117+
renderDelegate->GetRenderSetting<unsigned int>(
118+
HdEmbreeRenderSettingsTokens->randomNumberSeed, (unsigned int)-1));
119+
116120
needStartRender = true;
117121
}
118122

pxr/imaging/plugin/hdEmbree/renderer.cpp

+16-4
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,12 @@ HdEmbreeRenderer::SetEnableSceneColors(bool enableSceneColors)
6969
_enableSceneColors = enableSceneColors;
7070
}
7171

72+
void
73+
HdEmbreeRenderer::SetRandomNumberSeed(int randomNumberSeed)
74+
{
75+
_randomNumberSeed = randomNumberSeed;
76+
}
77+
7278
void
7379
HdEmbreeRenderer::SetDataWindow(const GfRect2i &dataWindow)
7480
{
@@ -432,8 +438,8 @@ HdEmbreeRenderer::Render(HdRenderThread *renderThread)
432438
// Always pass the renderThread to _RenderTiles to allow the first frame
433439
// to be interrupted.
434440
WorkParallelForN(numTilesX*numTilesY,
435-
std::bind(&HdEmbreeRenderer::_RenderTiles, this, renderThread,
436-
std::placeholders::_1, std::placeholders::_2));
441+
std::bind(&HdEmbreeRenderer::_RenderTiles, this,
442+
renderThread, i, std::placeholders::_1, std::placeholders::_2));
437443

438444
// After the first pass, mark the single-sampled attachments as
439445
// converged and unmap them. If there are no multisampled attachments,
@@ -472,7 +478,7 @@ HdEmbreeRenderer::Render(HdRenderThread *renderThread)
472478
}
473479

474480
void
475-
HdEmbreeRenderer::_RenderTiles(HdRenderThread *renderThread,
481+
HdEmbreeRenderer::_RenderTiles(HdRenderThread *renderThread, int sampleNum,
476482
size_t tileStart, size_t tileEnd)
477483
{
478484
const unsigned int minX = _dataWindow.GetMinX();
@@ -497,8 +503,14 @@ HdEmbreeRenderer::_RenderTiles(HdRenderThread *renderThread,
497503

498504
// Initialize the RNG for this tile (each tile creates one as
499505
// a lazy way to do thread-local RNGs).
500-
size_t seed = std::chrono::system_clock::now().time_since_epoch().count();
506+
size_t seed;
507+
if (_randomNumberSeed == -1) {
508+
seed = std::chrono::system_clock::now().time_since_epoch().count();
509+
} else {
510+
seed = static_cast<size_t>(_randomNumberSeed);
511+
}
501512
seed = TfHash::Combine(seed, tileStart);
513+
seed = TfHash::Combine(seed, sampleNum);
502514
std::default_random_engine random(seed);
503515

504516
// Create a uniform distribution for jitter calculations.

pxr/imaging/plugin/hdEmbree/renderer.h

+9-1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,12 @@ class HdEmbreeRenderer final
8181
/// everything as white.
8282
void SetEnableSceneColors(bool enableSceneColors);
8383

84+
/// Sets a number to seed the random number generator with.
85+
/// \param randomNumberSeed If -1, then the random number generator
86+
/// is seeded in a non-deterministic way;
87+
/// otherwise, it is seeded with this value.
88+
void SetRandomNumberSeed(int randomNumberSeed);
89+
8490
/// Rendering entrypoint: add one sample per pixel to the whole sample
8591
/// buffer, and then loop until the image is converged. After each pass,
8692
/// the image will be resolved into a color buffer.
@@ -115,7 +121,7 @@ class HdEmbreeRenderer final
115121
// work. For each tile, iterate over pixels in the tile, generating camera
116122
// rays, and following them/calculating color with _TraceRay. This function
117123
// renders all tiles between tileStart and tileEnd.
118-
void _RenderTiles(HdRenderThread *renderThread,
124+
void _RenderTiles(HdRenderThread *renderThread, int sampleNum,
119125
size_t tileStart, size_t tileEnd);
120126

121127
// Cast a ray into the scene and if it hits an object, write to the bound
@@ -184,6 +190,8 @@ class HdEmbreeRenderer final
184190
int _ambientOcclusionSamples;
185191
// Should we enable scene colors?
186192
bool _enableSceneColors;
193+
// If other than -1, use this to seed the random number generator with.
194+
int _randomNumberSeed;
187195

188196
// How many samples have been completed.
189197
std::atomic<int> _completedSamples;

0 commit comments

Comments
 (0)