Skip to content

Commit eae3b78

Browse files
authored
Merge pull request #47 from rnd-team-dev/r0.16.1
R0.16.1
2 parents 006c492 + 106540b commit eae3b78

File tree

83 files changed

+548
-386
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+548
-386
lines changed

CHANGELOG.rst

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,23 @@
11
Release history
22
===============
33

4+
`v0.16.1` - 2023-06-04
5+
----------------------
6+
7+
**NOTE:** Binaries recompiled with OptiX 7.7, NVIDIA driver r530 or above is required.
8+
9+
Added
10+
~~~~~
11+
12+
- CuPy support for texture and geometry data updates
13+
- New curve geometries: Ribbon, Beziers
14+
15+
Changed
16+
~~~~~~~
17+
18+
- no dedicated PyTorch/CuPy/... methods, all types handled with single corresponding method
19+
20+
421
`v0.16.0` - 2023-05-17
522
----------------------
623

@@ -582,6 +599,7 @@ Added
582599
- this changelog, markdown description content type tag for PyPI
583600
- use [Semantic Versioning](https://semver.org/spec/v2.0.0.html)
584601

602+
.. _`v0.16.1`: https://github.com/rnd-team-dev/plotoptix/releases/tag/v0.16.1
585603
.. _`v0.16.0`: https://github.com/rnd-team-dev/plotoptix/releases/tag/v0.16.0
586604
.. _`v0.15.1`: https://github.com/rnd-team-dev/plotoptix/releases/tag/v0.15.1
587605
.. _`v0.15.0`: https://github.com/rnd-team-dev/plotoptix/releases/tag/v0.15.0

README.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ No need to write shaders, intersection algorithms, handle 3D scene technicalitie
4444

4545
Check `examples on GitHub <https://github.com/rnd-team-dev/plotoptix/tree/master/examples>`__ for practical code samples and `documentation pages <https://plotoptix.rnd.team>`__ for a complete API reference.
4646

47-
PlotOptiX is a set of CUDA shaders by `R&D Team <https://rnd.team>`_ wrapped in C#/C++ libraries with a Python API. PlotOptiX is based on `NVIDIA OptiX 7.6 <https://developer.nvidia.com/optix>`_ framework and makes use of RTX-capable GPU's.
47+
PlotOptiX is a set of CUDA shaders by `R&D Team <https://rnd.team>`_ wrapped in C#/C++ libraries with a Python API. PlotOptiX is based on `NVIDIA OptiX 7.7 <https://developer.nvidia.com/optix>`_ framework and makes use of RTX-capable GPU's.
4848

4949
You can quickly display data in a simple plot:
5050

@@ -68,7 +68,7 @@ Features
6868
- *callbacks*: at the scene initialization, start and end of each frame raytracing, end of progressive accumulation
6969
- 8/16/32bps(hdr) image output to `numpy <https://numpy.org>`__ array, or save to popular image file formats
7070
- zero-copy access to GPU buffers wrapped in ndarrays: 8/32bpc image, hit and object info, albedo, normals
71-
- direct access to `PyTorch <https://pytorch.org>`__ tensors data stored on GPU (and CPU as well) for texture and geometry updates
71+
- direct access to `CuPy <https://cupy.dev>`__ and `PyTorch <https://pytorch.org>`__ tensors data stored on GPU (and CPU as well) for texture and geometry updates
7272
- GPU acceleration using RT Cores and everything else what comes with `OptiX <https://developer.nvidia.com/optix>`__
7373
- hardware accelerated video output to MP4 file format using `NVENC 9.0 <https://developer.nvidia.com/nvidia-video-codec-sdk>`__
7474
- Tkinter based simple GUI window or a headless raytracer
@@ -78,7 +78,7 @@ System Requirements
7878
-------------------
7979

8080
- a `CUDA-enabled GPU <https://developer.nvidia.com/cuda-gpus>`__ with compute capability 5.0 (Maxwell) to latest (Ada Lovelace);
81-
- NVIDIA driver >= r520;
81+
- NVIDIA driver >= r530;
8282
- **Python 3 64-bit**
8383
- Windows:
8484
- Framework .NET >= 4.8 (present in all modern Windows)

docs/npoptix_config.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Start, configure, get output
1818
.. automethod:: plotoptix.NpOptiX._run_event_loop
1919
.. automethod:: plotoptix.NpOptiX.run
2020
.. automethod:: plotoptix.NpOptiX.get_gpu_architecture
21+
.. automethod:: plotoptix.NpOptiX.enable_cupy
2122
.. automethod:: plotoptix.NpOptiX.enable_torch
2223

2324
Scene configuration
@@ -127,9 +128,7 @@ GPU variables related to the raytracer general configuraton are documented below
127128
.. automethod:: plotoptix.NpOptiX.get_float
128129
.. automethod:: plotoptix.NpOptiX.get_float2
129130
.. automethod:: plotoptix.NpOptiX.get_float3
130-
.. automethod:: plotoptix.NpOptiX.set_torch_texture_1d
131131
.. automethod:: plotoptix.NpOptiX.set_texture_1d
132-
.. automethod:: plotoptix.NpOptiX.set_torch_texture_2d
133132
.. automethod:: plotoptix.NpOptiX.set_texture_2d
134133
.. automethod:: plotoptix.NpOptiX.load_texture
135134

examples/1_basics/2_beziers.py

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
"""
2+
With ``Beziers`` geometry you can setup all control points and segments
3+
can be placed independently in contrast to other curve geometries where
4+
all data points are connected or interpolated with a single curve.
5+
6+
This example shows how to:
7+
- create a large set of independent bezier segments
8+
- assign individual colors and radii to each segment
9+
"""
10+
11+
import math
12+
import numpy as np
13+
from plotoptix import TkOptiX
14+
15+
def random3d(n):
16+
phi = np.random.uniform(0, 2 * np.pi, size=n)
17+
costheta = np.random.uniform(-1, 1, size=n)
18+
19+
theta = np.arccos(costheta)
20+
x = np.sin(theta) * np.cos(phi)
21+
y = np.sin(theta) * np.sin(phi)
22+
z = np.cos(theta)
23+
24+
return np.stack([x, y, z], axis=1)
25+
26+
def main():
27+
28+
# create some data
29+
30+
n = 150000
31+
32+
# origins at (0,0,0)
33+
xyz = np.zeros((n, 4, 3))
34+
35+
# control points #1 randomly distributed on the sphere
36+
xyz[:,1,:] = random3d(n)
37+
38+
# endpoints follow the above direction, with some randomization
39+
xyz[:,3,:] = 2 * xyz[:,1,:] + np.array([0, -0.75, 0])
40+
xyz[:,3,:] += 0.75 * (np.random.rand(n, 3) - 0.5)
41+
42+
# control points #2 placed ~over the endpoints, so the curves look like falling down
43+
xyz[:,2,:] = xyz[:,3,:] + np.array([0, 0.5, 0])
44+
xyz[:,2,:] += 0.2 * (np.random.rand(n, 3) - 0.5)
45+
46+
# reshape to have a single sequence of origin-ctrl#1-ctrl#2-endpoint for all segments
47+
xyz = xyz.reshape((4 * n, 3))
48+
49+
c = np.array([
50+
[0.4, 0.1, 0.1],
51+
[0.7, 0.1, 0.1],
52+
[0.9, 0.7, 0.9],
53+
[0.93, 0.93, 0.93],
54+
])
55+
c = np.tile(c, (n, 1))
56+
c += 0.3 * (np.random.rand(4 * n, 3) - 0.5)
57+
c = np.clip(c, 0, 1)
58+
59+
r = np.array([0.003, 0.008, 0.002, 0.0002])
60+
r = np.tile(r, n)
61+
print(xyz.shape, c.shape, r.shape)
62+
63+
# setup ray tracing
64+
65+
rt = TkOptiX()
66+
67+
rt.set_uint("path_seg_range", 8, 24) # more segments to let the light enter between strands
68+
rt.set_background(0.99) # white background
69+
rt.set_ambient(0.15) # dim ambient light
70+
71+
rt.set_data("curve", pos=xyz, r=r, c=c, geom="Beziers")
72+
73+
rt.setup_camera("cam1", # cam_type="DoF",
74+
eye=[-6, 4, 5], target=[0, -0.6, 0],
75+
glock=True
76+
)
77+
78+
rt.setup_light("light1", pos=[-6, 10, 10], color=10*np.array([0.99, 0.9, 0.7]), radius=3, in_geometry=True)
79+
rt.setup_light("light2", pos=[-6, -10, 5], color=20*np.array([0.7, 0.9, 0.99]), radius=2, in_geometry=True)
80+
81+
rt.set_param(max_accumulation_frames=256)
82+
83+
rt.show()
84+
85+
print("done")
86+
87+
if __name__ == '__main__':
88+
main()

examples/1_basics/2_parametric_line_plot_3d.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,16 @@ def main():
4646
rt.set_ambient(0.2) # dim ambient light
4747

4848
# add plot: BezierChain geometry makes a smooth line interpolating data points
49-
#rt.set_data("curve", pos=xyz, r=r, c=0.9, geom="BezierChain")
49+
rt.set_data("curve", pos=xyz, r=r, c=0.9, geom="BezierChain")
5050

5151
# or use SegmentChain for a piecewise-linear plot
5252
#rt.set_data("curve", pos=xyz, r=r, c=0.9, geom="SegmentChain")
5353

5454
# or use b-spline geometry (approximating data points, flat end caps)
5555
#rt.set_data("curve", pos=xyz, r=r, c=0.9, geom="BSplineQuad")
5656
#rt.set_data("curve", pos=xyz, r=r, c=0.9, geom="BSplineCubic")
57-
rt.set_data("curve", pos=xyz, r=r, c=0.9, geom="CatmullRom")
57+
#rt.set_data("curve", pos=xyz, r=r, c=0.9, geom="CatmullRom")
58+
#rt.set_data("curve", pos=xyz, r=r, c=0.9, geom="Ribbon")
5859

5960
# show the UI window here - this method is calling some default
6061
# initialization for us, e.g. creates camera, so any modification

examples/1_basics/6_postprocessing.py

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -24,56 +24,58 @@ def main():
2424
# heights of blocks
2525
v = np.zeros(data.shape); v[:,1] = (Y.flatten() + 0.3 * np.random.rand(n*n))[:]
2626

27-
optix = TkOptiX() # create and configure, show the window later
27+
rt = TkOptiX() # create and configure, show the window later
2828

29-
optix.set_param(max_accumulation_frames=50) # accumulate up to 50 frames
30-
optix.set_background(0) # black background
31-
optix.set_ambient([0, 0.2, 0.4]) # cold ambient light
29+
rt.set_param(max_accumulation_frames=50) # accumulate up to 50 frames
30+
rt.set_background(0) # black background
31+
rt.set_ambient([0, 0.2, 0.4]) # cold ambient light
3232

3333
# add plot geometry
3434
size_u = 0.98 * (rx[1] - rx[0]) / (n - 1)
3535
size_w = 0.98 * (rz[1] - rz[0]) / (n - 1)
36-
optix.set_data("blocks", pos=data,
37-
u=[size_u, 0, 0], v=v, w=[0, 0, size_w],
38-
c = np.random.rand(n*n),
39-
geom="Parallelepipeds")
36+
rt.set_data("blocks", pos=data,
37+
u=[size_u, 0, 0], v=v, w=[0, 0, size_w],
38+
c = np.random.rand(n*n),
39+
geom="Parallelepipeds"
40+
)
4041

4142
# set camera and light position
42-
optix.setup_camera("cam1", cam_type="DoF",
43-
eye=[-0.3, 2, -0.3], target=[1, 1, 1],
44-
fov=60, focal_scale=0.85)
45-
optix.setup_light("light1", pos=[3, 4.5, 1], color=[6, 5, 4.5], radius=2)
43+
rt.setup_camera("cam1", cam_type="DoF",
44+
eye=[-0.3, 2, -0.3], target=[1, 1, 1],
45+
fov=60, focal_scale=0.85
46+
)
47+
rt.setup_light("light1", pos=[3, 4.5, 1], color=[6, 5, 4.5], radius=2)
4648

4749

4850
# Postprocessing configuration - uncomment what you'd like to include
4951
# or comment out all stages to see raw image. Try also combining
5052
# the mask overlay with one of tonal or levels corrections.
5153

5254
# 1. Levels adjustment.
53-
#optix.set_float("levels_low_range", 0.1, 0.05, -0.05)
54-
#optix.set_float("levels_high_range", 0.9, 0.85, 0.8)
55-
#optix.add_postproc("Levels")
55+
#rt.set_float("levels_low_range", 0.1, 0.05, -0.05)
56+
#rt.set_float("levels_high_range", 0.9, 0.85, 0.8)
57+
#rt.add_postproc("Levels")
5658

5759
# 2. Gamma correction.
58-
#optix.set_float("tonemap_exposure", 0.8)
59-
#optix.set_float("tonemap_gamma", 2.2)
60-
#optix.add_postproc("Gamma")
60+
#rt.set_float("tonemap_exposure", 0.8)
61+
#rt.set_float("tonemap_gamma", 2.2)
62+
#rt.add_postproc("Gamma")
6163

6264
# 3. Tonal correction with a custom curve.
63-
optix.set_float("tonemap_exposure", 0.8)
65+
rt.set_float("tonemap_exposure", 0.8)
6466
# correction curve set explicitly:
65-
optix.set_texture_1d("tone_curve_gray", np.sqrt(np.linspace(0, 1, 64)))
67+
rt.set_texture_1d("tone_curve_gray", np.sqrt(np.linspace(0, 1, 64)))
6668
# correction curve calculated from control input/output values
67-
# (convenient if the curve was prepared in an image editor)
68-
#optix.set_correction_curve([[13,51], [54, 127], [170, 192]])
69-
optix.add_postproc("GrayCurve")
69+
# (convenient if the curve was prepared eg in an image editor)
70+
#rt.set_correction_curve([[13,51], [54, 127], [170, 192]])
71+
rt.add_postproc("GrayCurve")
7072

7173
# 4. Tonal correction with a custom RGB curves.
72-
#optix.set_float("tonemap_exposure", 0.8)
73-
#optix.set_texture_1d("tone_curve_r", np.sqrt(np.linspace(0.1, 1, 64)))
74-
#optix.set_texture_1d("tone_curve_g", np.sqrt(np.linspace(0, 1, 64)))
75-
#optix.set_texture_1d("tone_curve_b", np.sqrt(np.linspace(0, 1, 64)))
76-
#optix.add_postproc("RgbCurve")
74+
#rt.set_float("tonemap_exposure", 0.8)
75+
#rt.set_texture_1d("tone_curve_r", np.sqrt(np.linspace(0.15, 1, 64)))
76+
#rt.set_texture_1d("tone_curve_g", np.sqrt(np.linspace(0, 1, 64)))
77+
#rt.set_texture_1d("tone_curve_b", np.sqrt(np.linspace(0, 1, 64)))
78+
#rt.add_postproc("RgbCurve")
7779

7880
# 5. Overlay with a mask.
7981
#mx = (-1, 1)
@@ -89,11 +91,11 @@ def main():
8991

9092
#M = make_color_2d(M, channel_order="RGBA")
9193

92-
#optix.set_texture_2d("frame_mask", M)
93-
#optix.add_postproc("Mask")
94+
#rt.set_texture_2d("frame_mask", M)
95+
#rt.add_postproc("Mask")
9496

9597

96-
optix.start()
98+
rt.start()
9799
print("done")
98100

99101

0 commit comments

Comments
 (0)