Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ A slotted-actions Z-rotation turntable keyed through the cross-version channelba
</tr>
<tr>
<td width="46%" valign="middle">
<a href="examples/gn-sdf-remesh/"><img src="examples/gn-sdf-remesh/preview.webp" alt="Geometry Nodes SDF remesh: a smooth torus (before) beside its voxel-remeshed result (after)" /></a>
<a href="examples/gn-sdf-remesh/"><img src="examples/gn-sdf-remesh/preview.webp" alt="Geometry Nodes SDF remesh: a crimson ceramic torus with visible voxel-remesh facets, resting on a dark studio floor" /></a>
</td>
<td valign="middle">

Expand All @@ -95,7 +95,7 @@ and that a `Set Material` node carries the material through the remesh.
</tr>
<tr>
<td width="46%" valign="middle">
<a href="examples/depsgraph-export/"><img src="examples/depsgraph-export/preview.webp" alt="Depsgraph-evaluated export: a faceted base cube (before) beside its smooth subdivision-surface evaluated form (after), rendered with EEVEE" /></a>
<a href="examples/depsgraph-export/"><img src="examples/depsgraph-export/preview.webp" alt="Depsgraph-evaluated export: a matte graphite base cube beside its glossy green subdivision-surface evaluated form on a dark studio floor" /></a>
</td>
<td valign="middle">

Expand All @@ -109,7 +109,7 @@ modifier-applied geometry (exported vertex count == evaluated > base).
</tr>
<tr>
<td width="46%" valign="middle">
<a href="examples/wave-displace/"><img src="examples/wave-displace/preview.webp" alt="Wave displace: a dense grid displaced into smooth standing-wave dunes, rendered with EEVEE" /></a>
<a href="examples/wave-displace/"><img src="examples/wave-displace/preview.webp" alt="Wave displace: a glossy sapphire-blue surface displaced into smooth standing-wave dunes against a black backdrop" /></a>
</td>
<td valign="middle">

Expand All @@ -123,7 +123,7 @@ the Z span matches the amplitude, and a probe vertex matches the closed-form wav
</tr>
<tr>
<td width="46%" valign="middle">
<a href="examples/driver-wave/"><img src="examples/driver-wave/preview.webp" alt="Driver wave: sixteen columns whose heights form a sine skyline, each driven by a driver_namespace function, rendered with EEVEE" /></a>
<a href="examples/driver-wave/"><img src="examples/driver-wave/preview.webp" alt="Driver wave: sixteen orange columns whose heights form a sine skyline on a dark studio floor, each driven by a driver_namespace function" /></a>
</td>
<td valign="middle">

Expand Down
Binary file modified docs/gallery/assets/depsgraph-export-hero.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/gallery/assets/driver-wave-hero.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/gallery/assets/gn-sdf-remesh-hero.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/gallery/assets/wave-displace-hero.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 19 additions & 7 deletions docs/gallery/driver-wave/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -288,8 +288,8 @@ <h2>Source</h2>
mat = bpy.data.materials.new(<span class="s">&quot;ColMat&quot;</span>)
mat.use_nodes = <span class="k">True</span>
bsdf = mat.node_tree.nodes[<span class="s">&quot;Principled BSDF&quot;</span>]
bsdf.inputs[<span class="s">&quot;Base Color&quot;</span>].default_value = (<span class="n">0.62</span>, <span class="n">0.68</span>, <span class="n">0.78</span>, <span class="n">1.0</span>)
bsdf.inputs[<span class="s">&quot;Roughness&quot;</span>].default_value = <span class="n">0.45</span>
bsdf.inputs[<span class="s">&quot;Base Color&quot;</span>].default_value = (<span class="n">1.0</span>, <span class="n">0.26</span>, <span class="n">0.012</span>, <span class="n">1.0</span>) <span class="c"># selection orange</span>
bsdf.inputs[<span class="s">&quot;Roughness&quot;</span>].default_value = <span class="n">0.32</span>
objs[<span class="n">0</span>].data.materials.append(mat) <span class="c"># shared mesh -&gt; all columns</span>

