-
Notifications
You must be signed in to change notification settings - Fork 0
/
path_tracing_render.py
168 lines (112 loc) · 4.51 KB
/
path_tracing_render.py
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
import drjit as dr
import mitsuba as mi
if __name__ == '__main__':
mi.set_variant('cuda_ad_rgb')
from src.path_tracing_integrator_py import PathTracingIntegrator
import matplotlib.pyplot as plt
from src.file_name_manager import FileNameManager
FileNameManager.setSceneName('')
import pathlib
from src.common import PerformanceData, printTitle, printBoldUnderLine
from random import randint
import time
import progressbar
"""
Use as a benchmark renderer
"""
if __name__ == '__main__':
# Load scene
# scene = mi.load_file('scenes/cornell-box/scene.xml')
# scene = mi.load_file('scenes/torus/scene.xml')
# scene = mi.load_file('scenes/veach-bidir/scene.xml')
# scene = mi.load_file('scenes/veach-ajar/scene.xml')
scene = mi.load_file('scenes/kitchen/scene.xml')
sceneName = 'kitchen' # for file saving
# Load ground truth
groundTruthFileName = 'scenes/kitchen/TungstenRender.exr'
groundTruthImg = mi.TensorXf( mi.Bitmap( groundTruthFileName ) )
# film_size = scene.sensors()[0].film().size()
# imgShape = film_size[0] * film_size[1]
# groundTruthImg = dr.zeros( mi.Float, shape= imgShape * 3 )
groundTruth = dr.unravel( mi.Color3f, groundTruthImg.array )
pathTracingIntegrator: PathTracingIntegrator = scene.integrator()
# Define desired SPP and chunk size
target_spp = 40
isTimeBudget = True # if this is true then it overrides target_spp
timeBudget = 1000 # in secs
chunkSize = 4
# Record variance data
variance_groundTruth_record = PerformanceData()
cumm_time = 0
used_spp = 0
image_acc = None
# Set to 0 if want reproductibility across simulation
initiali_seed = randint(0, 1000000)
printBoldUnderLine('Initial seed:', initiali_seed)
# normal-integrator folder path for saving image
folderPath = f'{FileNameManager.DEBUG_FOLDER_PATH}/normal-integrator/{sceneName}/'
pathlib.Path( folderPath ).mkdir( parents= True, exist_ok= True )
# Render progress bar
render_progressbar = progressbar.ProgressBar(maxval= 100, widgets=[progressbar.Bar('=', 'Render progress [', ']'), ' ', progressbar.Percentage()])
render_progressbar.start()
if not isTimeBudget:
# Calculate SPP per batch
numChunks = target_spp // chunkSize
spp_arr = [chunkSize] * numChunks
remainingSPP = target_spp % chunkSize
if remainingSPP != 0:
spp_arr.append( remainingSPP )
for i, spp in enumerate( spp_arr ):
start_render_time = time.perf_counter()
# Render
image = mi.render( scene, seed= initiali_seed + i, spp= spp )
if image_acc is None:
image_acc = image
else:
image_acc += image
dr.eval( image_acc )
used_spp += spp
mse = pathTracingIntegrator.computeMSE( used_spp, groundTruth )
variance = pathTracingIntegrator.computeVariance( used_spp, groundTruth )
end_render_time = time.perf_counter()
elapse_render_time = end_render_time - start_render_time
curr_time = elapse_render_time + cumm_time
cumm_time += elapse_render_time
# Record variance
variance_groundTruth_record.append( time= curr_time, spp= used_spp, iteration= 0, variance= variance, mse= mse )
render_progressbar.update( round( 100 * used_spp / target_spp ) )
# Save image
image = image_acc / (i+1)
mi.util.write_bitmap( f'{folderPath}{sceneName}-{used_spp}.png', image )
mi.util.write_bitmap( f'{folderPath}{sceneName}-{used_spp}.exr', image )
else:
pass_count = 0
start_render_time = time.perf_counter()
while cumm_time < timeBudget:
# Render
image = mi.render( scene, seed= initiali_seed + pass_count, spp= chunkSize )
pass_count += 1
if image_acc is None:
image_acc = image
else:
image_acc += image
dr.eval( image_acc )
used_spp += chunkSize
mse = pathTracingIntegrator.computeMSE( used_spp, groundTruth )
variance = pathTracingIntegrator.computeVariance( used_spp, groundTruth )
now_time = time.perf_counter()
cumm_time = now_time - start_render_time
# Record variance
variance_groundTruth_record.append( time= cumm_time, spp= used_spp, iteration= 0, variance= variance, mse= mse )
render_progressbar.update( round( 100 * min( 1, cumm_time / timeBudget) ) )
# Save image
image = image_acc / pass_count
mi.util.write_bitmap( f'{folderPath}{sceneName}-{used_spp}.png', image )
mi.util.write_bitmap( f'{folderPath}{sceneName}-{used_spp}.exr', image )
render_progressbar.finish()
# Save plot data
variance_groundTruth_record.saveToFile( f'{folderPath}{sceneName}_variance_groundTruth_path_tracing_py.csv' )
# Render image
plt.axis("off")
plt.imshow( image ** (1.0 / 2.2) ); # approximate sRGB tonemapping
plt.show()