This repository was archived by the owner on Jan 15, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpssmltprimitivepath.h
More file actions
126 lines (105 loc) · 3.65 KB
/
pssmltprimitivepath.h
File metadata and controls
126 lines (105 loc) · 3.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#pragma once
#include "common/wurst.h"
#include "common/camera.h"
#include "common/mlt.h"
#include "common/parallel.h"
#include "common/renderer.h"
#include "common/scene.h"
#include "common/sampler.h"
#include "renderer/primitivepath.h"
struct PssmltPrimitivePathRenderer : public SingleCameraRenderer
{
PssmltPrimitivePathRenderer(shared_ptr<const Camera> & camera,
shared_ptr<const Scene> & scene,
shared_ptr<Sampler> & sampler,
const int mNumPathVertices,
const int numSamples) :
SingleCameraRenderer(camera, scene, sampler),
mNumVertices(mNumPathVertices),
mNumSamples(numSamples * Math::Volume(camera->mFilm->mResolution)),
mBaseRenderer(camera, scene, sampler, mNumPathVertices, 0, false)
{
}
// note: changed on 6 July 2019. Untested
PssmltState perturbAndEval(const PssmltState & prev, const bool isLargeStep, Rng * rng) const
{
PssmltState result = (isLargeStep) ? PssmltState::PerturbPrimarySampleLarge(prev, rng) : PssmltState::PerturbPrimarySampleSmall(prev, rng);
PssmltSampler pssmltSampler(&result.mPrimarySample);
Splat splat;
mBaseRenderer.evalContribution(&splat, &pssmltSampler);
result.mContrib = splat.mContrib;
result.mRaster = splat.mRaster;
result.mScalarContrib = Math::Length(result.mContrib);
return result;
}
void render() override
{
// scale the whole image down by numsamples
mCamera->mFilm->mAtomicScalingFactor.store(1.0 / static_cast<double>(mNumSamples));
Rng rng(0);
int numNormalizationFactorSamples = 0;
// estimate normalization factor
double b = 0.0;
PssmltState state(mNumVertices * 2);
for (int iB = 0; iB < 1000000; iB++)
{
b += perturbAndEval(state, true, &rng).mScalarContrib;
numNormalizationFactorSamples += 1;
}
int numDesiredMutationPerWorkUnit = 200000;
std::mutex mutex;
int numCurrentSamples = 0;
Parallel::Split(0, mNumSamples, numDesiredMutationPerWorkUnit, [&](const int start, const int end)
{
Rng rng(start);
PssmltState current = perturbAndEval(state, true, &rng);
int localNumLargeStep = 0;
double localB = 0.0;
for (int iMutation = start; iMutation < end; iMutation++)
{
const bool doPerturbLarge = (rng.nextFloat() < 0.3);
PssmltState proposed = perturbAndEval(current, doPerturbLarge, &rng);
const double acceptanceProb = (current.mScalarContrib == 0.0) ? 1.0 : std::min(1.0, proposed.mScalarContrib / current.mScalarContrib);
if (doPerturbLarge)
{
localNumLargeStep += 1;
localB += proposed.mScalarContrib;
}
// splat proposed
if (proposed.mScalarContrib != 0.0)
{
mCamera->mFilm->atomicAddSample(proposed.mRaster, proposed.mContrib * acceptanceProb / proposed.mScalarContrib);
}
// splat current
if (current.mScalarContrib != 0.0)
{
mCamera->mFilm->atomicAddSample(current.mRaster, current.mContrib * (1.0 - acceptanceProb) / current.mScalarContrib);
}
if (rng.nextFloat() <= acceptanceProb)
{
current = proposed;
}
// update film result
if ((iMutation + 1) % 5000000 == 0)
{
mutex.lock();
numCurrentSamples += 5000000;
b += localB;
numNormalizationFactorSamples += localNumLargeStep;
mCamera->mFilm->mAtomicScalingFactor.store(b / static_cast<double>(numNormalizationFactorSamples * numCurrentSamples));
if (numCurrentSamples % 100000000 == 0)
{
std::cout << "write" << std::endl;
std::string filename = "result_" + std::to_string(numCurrentSamples) + ".pfm";
FimageIo::Save(mCamera->mFilm->getImage(), filename);
}
mutex.unlock();
Viewer::Redraw(mCamera->mFilm);
}
}
});
}
int mNumVertices;
int mNumSamples;
PrimitivePathRenderer mBaseRenderer;
};