<span class="c"># columns stand on the floor: lift each by its DRIVEN half-height</span>
Expand All @@ -308,26 +308,38 @@ <h2>Source</h2>
fmat = bpy.data.materials.new(<span class="s">&quot;FloorMat&quot;</span>)
fmat.use_nodes = <span class="k">True</span>
fb = fmat.node_tree.nodes[<span class="s">&quot;Principled BSDF&quot;</span>]
fb.inputs[<span class="s">&quot;Base Color&quot;</span>].default_value = (<span class="n">0.55</span>, <span class="n">0.57</span>, <span class="n">0.62</span>, <span class="n">1.0</span>)
fb.inputs[<span class="s">&quot;Roughness&quot;</span>].default_value = <span class="n">0.9</span>
fb.inputs[<span class="s">&quot;Base Color&quot;</span>].default_value = (<span class="n">0.055</span>, <span class="n">0.06</span>, <span class="n">0.07</span>, <span class="n">1.0</span>) <span class="c"># dark graphite studio</span>
fb.inputs[<span class="s">&quot;Roughness&quot;</span>].default_value = <span class="n">0.5</span>
floor_me.materials.append(fmat)
scene.collection.objects.link(floor)
wall = bpy.data.objects.new(<span class="s">&quot;Wall&quot;</span>, floor_me.copy())
wall.location = (<span class="n">0.0</span>, <span class="n">9.0</span>, <span class="n">0.0</span>)
wall.rotation_euler = (math.radians(<span class="n">90</span>), <span class="n">0.0</span>, <span class="n">0.0</span>)
scene.collection.objects.link(wall)

world = bpy.data.worlds.new(<span class="s">&quot;World&quot;</span>)
world.use_nodes = <span class="k">True</span>
world.node_tree.nodes[<span class="s">&quot;Background&quot;</span>].inputs[<span class="s">&quot;Color&quot;</span>].default_value = (<span class="n">0.045</span>, <span class="n">0.05</span>, <span class="n">0.06</span>, <span class="n">1.0</span>)
world.node_tree.nodes[<span class="s">&quot;Background&quot;</span>].inputs[<span class="s">&quot;Color&quot;</span>].default_value = (<span class="n">0.008</span>, <span class="n">0.009</span>, <span class="n">0.012</span>, <span class="n">1.0</span>)
scene.world = world

