Skip to content

Commit 1b35766

Browse files
committed
add hdr examples, add hdr reading support, fix camera switching when ray generation program changes, prepare for the release
1 parent 2c13c4a commit 1b35766

File tree

8 files changed

+549
-4
lines changed

8 files changed

+549
-4
lines changed

CHANGELOG.rst

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
Release history
22
===============
33

4-
v0.8.1 - unreleased
5-
-------------------
4+
`v0.8.1`_ - 2020-06-14
5+
----------------------
66

77
Added
88
~~~~~
99

1010
- camera mode for baking 360 degree panoramic views
1111
- support 16 bit per channel and hdr (32 bit fp per channel) output to image files and ndarray
12+
- support reading hdr images
1213

1314
Fixed
1415
~~~~~
@@ -344,6 +345,7 @@ v0.1.2.5 - 2019-04-16
344345

345346
Two weeks and some steps from the initial release. Starting changelog relative to this point.
346347

348+
.. _`v0.8.1`: https://github.com/rnd-team-dev/plotoptix/releases/tag/v0.8.1
347349
.. _`v0.8.0`: https://github.com/rnd-team-dev/plotoptix/releases/tag/v0.8.0
348350
.. _`v0.7.2`: https://github.com/rnd-team-dev/plotoptix/releases/tag/v0.7.2
349351
.. _`v0.7.1`: https://github.com/rnd-team-dev/plotoptix/releases/tag/v0.7.1
Lines changed: 320 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,320 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"## High dynamic range and environment maps\n",
8+
"\n",
9+
"This example shows how to:\n",
10+
" - setup camera for baking 360 degree panoramic environment map\n",
11+
" - save image file with 8/16/32 bits per sample color depth\n",
12+
" - use OpenCV to save image in HDR format\n",
13+
"\n",
14+
"![plotoptix ray_tracing_output](https://plotoptix.rnd.team/images/360deg_env_map.jpg \"This notebook output\")\n",
15+
"\n",
16+
"Saving images to jpg format is great when you want to use them quickly, with no additional editing outside your script. Jpg uses 8 bit/sample color depth and lossy compression - such output of your work is ready to go e.g. to the web.\n",
17+
"\n",
18+
"If you plan to apply retouching in an image editing software you'll appreciate saving your renders to a lossless format, with 16 bit/sample color depth. PlotOptiX can do that, tiff (Linux/Windows) and png (Windows) formats are supported.\n",
19+
"\n",
20+
"However, the full information is preserved only if 32 bit/sample, floating point precision data, is saved to a file. Such a high dynamic range (HDR) representation keeps all the bright lights and details in shadows without clamping and rounding errors. Exposure and any tonal corrections can be re-adjusted in HDR images without quality losses. And, most importantly, HDR images are the best for lighting scenes as environment maps - that is what we are going to show in this example. HDR image are written by PlotOptiX natively in tiff format, or you can use OpenCV to save such images in the Radiance file format (.hdr)."
21+
]
22+
},
23+
{
24+
"cell_type": "code",
25+
"execution_count": 1,
26+
"metadata": {},
27+
"outputs": [],
28+
"source": [
29+
"import numpy as np\n",
30+
"from plotoptix import TkOptiX"
31+
]
32+
},
33+
{
34+
"cell_type": "markdown",
35+
"metadata": {},
36+
"source": [
37+
"Generate some data - balls distributed on a sphere:"
38+
]
39+
},
40+
{
41+
"cell_type": "code",
42+
"execution_count": 2,
43+
"metadata": {},
44+
"outputs": [],
45+
"source": [
46+
"n = 2000\n",
47+
"r0 = 0.1\n",
48+
"R = 4\n",
49+
"\n",
50+
"r = r0 + 0.3 * np.random.rand(n)\n",
51+
"\n",
52+
"x = np.random.normal(loc=0, scale=1.0, size=n)\n",
53+
"y = np.random.normal(loc=0, scale=1.0, size=n)\n",
54+
"z = np.random.normal(loc=0, scale=1.0, size=n)\n",
55+
"xyz = np.stack((x, y, z)).T\n",
56+
"for i in range(n): xyz[i] *= R / np.linalg.norm(xyz[i])"
57+
]
58+
},
59+
{
60+
"cell_type": "markdown",
61+
"metadata": {},
62+
"source": [
63+
"A simple function to signal that ray tracing has finished:"
64+
]
65+
},
66+
{
67+
"cell_type": "code",
68+
"execution_count": 3,
69+
"metadata": {},
70+
"outputs": [],
71+
"source": [
72+
"def accum_done(rt: TkOptiX) -> None:\n",
73+
" print(\"rt completed!\")"
74+
]
75+
},
76+
{
77+
"cell_type": "markdown",
78+
"metadata": {},
79+
"source": [
80+
"Setup the ray tracing parameters. **Note** that AI denoiser is NOT applied. It could result with a visible seam at the line joining vertical edges of the image, when the image is displayed as an environment map. Instead, only a gamma correction is used and you need to accumulate enough data to reduce the noise."
81+
]
82+
},
83+
{
84+
"cell_type": "code",
85+
"execution_count": 4,
86+
"metadata": {},
87+
"outputs": [],
88+
"source": [
89+
"rt = TkOptiX(on_rt_accum_done=accum_done)\n",
90+
"rt.set_param(\n",
91+
" min_accumulation_step=2,\n",
92+
" max_accumulation_frames=300\n",
93+
")\n",
94+
"rt.set_uint(\"path_seg_range\", 4, 8) # a little more than the default (2,6) to improve the ambient occlusion impression\n",
95+
"\n",
96+
"exposure = 1; gamma = 2.2\n",
97+
"rt.set_float(\"tonemap_exposure\", exposure)\n",
98+
"rt.set_float(\"tonemap_gamma\", gamma)\n",
99+
"rt.add_postproc(\"Gamma\")"
100+
]
101+
},
102+
{
103+
"cell_type": "markdown",
104+
"metadata": {},
105+
"source": [
106+
"Setup lighting: one bright warm spherical light and some cold light from the ambient."
107+
]
108+
},
109+
{
110+
"cell_type": "code",
111+
"execution_count": 5,
112+
"metadata": {
113+
"scrolled": true
114+
},
115+
"outputs": [],
116+
"source": [
117+
"rt.setup_light(\"l1\", pos=[1.5, 0, 1.5], color=[4.5, 4.2, 3.1], radius=0.75, in_geometry=False)\n",
118+
"\n",
119+
"rt.set_ambient([0.4, 0.6, 0.8])\n",
120+
"rt.set_background(0)"
121+
]
122+
},
123+
{
124+
"cell_type": "markdown",
125+
"metadata": {},
126+
"source": [
127+
"Setup cameras: one for making the panoramic view, one to show balls from inside the sphere, and one looking from a distance."
128+
]
129+
},
130+
{
131+
"cell_type": "code",
132+
"execution_count": 6,
133+
"metadata": {},
134+
"outputs": [],
135+
"source": [
136+
"rt.setup_camera(\"cam1\", cam_type=\"Panoramic\", eye=[0, 0, 0], target=[0, 0, -1], up=[0, 1, 0])\n",
137+
"\n",
138+
"rt.setup_camera(\"cam2\", cam_type=\"DoF\",\n",
139+
" eye=[0, 0, 2], target=[0, 0, 0], up=[0, 1, 0],\n",
140+
" aperture_radius=0.2, fov=45, focal_scale=2.8)\n",
141+
"\n",
142+
"rt.setup_camera(\"cam3\", cam_type=\"DoF\",\n",
143+
" eye=[0, 0, 10], target=[0, 0, 0], up=[0, 1, 0],\n",
144+
" aperture_radius=0.07, fov=35, focal_scale=0.56)"
145+
]
146+
},
147+
{
148+
"cell_type": "markdown",
149+
"metadata": {},
150+
"source": [
151+
"Upload data points:"
152+
]
153+
},
154+
{
155+
"cell_type": "code",
156+
"execution_count": 7,
157+
"metadata": {},
158+
"outputs": [],
159+
"source": [
160+
"rt.set_data(\"points\", pos=xyz, r=r, c=0.7)"
161+
]
162+
},
163+
{
164+
"cell_type": "markdown",
165+
"metadata": {},
166+
"source": [
167+
"Open the GUI window:"
168+
]
169+
},
170+
{
171+
"cell_type": "code",
172+
"execution_count": 8,
173+
"metadata": {
174+
"scrolled": true
175+
},
176+
"outputs": [],
177+
"source": [
178+
"rt.show()"
179+
]
180+
},
181+
{
182+
"cell_type": "markdown",
183+
"metadata": {},
184+
"source": [
185+
"Switch camera views. Let the ray tracing to converge with *cam1* active, this is the image to be used in the next example."
186+
]
187+
},
188+
{
189+
"cell_type": "code",
190+
"execution_count": 9,
191+
"metadata": {
192+
"scrolled": true
193+
},
194+
"outputs": [],
195+
"source": [
196+
"rt.set_current_camera(\"cam2\")"
197+
]
198+
},
199+
{
200+
"cell_type": "code",
201+
"execution_count": 10,
202+
"metadata": {},
203+
"outputs": [
204+
{
205+
"name": "stdout",
206+
"output_type": "stream",
207+
"text": [
208+
"rt completed!\n"
209+
]
210+
}
211+
],
212+
"source": [
213+
"rt.set_current_camera(\"cam1\")"
214+
]
215+
},
216+
{
217+
"cell_type": "markdown",
218+
"metadata": {},
219+
"source": [
220+
"Save images with 8, 16 and 32 bit/sample color depths. 360 degree environment maps can be inspected with the script ``7_panorama_viewer.py`` or used by the notebook ``10_2_read_hdr_360deg_env_map.ipynb``. "
221+
]
222+
},
223+
{
224+
"cell_type": "code",
225+
"execution_count": 11,
226+
"metadata": {},
227+
"outputs": [],
228+
"source": [
229+
"rt.save_image(\"rt_output_8bps.jpg\")"
230+
]
231+
},
232+
{
233+
"cell_type": "code",
234+
"execution_count": 12,
235+
"metadata": {},
236+
"outputs": [],
237+
"source": [
238+
"rt.save_image(\"rt_output_16bps.tif\", bps=\"Bps16\")"
239+
]
240+
},
241+
{
242+
"cell_type": "code",
243+
"execution_count": 13,
244+
"metadata": {},
245+
"outputs": [],
246+
"source": [
247+
"rt.save_image(\"rt_output_32bps.tif\", bps=\"Bps32\")"
248+
]
249+
},
250+
{
251+
"cell_type": "markdown",
252+
"metadata": {},
253+
"source": [
254+
"Save the image also in Radiance file, if you have OpenCV installed."
255+
]
256+
},
257+
{
258+
"cell_type": "code",
259+
"execution_count": 14,
260+
"metadata": {},
261+
"outputs": [
262+
{
263+
"name": "stdout",
264+
"output_type": "stream",
265+
"text": [
266+
"float32 (1084, 1924, 3) 1.2066944\n"
267+
]
268+
},
269+
{
270+
"data": {
271+
"text/plain": [
272+
"True"
273+
]
274+
},
275+
"execution_count": 14,
276+
"metadata": {},
277+
"output_type": "execute_result"
278+
}
279+
],
280+
"source": [
281+
"import cv2\n",
282+
"\n",
283+
"a = rt.get_rt_output(\"Bps32\", \"BGR\") # ray tracing output in 32bps depth and channels order required for .hdr format\n",
284+
"print(a.dtype, a.shape, np.max(a)) # note it is a floating point array, and strong lights are above 1.0 values\n",
285+
"\n",
286+
"cv2.imwrite('rt_output_32bps.hdr', a)"
287+
]
288+
},
289+
{
290+
"cell_type": "code",
291+
"execution_count": 15,
292+
"metadata": {},
293+
"outputs": [],
294+
"source": [
295+
"rt.close()"
296+
]
297+
}
298+
],
299+
"metadata": {
300+
"kernelspec": {
301+
"display_name": "Python 3",
302+
"language": "python",
303+
"name": "python3"
304+
},
305+
"language_info": {
306+
"codemirror_mode": {
307+
"name": "ipython",
308+
"version": 3
309+
},
310+
"file_extension": ".py",
311+
"mimetype": "text/x-python",
312+
"name": "python",
313+
"nbconvert_exporter": "python",
314+
"pygments_lexer": "ipython3",
315+
"version": "3.7.4"
316+
}
317+
},
318+
"nbformat": 4,
319+
"nbformat_minor": 2
320+
}

0 commit comments

Comments
 (0)