<jupyter_start><jupyter_text>OpenSimplex noise trajectories constrained to spheres. More comments to appear...<jupyter_code>import copy
import math
import numpy as np
from matplotlib import cm

from plotoptix import TkOptiX
from plotoptix.materials import m_diffuse, m_plastic, m_metallic, m_clear_glass
from plotoptix.utils import make_color, simplex
b = 60000  # number of curves
n = 100    # nodes per curve
dt = 0.02  # nodes distance
r0 = 0.07  # base thickness

R = 4 * np.sqrt(0.1 + 0.9 * np.random.rand(b))
for c in range(b):
    if np.random.uniform() < 0.045: R[c] = 4.01

inp = np.zeros((b, 3, 4), dtype=np.float32)
x = np.random.normal(loc=0, scale=1.0, size=b)
y = np.random.normal(loc=0, scale=1.0, size=b)
z = np.random.normal(loc=0, scale=1.0, size=b)
xyz = np.stack((x, y, z)).T
for c in range(b):
    xyz[c] *= R[c] / np.linalg.norm(xyz[c])

ofs = 50 * np.random.rand(3)
for c in range(b):
    inp[c,:,:3] = xyz[c]
    inp[c,:,3] = ofs              # sync the 4'th dim of the noise

pos = np.zeros((b, n, 3), dtype=np.float32)
col = np.zeros((b, n, 3), dtype=np.float32)
r = np.zeros((b, n), dtype=np.float32)

rnd = simplex(inp)
for t in range(n):
    rt = 2.0 * (t+1) / (n+2) - 1
    rt = 1 - rt*rt
    r[:,t] = r0 * rt * rt
    for c in range(b):
        mag = np.linalg.norm(rnd[c])
        r[c,t] *= 0.2 + 0.8 * mag
        
        rnd[c] *= dt / mag                # normalize and scale the step size
        s = inp[c,0,:3] + rnd[c]          # make unconstrained step...
        s *= R[c] / np.linalg.norm(s)     # ...target projected onto sphere...
        s -= inp[c,0,:3]                  # ...calculate constrained step...
        s *= 0.02 / np.linalg.norm(s)     # ...and normalize it
        p = s + inp[c,0,:3]               # make the final step
        p *= R[c] / np.linalg.norm(p)     # and the projection to sphere
        
        inp[c,:,:3] = p
        pos[c,t] = p

    rnd = simplex(inp, rnd)            # noise at the next pos
rt = TkOptiX(start_now=False)
rt.set_param(
    min_accumulation_step=2,
    max_accumulation_frames=500,
    rt_timeout=900000,                 # accept low fps
    light_shading="Soft"
)
rt.set_uint("path_seg_range", 6, 12)

exposure = 1.2; gamma = 2.2

rt.load_texture("bg_texture", r"data\starmap_4k.jpg", prescale=0.8, gamma=4)
rt.set_background_mode("TextureEnvironment")

rt.set_float("tonemap_exposure", exposure)
rt.set_float("tonemap_gamma", gamma)
rt.set_float("denoiser_blend", 0.25)
rt.add_postproc("Denoiser")
m_light = copy.deepcopy(m_diffuse)
m_light["VarFloat"] = { "light_emission": 3 }
rt.setup_material("light", m_light)

m_metallic["VarFloat"]["base_roughness"] = 0.004
rt.setup_material("metal", m_metallic)

rt.setup_material("plastic", m_plastic)

m_clear_glass["VarFloat"]["radiation_length"] = 12
m_clear_glass["VarFloat"]["light_emission"] = 0.004
m_clear_glass["VarFloat3"]["refraction_index"] = [ 1.0, 1.0, 1.0 ]
m_clear_glass["VarFloat3"]["subsurface_color"] = [ 0.1, 0.5, 1.0 ]
rt.setup_material("glow", m_clear_glass)
rt.set_data("blueglow", pos=[0, 0, 0], r=4.15, mat="glow", c=1000)
for c in range(b):
    if R[c] > 4:
        rt.set_data("c"+str(c), pos=pos[c], r=0.75*r[c], c=[0.94, 0.93, 0.9], geom="BezierChain", mat="metal")
    
    elif np.random.uniform() < 0.05:
        rt.set_data("c"+str(c), pos=pos[c], r=0.2*r[c], c=[0.4, 0, 0], geom="BezierChain", mat="light")

    else:
        rt.set_data("c"+str(c), pos=pos[c], r=0.25*r[c], c=[0.91, 0.93, 0.98], geom="BezierChain")<jupyter_output><empty_output><jupyter_text>Opent the GUI window:<jupyter_code>rt.setup_camera("dof_cam", eye=[0, 0, 12], target=[0, 0, 0],
                fov=47, focal_scale=0.683, aperture_radius=0.13,
                cam_type="DoF")

#rt.setup_light("l1", pos=[8, -3, 13], color=1.5*np.array([0.99, 0.97, 0.93]), radius=5)
rt.setup_light("l2", pos=[-17, -7, 5], u=[0, 0, -10], v=[0, 14, 0], color=1*np.array([0.25, 0.28, 0.35]), light_type="Parallelogram")
rt.show()<jupyter_output><empty_output><jupyter_text>Go to a lower resolution if you need it for higher fps:<jupyter_code>rt.set_rt_size([900, 900])
rt.set_rt_size([960, 540])<jupyter_output><empty_output><jupyter_text>Use more ray segments (finer image) and longer accumulation steps (perf) for the final render:<jupyter_code>rt.set_uint("path_seg_range", 10, 20)
rt.set_param(min_accumulation_step=8, max_accumulation_frames=500, rt_timeout=1000000)<jupyter_output><empty_output><jupyter_text>And set the final render resolution:<jupyter_code>rt.set_rt_size([3540, 3540])
rt.set_rt_size([5760, 3240])<jupyter_output><empty_output><jupyter_text>Save the image:<jupyter_code>rt.save_image("simplex_noise_scene.jpg")<jupyter_output><empty_output><jupyter_text>And we're done:<jupyter_code>rt.close()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.17615062761506275, 'fraction_numerical': 0.05564853556485356, 'mean_word_length': 3.8147029204431018, 'pattern_counts': {'":': 1, '<': 31, '<?xml version=': 0, '>': 30, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '454417', 'license': 'libtiff', 'n_tokens_mistral': 2158, 'n_tokens_neox': 1965, 'n_words': 395, 'path': 'examples/3_projects/simplex/simplex_curves-in-sphere.ipynb', 'repo_name': 'robertsulej/plotoptix', 'size': '4780'}