key = bpy.data.lights.new(<span class="s">&quot;Key&quot;</span>, <span class="s">&#x27;AREA&#x27;</span>); key.energy = <span class="n">1000.0</span>; key.size = <span class="n">6.0</span>
key = bpy.data.lights.new(<span class="s">&quot;Key&quot;</span>, <span class="s">&#x27;AREA&#x27;</span>); key.energy = <span class="n">1600.0</span>; key.size = <span class="n">5.0</span>
key.color = (<span class="n">1.0</span>, <span class="n">0.97</span>, <span class="n">0.92</span>)
key_ob = bpy.data.objects.new(<span class="s">&quot;Key&quot;</span>, key)
key_ob.location = (-<span class="n">4.5</span>, -<span class="n">5.5</span>, <span class="n">6.5</span>)
key_ob.rotation_euler = (math.radians(<span class="n">46</span>), <span class="n">0.0</span>, math.radians(-<span class="n">33</span>))
scene.collection.objects.link(key_ob)
fill = bpy.data.lights.new(<span class="s">&quot;Fill&quot;</span>, <span class="s">&#x27;AREA&#x27;</span>); fill.energy = <span class="n">350.0</span>; fill.size = <span class="n">8.0</span>
fill = bpy.data.lights.new(<span class="s">&quot;Fill&quot;</span>, <span class="s">&#x27;AREA&#x27;</span>); fill.energy = <span class="n">260.0</span>; fill.size = <span class="n">8.0</span>
fill.color = (<span class="n">0.8</span>, <span class="n">0.87</span>, <span class="n">1.0</span>)
fill_ob = bpy.data.objects.new(<span class="s">&quot;Fill&quot;</span>, fill)
fill_ob.location = (<span class="n">5.5</span>, -<span class="n">4.0</span>, <span class="n">3.5</span>)
fill_ob.rotation_euler = (math.radians(<span class="n">62</span>), <span class="n">0.0</span>, math.radians(<span class="n">48</span>))
scene.collection.objects.link(fill_ob)
rim = bpy.data.lights.new(<span class="s">&quot;Rim&quot;</span>, <span class="s">&#x27;AREA&#x27;</span>); rim.energy = <span class="n">480.0</span>; rim.size = <span class="n">5.0</span>
rim.color = (<span class="n">0.75</span>, <span class="n">0.85</span>, <span class="n">1.0</span>)
rim_ob = bpy.data.objects.new(<span class="s">&quot;Rim&quot;</span>, rim)
rim_ob.location = (<span class="n">0.0</span>, <span class="n">6.5</span>, <span class="n">3.0</span>)
rim_ob.rotation_euler = (math.radians(-<span class="n">78</span>), <span class="n">0.0</span>, math.radians(<span class="n">180</span>))
scene.collection.objects.link(rim_ob)

cam_data = bpy.data.cameras.new(<span class="s">&quot;Cam&quot;</span>); cam_data.lens = <span class="n">45.0</span>
cam = bpy.data.objects.new(<span class="s">&quot;Cam&quot;</span>, cam_data)
Expand Down
32 changes: 21 additions & 11 deletions docs/gallery/gn-sdf-remesh/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -246,14 +246,14 @@ <h2>Source</h2>

<span class="k">def</span> build():
bpy.ops.wm.read_factory_settings(use_empty=<span class="k">True</span>)
bpy.ops.mesh.primitive_torus_add(location=(<span class="n">0</span>, <span class="n">0</span>, <span class="n">1.0</span>), major_radius=<span class="n">1.2</span>, minor_radius=<span class="n">0.5</span>)
bpy.ops.mesh.primitive_torus_add(location=(<span class="n">0</span>, <span class="n">0</span>, <span class="n">0.55</span>), major_radius=<span class="n">1.2</span>, minor_radius=<span class="n">0.5</span>)
obj = bpy.context.active_object
<span class="k">for</span> p <span class="k">in</span> obj.data.polygons:
p.use_smooth = <span class="k">True</span>
mat = bpy.data.materials.new(<span class="s">&quot;Clay&quot;</span>); mat.use_nodes = <span class="k">True</span>
mat = bpy.data.materials.new(<span class="s">&quot;Ceramic&quot;</span>); mat.use_nodes = <span class="k">True</span>
b = mat.node_tree.nodes.get(<span class="s">&#x27;Principled BSDF&#x27;</span>)
b.inputs[<span class="s">&#x27;Base Color&#x27;</span>].default_value = (<span class="n">0.45</span>, <span class="n">0.55</span>, <span class="n">0.85</span>, <span class="n">1</span>)
b.inputs[<span class="s">&#x27;Roughness&#x27;</span>].default_value = <span class="n">0.45</span>
b.inputs[<span class="s">&#x27;Base Color&#x27;</span>].default_value = (<span class="n">0.42</span>, <span class="n">0.028</span>, <span class="n">0.045</span>, <span class="n">1</span>) <span class="c"># crimson ceramic</span>
b.inputs[<span class="s">&#x27;Roughness&#x27;</span>].default_value = <span class="n">0.22</span>
obj.data.materials.append(mat)
<span class="k">return</span> obj

Expand All @@ -262,23 +262,33 @@ <h2>Source</h2>
sc = bpy.context.scene
fme = bpy.data.meshes.new(<span class="s">&quot;Floor&quot;</span>); bm = bmesh.new()
bmesh.ops.create_grid(bm, x_segments=<span class="n">1</span>, y_segments=<span class="n">1</span>, size=<span class="n">30.0</span>); bm.to_mesh(fme); bm.free()
fmat = bpy.data.materials.new(<span class="s">&quot;Studio&quot;</span>); fmat.use_nodes = <span class="k">True</span>
fb = fmat.node_tree.nodes.get(<span class="s">&#x27;Principled BSDF&#x27;</span>)
fb.inputs[<span class="s">&#x27;Base Color&#x27;</span>].default_value = (<span class="n">0.055</span>, <span class="n">0.06</span>, <span class="n">0.07</span>, <span class="n">1</span>) <span class="c"># dark graphite studio</span>
fb.inputs[<span class="s">&#x27;Roughness&#x27;</span>].default_value = <span class="n">0.55</span>
fme.materials.append(fmat)
floor = bpy.data.objects.new(<span class="s">&quot;Floor&quot;</span>, fme); bpy.context.collection.objects.link(floor)
wall = bpy.data.objects.new(<span class="s">&quot;Wall&quot;</span>, fme.copy()); wall.location = (<span class="n">0</span>, <span class="n">9.0</span>, <span class="n">0</span>)
wall.rotation_euler = (<span class="n">1.5708</span>, <span class="n">0</span>, <span class="n">0</span>); bpy.context.collection.objects.link(wall)
w = bpy.data.worlds.new(<span class="s">&quot;W&quot;</span>); w.use_nodes = <span class="k">True</span>
w.node_tree.nodes[<span class="s">&quot;Background&quot;</span>].inputs[<span class="n">0</span>].default_value = (<span class="n">0.05</span>, <span class="n">0.06</span>, <span class="n">0.08</span>, <span class="n">1</span>); sc.world = w
aim = bpy.data.objects.new(<span class="s">&quot;Aim&quot;</span>, <span class="k">None</span>); aim.location = (<span class="n">0</span>, <span class="n">0</span>, <span class="n">1.0</span>); bpy.context.collection.objects.link(aim)
cam = bpy.data.objects.new(<span class="s">&quot;cam&quot;</span>, bpy.data.cameras.new(<span class="s">&quot;cam&quot;</span>)); cam.location = (<span class="n">0</span>, -<span class="n">6.5</span>, <span class="n">3.0</span>)
w.node_tree.nodes[<span class="s">&quot;Background&quot;</span>].inputs[<span class="n">0</span>].default_value = (<span class="n">0.01</span>, <span class="n">0.011</span>, <span class="n">0.014</span>, <span class="n">1</span>); sc.world = w
aim = bpy.data.objects.new(<span class="s">&quot;Aim&quot;</span>, <span class="k">None</span>); aim.location = (<span class="n">0</span>, <span class="n">0</span>, <span class="n">0.55</span>); bpy.context.collection.objects.link(aim)
cam = bpy.data.objects.new(<span class="s">&quot;cam&quot;</span>, bpy.data.cameras.new(<span class="s">&quot;cam&quot;</span>)); cam.location = (<span class="n">0</span>, -<span class="n">6.5</span>, <span class="n">2.2</span>)
bpy.context.collection.objects.link(cam); sc.camera = cam
c = cam.constraints.new(<span class="s">&#x27;TRACK_TO&#x27;</span>); c.target = aim; c.track_axis = <span class="s">&#x27;TRACK_NEGATIVE_Z&#x27;</span>; c.up_axis = <span class="s">&#x27;UP_Y&#x27;</span>
<span class="k">for</span> nm, loc, en <span class="k">in</span> [(<span class="s">&quot;K&quot;</span>, (-<span class="n">4</span>, -<span class="n">5</span>, <span class="n">7</span>), <span class="n">900</span>), (<span class="s">&quot;F2&quot;</span>, (<span class="n">5</span>, -<span class="n">4</span>, <span class="n">2</span>), <span class="n">350</span>)]:
ld = bpy.data.lights.new(nm, <span class="s">&#x27;AREA&#x27;</span>); ld.energy = en; ld.size = <span class="n">5.0</span>
<span class="c"># key, cool fill, warm rim</span>
<span class="k">for</span> nm, loc, en, sz, col <span class="k">in</span> [(<span class="s">&quot;K&quot;</span>, (-<span class="n">4</span>, -<span class="n">5</span>, <span class="n">7</span>), <span class="n">1100</span>, <span class="n">5.0</span>, (<span class="n">1.0</span>, <span class="n">0.98</span>, <span class="n">0.95</span>)),
(<span class="s">&quot;F2&quot;</span>, (<span class="n">5</span>, -<span class="n">4</span>, <span class="n">2</span>), <span class="n">220</span>, <span class="n">7.0</span>, (<span class="n">0.85</span>, <span class="n">0.9</span>, <span class="n">1.0</span>)),
(<span class="s">&quot;R&quot;</span>, (<span class="n">2.5</span>, <span class="n">6</span>, <span class="n">4</span>), <span class="n">700</span>, <span class="n">3.0</span>, (<span class="n">1.0</span>, <span class="n">0.72</span>, <span class="n">0.45</span>))]:
ld = bpy.data.lights.new(nm, <span class="s">&#x27;AREA&#x27;</span>); ld.energy = en; ld.size = sz; ld.color = col
lo = bpy.data.objects.new(nm, ld); lo.location = loc; bpy.context.collection.objects.link(lo)
lc = lo.constraints.new(<span class="s">&#x27;TRACK_TO&#x27;</span>); lc.target = aim; lc.track_axis = <span class="s">&#x27;TRACK_NEGATIVE_Z&#x27;</span>; lc.up_axis = <span class="s">&#x27;UP_Y&#x27;</span>
sc.render.engine = <span class="s">&#x27;CYCLES&#x27;</span> <span class="k">if</span> engine == <span class="s">&#x27;cycles&#x27;</span> <span class="k">else</span> get_eevee_engine_id()
<span class="k">if</span> sc.render.engine == <span class="s">&#x27;CYCLES&#x27;</span>:
<span class="k">try</span>: sc.cycles.samples = <span class="n">16</span>
<span class="k">try</span>: sc.cycles.samples = <span class="n">32</span>
<span class="k">except</span> Exception: <span class="k">pass</span>
<span class="k">else</span>:
<span class="k">try</span>: sc.eevee.taa_render_samples = <span class="n">16</span>
<span class="k">try</span>: sc.eevee.taa_render_samples = <span class="n">64</span>
<span class="k">except</span> Exception: <span class="k">pass</span>
sc.render.resolution_x = <span class="n">1280</span>; sc.render.resolution_y = <span class="n">720</span>
sc.render.image_settings.file_format = <span class="s">&#x27;PNG&#x27;</span>; sc.render.filepath = path
Expand Down
21 changes: 12 additions & 9 deletions docs/gallery/wave-displace/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -284,24 +284,27 @@ <h2>Source</h2>
mat = bpy.data.materials.new(<span class="s">&quot;WaveMat&quot;</span>)
mat.use_nodes = <span class="k">True</span>
bsdf = mat.node_tree.nodes[<span class="s">&quot;Principled BSDF&quot;</span>]
bsdf.inputs[<span class="s">&quot;Base Color&quot;</span>].default_value = (<span class="n">0.62</span>, <span class="n">0.68</span>, <span class="n">0.78</span>, <span class="n">1.0</span>)
bsdf.inputs[<span class="s">&quot;Roughness&quot;</span>].default_value = <span class="n">0.35</span>
bsdf.inputs[<span class="s">&quot;Base Color&quot;</span>].default_value = (<span class="n">0.012</span>, <span class="n">0.09</span>, <span class="n">0.38</span>, <span class="n">1.0</span>) <span class="c"># deep sapphire</span>
bsdf.inputs[<span class="s">&quot;Roughness&quot;</span>].default_value = <span class="n">0.18</span>
obj.data.materials.append(mat)

world = bpy.data.worlds.new(<span class="s">&quot;World&quot;</span>)
world.use_nodes = <span class="k">True</span>
world.node_tree.nodes[<span class="s">&quot;Background&quot;</span>].inputs[<span class="s">&quot;Color&quot;</span>].default_value = (<span class="n">0.045</span>, <span class="n">0.05</span>, <span class="n">0.06</span>, <span class="n">1.0</span>)
world.node_tree.nodes[<span class="s">&quot;Background&quot;</span>].inputs[<span class="s">&quot;Color&quot;</span>].default_value = (<span class="n">0.008</span>, <span class="n">0.009</span>, <span class="n">0.012</span>, <span class="n">1.0</span>)
scene.world = world

key = bpy.data.lights.new(<span class="s">&quot;Key&quot;</span>, <span class="s">&#x27;AREA&#x27;</span>); key.energy = <span class="n">1400.0</span>; key.size = <span class="n">7.0</span>
<span class="c"># grazing cool key picks out the crests; warm rim from behind</span>
key = bpy.data.lights.new(<span class="s">&quot;Key&quot;</span>, <span class="s">&#x27;AREA&#x27;</span>); key.energy = <span class="n">2000.0</span>; key.size = <span class="n">6.0</span>
key.color = (<span class="n">0.9</span>, <span class="n">0.95</span>, <span class="n">1.0</span>)
key_ob = bpy.data.objects.new(<span class="s">&quot;Key&quot;</span>, key)
key_ob.location = (-<span class="n">5.0</span>, -<span class="n">6.0</span>, <span class="n">6.5</span>)
key_ob.rotation_euler = (math.radians(<span class="n">48</span>), <span class="n">0.0</span>, math.radians(-<span class="n">35</span>))
key_ob.location = (-<span class="n">6.5</span>, -<span class="n">5.0</span>, <span class="n">3.2</span>)
key_ob.rotation_euler = (math.radians(<span class="n">65</span>), <span class="n">0.0</span>, math.radians(-<span class="n">50</span>))
scene.collection.objects.link(key_ob)
rim = bpy.data.lights.new(<span class="s">&quot;Rim&quot;</span>, <span class="s">&#x27;AREA&#x27;</span>); rim.energy = <span class="n">600.0</span>; rim.size = <span class="n">5.0</span>
rim = bpy.data.lights.new(<span class="s">&quot;Rim&quot;</span>, <span class="s">&#x27;AREA&#x27;</span>); rim.energy = <span class="n">1300.0</span>; rim.size = <span class="n">4.0</span>
rim.color = (<span class="n">1.0</span>, <span class="n">0.68</span>, <span class="n">0.38</span>)
rim_ob = bpy.data.objects.new(<span class="s">&quot;Rim&quot;</span>, rim)
rim_ob.location = (<span class="n">4.0</span>, <span class="n">6.0</span>, <span class="n">4.5</span>)
rim_ob.rotation_euler = (math.radians(-<span class="n">55</span>), <span class="n">0.0</span>, math.radians(<span class="n">150</span>))
rim_ob.location = (<span class="n">4.5</span>, <span class="n">6.5</span>, <span class="n">2.6</span>)
rim_ob.rotation_euler = (math.radians(-<span class="n">68</span>), <span class="n">0.0</span>, math.radians(<span class="n">148</span>))
scene.collection.objects.link(rim_ob)

cam_data = bpy.data.cameras.new(<span class="s">&quot;Cam&quot;</span>); cam_data.lens = <span class="n">50.0</span>
Expand Down
Binary file modified examples/depsgraph-export/preview.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading