Merge pull request #59 from RodZill4/dev-functions

Merged raymarching related stuff
This commit is contained in:
Rodz Labs 2019-12-25 13:50:11 +01:00 committed by GitHub
commit 172b8e4bc3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
142 changed files with 6880 additions and 744 deletions

View File

@ -8,6 +8,7 @@ to describe procedural materials.
:maxdepth: 2 :maxdepth: 2
nodes_simple nodes_simple
nodes_3d
nodes_pattern nodes_pattern
nodes_noise nodes_noise
nodes_filter nodes_filter

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@ -0,0 +1,69 @@
3D signed distance function geometry nodes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The signed distance function nodes can be used to define complex 3D geometry using simple
shapes.
They are based on a very small set of basic shapes, that can be combined using operators,
and finally output as a greyscale heightmap and a color normal map using the **render** node.
Describing 3D objects using SDF primitives is more difficult than using existing meshes, but this
method integrates smoothly with shader generation, and (as many nodes in Material Maker) is
resolution independant.
All output samples shown in this section are preview images.
All Signed Distance Functions nodes are based on code written by Inigo Quilez that can be found
`on this page`__.
.. _sdf3dpage: https://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
__ sdf3dpage_
.. toctree::
:maxdepth: 1
node_3d_sdf_render
Shapes
++++++
.. toctree::
:maxdepth: 1
node_3d_sdf_shapes_sphere
node_3d_sdf_shapes_box
node_3d_sdf_shapes_cylinder
node_3d_sdf_shapes_capsule
node_3d_sdf_shapes_cone
node_3d_sdf_shapes_torus
Operators
+++++++++
.. toctree::
:maxdepth: 1
node_3d_sdf_operators_boolean
node_3d_sdf_operators_smoothboolean
node_3d_sdf_operators_rounded
node_3d_sdf_operators_repeat
node_3d_sdf_operators_circlerepeat
node_3d_sdf_operators_extrusion
node_3d_sdf_operators_revolution
Transforms
++++++++++
.. toctree::
:maxdepth: 1
node_3d_sdf_transforms_translate
node_3d_sdf_transforms_scale
node_3d_sdf_transforms_rotate
Example images
++++++++++++++
.. image:: images/node_sdf3d_samples.png
:align: center

View File

@ -0,0 +1,31 @@
Boolean node
............
The **Boolean** node generates a 3D signed distance function for the combination (union,
intersection or difference) of its inputs.
.. image:: images/node_sdf3d_boolean.png
:align: center
Inputs
::::::
The **Boolean** node accepts 2 inputs in 3D signed distance function format.
Outputs
:::::::
The **Boolean** node generates a signed distance function of the
combination of its inputs.
Parameters
::::::::::
The **Boolean** node accepts *the operator it applies (union, intersection or
difference)* as parameter.
Example images
::::::::::::::
.. image:: images/node_sdf3d_boolean_sample.png
:align: center

View File

@ -0,0 +1,30 @@
CircleRepeat node
...........
The **CircleRepeat** node generates a 3D signed distance image of a circular repetition of its
input. The source object must be offset in the positive Y direction from the center.
.. image:: images/node_sdf3d_circlerepeat.png
:align: center
Inputs
::::::
The **CircleRepeat** node accepts an input in 3D signed distance function format.
Outputs
:::::::
The **CircleRepeat** node generates a signed distance function of the
repeated version of the input shape.
Parameters
::::::::::
The **CircleRepeat** node accepts *the number of repetitions* as parameter.
Example images
::::::::::::::
.. image:: images/node_sdf3d_circlerepeat_sample.png
:align: center

View File

@ -0,0 +1,30 @@
Extrusion node
..............
The **Extrusion** node generates a 3D signed distance function of a shape based on
its (2D signed function) input extruded along the Y axis.
.. image:: images/node_sdf3d_extrusion.png
:align: center
Inputs
::::::
The **Extrusion** node accepts an input in 2D signed distance function format.
Outputs
:::::::
The **Extrusion** node generates a signed distance function of the
extruded version of the input shape.
Parameters
::::::::::
The **Extrusion** node accepts the *the length* of the extruded shape as parameter.
Example images
::::::::::::::
.. image:: images/node_sdf3d_extrusion_sample.png
:align: center

View File

@ -0,0 +1,34 @@
Repeat node
...........
The **Repeat** node generates a 3D signed distance image of a repetition of its
input on the X and Y axes. It can also apply a random rotation to the repeated
object instances.
.. image:: images/node_sdf3d_repeat.png
:align: center
Inputs
::::::
The **Repeat** node accepts an input in 3D signed distance function format.
Outputs
:::::::
The **Repeat** node generates a signed distance function of the
repeated version of the input shape.
Parameters
::::::::::
The **Repeat** node accepts the following parameters:
* *the repetition offset* for both X and Y axes
* *the amount of random rotation* applied to all instances
Example images
::::::::::::::
.. image:: images/node_sdf3d_repeat_sample.png
:align: center

View File

@ -0,0 +1,30 @@
Revolution node
...............
The **Revolution** node generates a 3D signed distance function of a shape based on
the revolution along the Z axis of its (2D signed function) input.
.. image:: images/node_sdf3d_revolution.png
:align: center
Inputs
::::::
The **Revolution** node accepts an input in 2D signed distance function format.
Outputs
:::::::
The **Revolution** node generates a signed distance function of the
revolution of the input shape.
Parameters
::::::::::
The **Revolution** node accepts the *the radius* of the revolution operation as parameter.
Example images
::::::::::::::
.. image:: images/node_sdf3d_revolution_sample.png
:align: center

View File

@ -0,0 +1,33 @@
Rounded node
.................
The **Rounded** node generates a 3D signed distance function of a rounded shape
based on its input, by substracting a constant from its input (i.e.
"growing" it towards the outside).
.. image:: images/node_sdf3d_roundedshape.png
:align: center
Inputs
::::::
The **Rounded** node accepts an input in 3D signed distance function format.
Outputs
:::::::
The **Rounded** node generates a signed distance function of the
rounded version of the input shape.
Parameters
::::::::::
The **Rounded** node accepts the following parameters:
* *the distance* to be substracted from the function
Example images
::::::::::::::
.. image:: images/node_sdf3d_roundedshape_sample.png
:align: center

View File

@ -0,0 +1,33 @@
SmoothBoolean node
..................
The **SmoothBoolean** node generates a 3D signed distance image for the combination (union,
intersection or difference) of its inputs.
.. image:: images/node_sdf3d_smoothboolean.png
:align: center
Inputs
::::::
The **SmoothBoolean** node accepts 2 inputs in signed distance function format.
Outputs
:::::::
The **SmoothBoolean** node generates a signed distance function of the
combination of its inputs.
Parameters
::::::::::
The **SmoothBoolean** node accepts the following parameters:
* *the operator it applies (union, intersection or difference)*
* *the smoothness* of the operation
Example images
::::::::::::::
.. image:: images/node_sdf3d_smoothboolean_sample.png
:align: center

View File

@ -0,0 +1,27 @@
Render node
...........
The **Render** node generates images from a 3D signed distance function inputs.
.. image:: images/node_sdf3d_render.png
:align: center
Inputs
::::::
The **Render** node accepts an input in 3D signed distance function format.
Outputs
:::::::
The **Render** node generates two images from its input:
* a *height map* of the rendered input along the Z axis
* a *normal map* of the rendered input calculated directly
using the 3D signed function (and consequently more
accurate than a normal map generated from the height map)
Parameters
::::::::::
The **Render** node does no accept any parameter.

View File

@ -0,0 +1,31 @@
Box node
........
The **Box** node generates a 3d signed distance function for a box with rounded corners.
.. image:: images/node_sdf3d_box.png
:align: center
Inputs
::::::
The **Box** node does not accept any input.
Outputs
:::::::
The **Box** node generates a signed distance function for a box.
Parameters
::::::::::
The **Box** node accepts the following parameters:
* the X, Y and Z sizes of the box (not including the rounded corners and edges)
* the radius of the rounded corners and edges
Example images
::::::::::::::
.. image:: images/node_sdf3d_box_sample.png
:align: center

View File

@ -0,0 +1,28 @@
Capsule node
............
The **Capsule** node generates a 3d signed distance function for a capsule.
.. image:: images/node_sdf3d_capsule.png
:align: center
Inputs
::::::
The **Capsule** node does not accept any input.
Outputs
:::::::
The **Capsule** node generates a signed distance function for a capsule.
Parameters
::::::::::
The **Capsule** node accepts as parameters the length of the capsule and its radius.
Example images
::::::::::::::
.. image:: images/node_sdf3d_capsule_sample.png
:align: center

View File

@ -0,0 +1,28 @@
Capsule node
............
The **Capsule** node generates a 3d signed distance function for a capsule.
.. image:: images/node_sdf3d_capsule.png
:align: center
Inputs
::::::
The **Capsule** node does not accept any input.
Outputs
:::::::
The **Capsule** node generates a signed distance function for a capsule.
Parameters
::::::::::
The **Capsule** node accepts as parameters the length of the capsule and its radius.
Example images
::::::::::::::
.. image:: images/node_sdf3d_capsule_sample.png
:align: center

View File

@ -0,0 +1,28 @@
Cylinder node
.............
The **Cylinder** node generates a 3d signed distance function for a cylinder.
.. image:: images/node_sdf3d_cylinder.png
:align: center
Inputs
::::::
The **Cylinder** node does not accept any input.
Outputs
:::::::
The **Cylinder** node generates a signed distance function for a cylinder.
Parameters
::::::::::
The **Cylinder** node accepts as parameters the length of the cylinder and its radius.
Example images
::::::::::::::
.. image:: images/node_sdf3d_cylinder_sample.png
:align: center

View File

@ -0,0 +1,28 @@
Sphere node
...........
The **Sphere** node generates a 3d signed distance function for a sphere.
.. image:: images/node_sdf3d_sphere.png
:align: center
Inputs
::::::
The **Sphere** node does not accept any input.
Outputs
:::::::
The **Sphere** node generates a signed distance function for a sphere.
Parameters
::::::::::
The **Sphere** node accepts a single parameter, its radius.
Example images
::::::::::::::
.. image:: images/node_sdf3d_sphere_sample.png
:align: center

View File

@ -0,0 +1,28 @@
Torus node
..........
The **Torus** node generates a 3d signed distance function for a torus.
.. image:: images/node_sdf3d_torus.png
:align: center
Inputs
::::::
The **Torus** node does not accept any input.
Outputs
:::::::
The **Torus** node generates a signed distance function for a torus.
Parameters
::::::::::
The **Torus** node accepts as parameters both radiuses of the torus.
Example images
::::::::::::::
.. image:: images/node_sdf3d_torus_sample.png
:align: center

View File

@ -0,0 +1,24 @@
Rotate node
...........
The **Rotate** node generates a 3D signed distance function of a rotated shape
based on its input.
.. image:: images/node_sdf3d_rotate.png
:align: center
Inputs
::::::
The **Rotate** node accepts an input in 3D signed distance function format.
Outputs
:::::::
The **Rotate** node generates a signed distance function of the
rotated input shape.
Parameters
::::::::::
The **Rotate** node accepts *the angles of the rotations around the X, Y and Z axes* as parameters.

View File

@ -0,0 +1,24 @@
Scale node
..........
The **Scale** node generates a 3D signed distance function of a scaled shape
based on its input.
.. image:: images/node_sdf3d_scale.png
:align: center
Inputs
::::::
The **Scale** node accepts an input in 3D signed distance function format.
Outputs
:::::::
The **Scale** node generates a signed distance function of the
scaled input shape.
Parameters
::::::::::
The **Scale** node accepts *its scale factor* as parameters.

View File

@ -0,0 +1,24 @@
Translate node
..............
The **Translate** node generates a 3D signed distance function of a translated shape
based on its input.
.. image:: images/node_sdf3d_translate.png
:align: center
Inputs
::::::
The **Translate** node accepts an input in 3D signed distance function format.
Outputs
:::::::
The **Translate** node generates a signed distance function of the
translated input shape.
Parameters
::::::::::
The **Translate** node accepts *the X, Y and Z components of the translation* as parameters.

View File

@ -1,5 +1,5 @@
Signed distance function geometry nodes 2D Signed distance function geometry nodes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The signed distance function nodes can be used to define complex geometry using simple The signed distance function nodes can be used to define complex geometry using simple
shapes. shapes.
@ -7,7 +7,7 @@ shapes.
They are based on a very small set of basic shapes, that can be combined using operators, They are based on a very small set of basic shapes, that can be combined using operators,
and finally output as a greyscale image using the **sdShow** node. and finally output as a greyscale image using the **sdShow** node.
All output samples shown in this sections are images generated through the **sdView** node. All output samples shown in this sections are images generated through the **sdShow** node.
All Signed Distance Functions nodes are based on code written by Inigo Quilez that can be found All Signed Distance Functions nodes are based on code written by Inigo Quilez that can be found
`on this page`__. `on this page`__.

View File

@ -0,0 +1,10 @@
3D nodes
--------
The simple nodes are nodes that do not accept any input and generate one or several simple shapes.
.. toctree::
:maxdepth: 0
node_3d_sdf

View File

@ -21,11 +21,12 @@ shortcut will make it possible to edit its contents using the pencil button.
The newly created subgraph contains: The newly created subgraph contains:
* all nodes that have been grouped * all nodes that have been grouped
* an **Input** and an **Output** node that rep^resent the inputs and the outputs * an **Input** and an **Output** node that represent the inputs and the outputs
of the subgraph. Selecting them and using the **Control+W** shortcut makes them of the subgraph. Selecting them and using the **Control+W** shortcut makes them
editable so the subgraph inputs and outputs can be added, removed reordered or editable so the subgraph inputs and outputs can be added, removed, reordered,
renamed. Please note that all those operations will (when possible) keep renamed or have their types modified.
connectivity inside and outside the subgraph. Please note that all those operations will (when possible) keep connectivity
inside and outside the subgraph.
* A **Parameters** node that is a **remote** can be edited to expose selected * A **Parameters** node that is a **remote** can be edited to expose selected
parameters to the parent graph. When grouping nodes with a **remote**, the parameters to the parent graph. When grouping nodes with a **remote**, the
remote will automatically be used as **Parameters** node in the nealy created remote will automatically be used as **Parameters** node in the nealy created

View File

@ -37,6 +37,17 @@ var parameters = {}
var seed_locked : bool = false var seed_locked : bool = false
var seed_value : int = 0 var seed_value : int = 0
const PORT_TYPE_NAMES : Array = [ "f", "rgb", "rgba", "sdf2d", "sdf3d" ]
const PORT_TYPES : Dictionary = {
f = { type="float", paramdefs="vec2 uv", params="uv", slot_type=0, color=Color(0.5, 0.5, 0.5) },
rgb = { type="vec3", paramdefs="vec2 uv", params="uv", slot_type=0, color=Color(0.5, 0.5, 1.0) },
rgba = { type="vec4", paramdefs="vec2 uv", params="uv", slot_type=0, color=Color(0.0, 0.5, 0.0, 0.5) },
sdf2d = { type="float", paramdefs="vec2 uv", params="uv", slot_type=1, color=Color(1.0, 0.5, 0.0) },
sdf3d = { type="float", paramdefs="vec3 p", params="p", slot_type=2, color=Color(1.0, 0.0, 0.0) },
any = { slot_type=42, color=Color(1.0, 1.0, 1.0) }
}
func _ready() -> void: func _ready() -> void:
init_parameters() init_parameters()
@ -151,14 +162,18 @@ func get_input_shader(input_index : int) -> Dictionary:
func get_shader(output_index : int, context) -> Dictionary: func get_shader(output_index : int, context) -> Dictionary:
return get_shader_code("UV", output_index, context) return get_shader_code("UV", output_index, context)
func render(output_index : int, size : int) -> Object: func render(output_index : int, size : int, preview : bool = false) -> Object:
var context : MMGenContext = MMGenContext.new() var context : MMGenContext = MMGenContext.new()
var source = get_shader_code("UV", output_index, context) var source = get_shader_code("uv", output_index, context)
while source is GDScriptFunctionState: while source is GDScriptFunctionState:
source = yield(source, "completed") source = yield(source, "completed")
if source.empty(): if source.empty():
source = { defs="", code="", textures={}, rgba="vec4(0.0)" } source = { defs="", code="", textures={}, rgba="vec4(0.0)" }
var shader : String = mm_renderer.generate_shader(source) var shader : String
if preview:
shader = mm_renderer.generate_preview_shader(source)
else:
shader = mm_renderer.generate_shader(source)
var result = mm_renderer.render_shader(shader, source.textures, size) var result = mm_renderer.render_shader(shader, source.textures, size)
while result is GDScriptFunctionState: while result is GDScriptFunctionState:
result = yield(result, "completed") result = yield(result, "completed")
@ -174,15 +189,14 @@ func get_shader_code(uv : String, output_index : int, context : MMGenContext) ->
rv.f = "(dot("+rv.rgb+", vec3(1.0))/3.0)" rv.f = "(dot("+rv.rgb+", vec3(1.0))/3.0)"
elif rv.has("rgba"): elif rv.has("rgba"):
rv.f = "(dot("+rv.rgba+".rgb, vec3(1.0))/3.0)" rv.f = "(dot("+rv.rgba+".rgb, vec3(1.0))/3.0)"
else:
rv.f = "0.0"
if !rv.has("rgb"): if !rv.has("rgb"):
if rv.has("rgba"): if rv.has("rgba"):
rv.rgb = rv.rgba+".rgb" rv.rgb = rv.rgba+".rgb"
else: elif rv.has("f"):
rv.rgb = "vec3("+rv.f+")" rv.rgb = "vec3("+rv.f+")"
if !rv.has("rgba"): if !rv.has("rgba"):
rv.rgba = "vec4("+rv.rgb+", 1.0)" if rv.has("rgb"):
rv.rgba = "vec4("+rv.rgb+", 1.0)"
return rv return rv
func _get_shader_code(__, __, __) -> Dictionary: func _get_shader_code(__, __, __) -> Dictionary:

View File

@ -4,10 +4,19 @@ class_name MMGenContext
var variants : Dictionary = {} var variants : Dictionary = {}
var parent_context : MMGenContext = null
func _init(p = null) -> void:
parent_context = p
func has_variant(generator) -> bool: func has_variant(generator) -> bool:
return variants.has(generator) return variants.has(generator) or parent_context != null and parent_context.has_variant(generator)
func touch_variant(generator) -> void:
if !variants.has(generator):
variants[generator] = []
if parent_context != null:
parent_context.touch_variant(generator)
func get_variant(generator, variant) -> int: func get_variant(generator, variant) -> int:
var rv = -1 var rv = -1
@ -17,4 +26,5 @@ func get_variant(generator, variant) -> int:
variants[generator].push_back(variant) variants[generator].push_back(variant)
else: else:
variants[generator] = [variant] variants[generator] = [variant]
touch_variant(generator)
return rv return rv

View File

@ -284,8 +284,8 @@ func create_subgraph(gens : Array) -> MMGenGraph:
if port_index == -1: if port_index == -1:
port_index = outputs.size() port_index = outputs.size()
outputs.push_back(src_name) outputs.push_back(src_name)
gen_outputs.ports.push_back( { name="port"+str(port_index), type="rgba" } ) var type = new_graph.get_node(c.from).get_output_defs()[c.from_port].type
print(gen_outputs.ports) gen_outputs.ports.push_back( { name="port"+str(port_index), type=type } )
my_new_connections.push_back( { from=new_graph.name, from_port=port_index, to=c.to, to_port=c.to_port } ) my_new_connections.push_back( { from=new_graph.name, from_port=port_index, to=c.to, to_port=c.to_port } )
new_graph_connections.push_back( { from=c.from, from_port=c.from_port, to="gen_outputs", to_port=port_index } ) new_graph_connections.push_back( { from=c.from, from_port=c.from_port, to="gen_outputs", to_port=port_index } )
elif names.find(c.to) != -1: elif names.find(c.to) != -1:
@ -293,7 +293,8 @@ func create_subgraph(gens : Array) -> MMGenGraph:
if port_index == -1: if port_index == -1:
port_index = inputs.size() port_index = inputs.size()
inputs.push_back(src_name) inputs.push_back(src_name)
gen_inputs.ports.push_back( { name="port"+str(port_index), type="rgba" } ) var type = get_node(c.from).get_output_defs()[c.from_port].type
gen_inputs.ports.push_back( { name="port"+str(port_index), type=type } )
my_new_connections.push_back( { from=c.from, from_port=c.from_port, to=new_graph.name, to_port=port_index } ) my_new_connections.push_back( { from=c.from, from_port=c.from_port, to=new_graph.name, to_port=port_index } )
new_graph_connections.push_back( { from="gen_inputs", from_port=port_index, to=c.to, to_port=c.to_port } ) new_graph_connections.push_back( { from="gen_inputs", from_port=port_index, to=c.to, to_port=c.to_port } )
else: else:

View File

@ -27,7 +27,7 @@ func get_type_name() -> String:
func get_io_defs() -> Array: func get_io_defs() -> Array:
var rv : Array = [] var rv : Array = []
for p in ports: for p in ports:
rv.push_back({ name=p.name, type="rgba" }) rv.push_back({ name=p.name, type=p.type })
return rv return rv
func get_input_defs() -> Array: func get_input_defs() -> Array:
@ -54,6 +54,11 @@ func add_port() -> void:
func set_port_name(i : int, n : String) -> void: func set_port_name(i : int, n : String) -> void:
ports[i].name = n ports[i].name = n
func set_port_type(i : int, t : String) -> void:
print(t)
ports[i].type = t
emit_signal("parameter_changed", "__update_all__", null)
func delete_port(i : int) -> void: func delete_port(i : int) -> void:
ports.remove(i) ports.remove(i)
var input_gen = get_parent() if name == "gen_inputs" else self var input_gen = get_parent() if name == "gen_inputs" else self

View File

@ -2,11 +2,13 @@ tool
extends MMGenBase extends MMGenBase
class_name MMGenShader class_name MMGenShader
var shader_model : Dictionary = {} var shader_model : Dictionary = {}
var uses_seed = false var uses_seed = false
var editable = false var editable = false
func toggle_editable() -> bool: func toggle_editable() -> bool:
editable = !editable editable = !editable
if editable: if editable:
@ -53,16 +55,12 @@ func set_shader_model(data: Dictionary) -> void:
for i in range(shader_model.outputs.size()): for i in range(shader_model.outputs.size()):
var output = shader_model.outputs[i] var output = shader_model.outputs[i]
var output_code = "" var output_code = ""
if output.has("rgba"): for f in PORT_TYPES.keys():
shader_model.outputs[i].type = "rgba" if output.has(f):
output_code = output.rgba shader_model.outputs[i].type = f
elif output.has("rgb"): output_code = output[f]
shader_model.outputs[i].type = "rgb" break
output_code = output.rgb if output_code == "":
elif output.has("f"):
shader_model.outputs[i].type = "f"
output_code = output.f
else:
print("Unsupported output type") print("Unsupported output type")
if output_code.find("$seed") != -1 or output_code.find("$(seed)") != -1: if output_code.find("$seed") != -1 or output_code.find("$(seed)") != -1:
uses_seed = true uses_seed = true
@ -90,7 +88,19 @@ func find_keyword_call(string, keyword):
parenthesis_level -= 1 parenthesis_level -= 1
return "" return ""
func replace_input(string, context, input, type, src, default) -> Dictionary: func replace_input_with_function_call(string : String, input : String) -> String:
var genname = "o"+str(get_instance_id())
while true:
var uv = find_keyword_call(string, input)
if uv == null:
break
elif uv == "":
print("syntax error")
break
string = string.replace("$%s(%s)" % [ input, uv ], "%s_input_%s(%s)" % [ genname, input, uv ])
return string
func replace_input(string : String, context, input : String, type : String, src : OutputPort, default : String) -> Dictionary:
var required_globals = [] var required_globals = []
var required_defs = "" var required_defs = ""
var required_code = "" var required_code = ""
@ -113,7 +123,10 @@ func replace_input(string, context, input, type, src, default) -> Dictionary:
src_code = src.generator.get_shader_code(uv, src.output_index, context) src_code = src.generator.get_shader_code(uv, src.output_index, context)
while src_code is GDScriptFunctionState: while src_code is GDScriptFunctionState:
src_code = yield(src_code, "completed") src_code = yield(src_code, "completed")
src_code.string = src_code[type] if src_code.has(type):
src_code.string = src_code[type]
else:
src_code.string = "*error*"
# Add global definitions # Add global definitions
if src_code.has("globals"): if src_code.has("globals"):
for d in src_code.globals: for d in src_code.globals:
@ -134,7 +147,7 @@ func replace_input(string, context, input, type, src, default) -> Dictionary:
func is_word_letter(l) -> bool: func is_word_letter(l) -> bool:
return "azertyuiopqsdfghjklmwxcvbnAZERTYUIOPQSDFGHJKLMWXCVBN1234567890_".find(l) != -1 return "azertyuiopqsdfghjklmwxcvbnAZERTYUIOPQSDFGHJKLMWXCVBN1234567890_".find(l) != -1
func replace_variable(string, variable, value) -> String: func replace_variable(string : String, variable : String, value : String) -> String:
string = string.replace("$(%s)" % variable, value) string = string.replace("$(%s)" % variable, value)
var keyword_size = variable.length()+1 var keyword_size = variable.length()+1
var new_string = "" var new_string = ""
@ -152,7 +165,7 @@ func replace_variable(string, variable, value) -> String:
string = string.right(keyword_size) string = string.right(keyword_size)
return new_string return new_string
func subst(string, context, uv = "") -> Dictionary: func subst(string : String, context : MMGenContext, uv : String = "") -> Dictionary:
var genname = "o"+str(get_instance_id()) var genname = "o"+str(get_instance_id())
var required_globals = [] var required_globals = []
var required_defs = "" var required_defs = ""
@ -199,40 +212,41 @@ func subst(string, context, uv = "") -> Dictionary:
for i in range(shader_model.inputs.size()): for i in range(shader_model.inputs.size()):
var input = shader_model.inputs[i] var input = shader_model.inputs[i]
var source = get_source(i) var source = get_source(i)
var result = replace_input(string, context, input.name, input.type, source, input.default) if input.has("function") and input.function:
while result is GDScriptFunctionState: string = replace_input_with_function_call(string, input.name)
result = yield(result, "completed") else:
if string != result.string: var result = replace_input(string, context, input.name, input.type, source, input.default)
changed = true while result is GDScriptFunctionState:
if result.new_pass_required: result = yield(result, "completed")
new_pass_required = true if string != result.string:
string = result.string changed = true
# Add global definitions if result.new_pass_required:
for d in result.globals: new_pass_required = true
if required_globals.find(d) == -1: string = result.string
required_globals.push_back(d) # Add global definitions
# Add generated definitions for d in result.globals:
required_defs += result.defs if required_globals.find(d) == -1:
# Add generated code required_globals.push_back(d)
required_code += result.code # Add generated definitions
for t in result.textures.keys(): required_defs += result.defs
required_textures[t] = result.textures[t] # Add generated code
required_code += result.code
for t in result.textures.keys():
required_textures[t] = result.textures[t]
cont = changed and new_pass_required cont = changed and new_pass_required
return { string=string, globals=required_globals, defs=required_defs, code=required_code, textures=required_textures } return { string=string, globals=required_globals, defs=required_defs, code=required_code, textures=required_textures }
func create_input_function(function_name : String, input_index : int, context : MMGenContext) -> Dictionary:
var rv = { globals=[], defs="", code="", textures={} }
return rv
func _get_shader_code(uv : String, output_index : int, context : MMGenContext) -> Dictionary: func _get_shader_code(uv : String, output_index : int, context : MMGenContext) -> Dictionary:
var genname = "o"+str(get_instance_id()) var genname = "o"+str(get_instance_id())
var output_info = [ { field="rgba", type="vec4" }, { field="rgb", type="vec3" }, { field="f", type="float" } ]
var rv = { globals=[], defs="", code="", textures={} } var rv = { globals=[], defs="", code="", textures={} }
if shader_model != null and shader_model.has("outputs") and shader_model.outputs.size() > output_index: if shader_model != null and shader_model.has("outputs") and shader_model.outputs.size() > output_index:
var output = shader_model.outputs[output_index] var output = shader_model.outputs[output_index]
if shader_model.has("instance") && !context.has_variant(self): if !context.has_variant(self):
var subst_output = subst(shader_model.instance, context, "") # Generate functions for gradients
while subst_output is GDScriptFunctionState:
subst_output = yield(subst_output, "completed")
rv.defs += subst_output.string
for t in subst_output.textures.keys():
rv.textures[t] = subst_output.textures[t]
for p in shader_model.parameters: for p in shader_model.parameters:
if p.type == "gradient": if p.type == "gradient":
var g = parameters[p.name] var g = parameters[p.name]
@ -240,6 +254,37 @@ func _get_shader_code(uv : String, output_index : int, context : MMGenContext) -
g = MMGradient.new() g = MMGradient.new()
g.deserialize(parameters[p.name]) g.deserialize(parameters[p.name])
rv.defs += g.get_shader(genname+"_p_"+p.name+"_gradient_fct") rv.defs += g.get_shader(genname+"_p_"+p.name+"_gradient_fct")
# Generate functions for inputs
if shader_model.has("inputs"):
for i in range(shader_model.inputs.size()):
var input = shader_model.inputs[i]
if input.has("function") and input.function:
var source = get_source(i)
var string = "$%s(%s)" % [ input.name, PORT_TYPES[input.type].params ]
var local_context = MMGenContext.new(context)
var result = replace_input(string, local_context, input.name, input.type, source, input.default)
while result is GDScriptFunctionState:
result = yield(result, "completed")
# Add global definitions
for d in result.globals:
if rv.globals.find(d) == -1:
rv.globals.push_back(d)
# Add generated definitions
rv.defs += result.defs
# Add textures
for t in result.textures.keys():
rv.textures[t] = result.textures[t]
rv.defs += "%s %s_input_%s(%s) {\n" % [ PORT_TYPES[input.type].type, genname, input.name, PORT_TYPES[input.type].paramdefs ]
rv.defs += "%s\n" % result.code
rv.defs += "return %s;\n}\n" % result.string
if shader_model.has("instance"):
var subst_output = subst(shader_model.instance, context, "")
while subst_output is GDScriptFunctionState:
subst_output = yield(subst_output, "completed")
rv.defs += subst_output.string
# process textures
for t in subst_output.textures.keys():
rv.textures[t] = subst_output.textures[t]
# Add inline code # Add inline code
if shader_model.has("code"): if shader_model.has("code"):
var variant_index = context.get_variant(self, uv) var variant_index = context.get_variant(self, uv)
@ -262,9 +307,9 @@ func _get_shader_code(uv : String, output_index : int, context : MMGenContext) -
var variant_index = context.get_variant(self, variant_string) var variant_index = context.get_variant(self, variant_string)
if variant_index == -1: if variant_index == -1:
variant_index = context.get_variant(self, variant_string) variant_index = context.get_variant(self, variant_string)
for t in output_info: for f in PORT_TYPES.keys():
if output.has(t.field): if output.has(f):
var subst_output = subst(output[t.field], context, uv) var subst_output = subst(output[f], context, uv)
while subst_output is GDScriptFunctionState: while subst_output is GDScriptFunctionState:
subst_output = yield(subst_output, "completed") subst_output = yield(subst_output, "completed")
# Add global definitions # Add global definitions
@ -275,12 +320,12 @@ func _get_shader_code(uv : String, output_index : int, context : MMGenContext) -
rv.defs += subst_output.defs rv.defs += subst_output.defs
# Add generated code # Add generated code
rv.code += subst_output.code rv.code += subst_output.code
rv.code += "%s %s_%d_%d_%s = %s;\n" % [ t.type, genname, output_index, variant_index, t.field, subst_output.string ] rv.code += "%s %s_%d_%d_%s = %s;\n" % [ PORT_TYPES[f].type, genname, output_index, variant_index, f, subst_output.string ]
for t in subst_output.textures.keys(): for t in subst_output.textures.keys():
rv.textures[t] = subst_output.textures[t] rv.textures[t] = subst_output.textures[t]
for t in output_info: for f in PORT_TYPES.keys():
if output.has(t.field): if output.has(f):
rv[t.field] = "%s_%d_%d_%s" % [ genname, output_index, variant_index, t.field ] rv[f] = "%s_%d_%d_%s" % [ genname, output_index, variant_index, f ]
if shader_model.has("global") && rv.globals.find(shader_model.global) == -1: if shader_model.has("global") && rv.globals.find(shader_model.global) == -1:
rv.globals.push_back(shader_model.global) rv.globals.push_back(shader_model.global)
return rv return rv

View File

@ -34,14 +34,14 @@ func get_input_defs() -> Array:
for c in range(parameters.choices): for c in range(parameters.choices):
for o in range(parameters.outputs): for o in range(parameters.outputs):
var n = PoolByteArray([65+o]).get_string_from_ascii()+str(c) var n = PoolByteArray([65+o]).get_string_from_ascii()+str(c)
rv.push_back({ name=n, label=n, type="rgba" }) rv.push_back({ name=n, label=n, type="any" })
return rv return rv
func get_output_defs() -> Array: func get_output_defs() -> Array:
var rv : Array = [] var rv : Array = []
for o in range(parameters.outputs): for o in range(parameters.outputs):
var n = PoolByteArray([65+o]).get_string_from_ascii() var n = PoolByteArray([65+o]).get_string_from_ascii()
rv.push_back({ name=n, type="rgba" }) rv.push_back({ name=n, type="any" })
return rv return rv
func set_parameter(p, v) -> void: func set_parameter(p, v) -> void:

View File

@ -27,13 +27,86 @@ static func generate_shader(src_code) -> String:
code += g code += g
var shader_code = src_code.defs var shader_code = src_code.defs
shader_code += "\nvoid fragment() {\n" shader_code += "\nvoid fragment() {\n"
shader_code += "vec2 uv = UV;\n"
shader_code += src_code.code shader_code += src_code.code
shader_code += "COLOR = "+src_code.rgba+";\n" if src_code.has("rgba"):
shader_code += "COLOR = "+src_code.rgba+";\n"
else:
shader_code += "COLOR = vec4(1.0, 0.0, 0.0, 1.0);\n"
shader_code += "}\n" shader_code += "}\n"
#print("GENERATED SHADER:\n"+shader_code) #print("GENERATED SHADER:\n"+shader_code)
code += shader_code code += shader_code
return code return code
static func generate_preview_shader(src_code) -> String:
var code
code = "shader_type canvas_item;\n"
code += "render_mode blend_disabled;\n"
code += "uniform float preview_size = 64;\n"
var file = File.new()
file.open("res://addons/material_maker/common.shader", File.READ)
code += file.get_as_text()
code += "\n"
if src_code.has("textures"):
for t in src_code.textures.keys():
code += "uniform sampler2D "+t+";\n"
if src_code.has("globals"):
for g in src_code.globals:
code += g
var shader_code = src_code.defs
if src_code.has("rgba"):
shader_code += "\nvoid fragment() {\n"
shader_code += "vec2 uv = UV;\n"
shader_code += src_code.code
shader_code += "COLOR = "+src_code.rgba+";\n"
shader_code += "}\n"
elif src_code.has("sdf2d"):
shader_code += "\nvoid fragment() {\n"
shader_code += "vec2 uv = UV;\n"
shader_code += src_code.code
shader_code += "float d = "+src_code.sdf2d+";\n"
shader_code += "vec3 col = vec3(cos(d*min(256, preview_size)));\n"
shader_code += "col *= clamp(1.0-d*d, 0.0, 1.0);\n"
shader_code += "col *= vec3(1.0, vec2(step(-0.015, d)));\n"
shader_code += "col *= vec3(vec2(step(d, 0.015)), 1.0);\n"
shader_code += "COLOR = vec4(col, 1.0);\n"
shader_code += "}\n"
elif src_code.has("sdf3d"):
shader_code += "\nfloat calcdist(vec3 uv) {\n"
shader_code += src_code.code
shader_code += "return min("+src_code.sdf3d+", uv.z);\n"
shader_code += "}\n"
shader_code += "float raymarch(vec3 ro, vec3 rd) {\n"
shader_code += "float d=0.0;\n"
shader_code += "for (int i = 0; i < 50; i++) {\n"
shader_code += "vec3 p = ro + rd*d;\n"
shader_code += "float dstep = calcdist(p);\n"
shader_code += "d += dstep;\n"
shader_code += "if (dstep < 0.0001) break;\n"
shader_code += "}\n"
shader_code += "return d;\n"
shader_code += "}\n"
shader_code += "vec3 normal(vec3 p) {\n"
shader_code += " float d = calcdist(p);\n"
shader_code += " float e = .0001;\n"
shader_code += " vec3 n = d - vec3(calcdist(p-vec3(e, 0.0, 0.0)), calcdist(p-vec3(0.0, e, 0.0)), calcdist(p-vec3(0.0, 0.0, e)));\n"
shader_code += " return normalize(n);\n"
shader_code += "}\n"
shader_code += "\nvoid fragment() {\n"
shader_code += "vec2 uv = UV-vec2(0.5);\n"
shader_code += "vec3 p = vec3(uv, 2.0-raymarch(vec3(uv, 2.0), vec3(0.0, 0.0, -1.0)));\n"
shader_code += "vec3 n = normal(p);\n"
shader_code += "vec3 l = vec3(5.0, 5.0, 10.0);\n"
shader_code += "vec3 ld = normalize(l-p);\n"
shader_code += "float o = step(p.z, 0.001);\n"
shader_code += "float shadow = 1.0-0.75*step(raymarch(l, -ld), length(l-p)-0.01);\n"
shader_code += "float light = 0.3+0.7*dot(n, ld)*shadow;\n"
shader_code += "COLOR = vec4(vec3(0.8+0.2*o, 0.8+0.2*o, 1.0)*light, 1.0);\n"
shader_code += "}\n"
#print("GENERATED SHADER:\n"+shader_code)
code += shader_code
return code
static func generate_combined_shader(red_code, green_code, blue_code) -> String: static func generate_combined_shader(red_code, green_code, blue_code) -> String:
var code var code
code = "shader_type canvas_item;\n" code = "shader_type canvas_item;\n"
@ -44,6 +117,7 @@ static func generate_combined_shader(red_code, green_code, blue_code) -> String:
code += "\n" code += "\n"
var globals = [] var globals = []
var textures = {} var textures = {}
var output = []
for c in [ red_code, green_code, blue_code ]: for c in [ red_code, green_code, blue_code ]:
if c.has("textures"): if c.has("textures"):
for t in c.textures.keys(): for t in c.textures.keys():
@ -52,6 +126,10 @@ static func generate_combined_shader(red_code, green_code, blue_code) -> String:
for g in c.globals: for g in c.globals:
if globals.find(g) == -1: if globals.find(g) == -1:
globals.push_back(g) globals.push_back(g)
if c.has("f"):
output.push_back(c.f)
else:
output.push_back("1.0")
for t in textures.keys(): for t in textures.keys():
code += "uniform sampler2D "+t+";\n" code += "uniform sampler2D "+t+";\n"
for g in globals: for g in globals:
@ -64,7 +142,7 @@ static func generate_combined_shader(red_code, green_code, blue_code) -> String:
shader_code += red_code.code shader_code += red_code.code
shader_code += green_code.code shader_code += green_code.code
shader_code += blue_code.code shader_code += blue_code.code
shader_code += "COLOR = vec4("+red_code.f+", "+green_code.f+", "+blue_code.f+", 1.0);\n" shader_code += "COLOR = vec4("+output[0]+", "+output[1]+", "+output[2]+", 1.0);\n"
shader_code += "}\n" shader_code += "}\n"
#print("GENERATED COMBINED SHADER:\n"+shader_code) #print("GENERATED COMBINED SHADER:\n"+shader_code)
code += shader_code code += shader_code
@ -95,6 +173,7 @@ func render_shader(shader, textures, render_size) -> Object:
if textures != null: if textures != null:
for k in textures.keys(): for k in textures.keys():
shader_material.set_shader_param(k, textures[k]) shader_material.set_shader_param(k, textures[k])
shader_material.set_shader_param("preview_size", render_size)
render_target_update_mode = Viewport.UPDATE_ONCE render_target_update_mode = Viewport.UPDATE_ONCE
update_worlds() update_worlds()
yield(get_tree(), "idle_frame") yield(get_tree(), "idle_frame")

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,625 @@
{
"connections": [
{
"from": "uniform",
"from_port": 0,
"to": "Material",
"to_port": 0
},
{
"from": "graph",
"from_port": 0,
"to": "sdf3d_scale_2",
"to_port": 0
},
{
"from": "sdf3d_scale_2",
"from_port": 0,
"to": "sdf3d_repeat",
"to_port": 0
},
{
"from": "sdf3d_repeat",
"from_port": 0,
"to": "sdf3d_boolean_3",
"to_port": 0
},
{
"from": "sdf3d_scale_2",
"from_port": 0,
"to": "sdf3d_repeat_2",
"to_port": 0
},
{
"from": "sdf3d_repeat_2",
"from_port": 0,
"to": "sdf3d_translate_3_2",
"to_port": 0
},
{
"from": "sdf3d_translate_3_2",
"from_port": 0,
"to": "sdf3d_boolean_3",
"to_port": 1
},
{
"from": "sdf3d_repeat_3",
"from_port": 0,
"to": "sdf3d_boolean_3_2",
"to_port": 0
},
{
"from": "sdf3d_repeat_2_2",
"from_port": 0,
"to": "sdf3d_translate_3_2_2",
"to_port": 0
},
{
"from": "sdf3d_translate_3_2_2",
"from_port": 0,
"to": "sdf3d_boolean_3_2",
"to_port": 1
},
{
"from": "sdf3d_scale_2",
"from_port": 0,
"to": "sdf3d_repeat_3",
"to_port": 0
},
{
"from": "sdf3d_scale_2",
"from_port": 0,
"to": "sdf3d_repeat_2_2",
"to_port": 0
},
{
"from": "sdf3d_boolean_3_2",
"from_port": 0,
"to": "sdf3d_boolean_3_3",
"to_port": 1
},
{
"from": "sdf3d_boolean_3_3",
"from_port": 0,
"to": "sdf3d_translate_3_2_2_2",
"to_port": 0
},
{
"from": "sdf3d_boolean_3",
"from_port": 0,
"to": "sdf3d_translate_3_2_3",
"to_port": 0
},
{
"from": "sdf3d_translate_3_2_3",
"from_port": 0,
"to": "sdf3d_boolean_3_3",
"to_port": 0
},
{
"from": "sdf3d_translate_3_2_2_2",
"from_port": 0,
"to": "raymarching",
"to_port": 0
},
{
"from": "raymarching",
"from_port": 1,
"to": "Material",
"to_port": 4
},
{
"from": "occlusion",
"from_port": 0,
"to": "Material",
"to_port": 5
},
{
"from": "raymarching",
"from_port": 0,
"to": "occlusion",
"to_port": 0
},
{
"from": "raymarching",
"from_port": 0,
"to": "colorize",
"to_port": 0
},
{
"from": "colorize",
"from_port": 0,
"to": "Material",
"to_port": 6
}
],
"label": "Graph",
"name": "49",
"node_position": {
"x": 0,
"y": 0
},
"nodes": [
{
"name": "Material",
"node_position": {
"x": 701,
"y": 78
},
"parameters": {
"albedo_color": {
"a": 1,
"b": 1,
"g": 1,
"r": 1,
"type": "Color"
},
"ao_light_affect": 1,
"depth_scale": 0.5,
"emission_energy": 1,
"metallic": 1,
"normal_scale": 1,
"roughness": 1,
"size": 11,
"subsurf_scatter_strength": 0
},
"type": "material"
},
{
"name": "uniform",
"node_position": {
"x": 467.5,
"y": 84
},
"parameters": {
"color": {
"a": 1,
"b": 0.180392,
"g": 0.372549,
"r": 0.768627,
"type": "Color"
}
},
"type": "uniform"
},
{
"name": "sdf3d_repeat",
"node_position": {
"x": -224.214783,
"y": -156
},
"parameters": {
"a": 0,
"r": 0.3,
"rx": 6,
"ry": 6,
"s": 0.3,
"x": 0.35,
"y": 0,
"z": 0
},
"type": "sdf3d_repeat"
},
{
"name": "sdf3d_scale_2",
"node_position": {
"x": -422.214783,
"y": 72
},
"parameters": {
"a": 0,
"s": 0.25,
"x": 0.35,
"y": 0,
"z": 0
},
"type": "sdf3d_scale"
},
{
"name": "sdf3d_boolean_3",
"node_position": {
"x": -16.214783,
"y": -56
},
"parameters": {
"bevel": 0,
"cx": 0,
"cy": 0,
"h": 0.08,
"op": 0,
"r": 0.3,
"w": 0.28
},
"type": "sdf3d_boolean"
},
{
"connections": [
{
"from": "sdf3d_box",
"from_port": 0,
"to": "sdf3d_boolean",
"to_port": 1
},
{
"from": "sdf3d_box_2",
"from_port": 0,
"to": "sdf3d_translate_3_2",
"to_port": 0
},
{
"from": "sdf3d_translate_3_2",
"from_port": 0,
"to": "sdf3d_boolean",
"to_port": 0
},
{
"from": "sdf3d_translate_3_2_2",
"from_port": 0,
"to": "sdf3d_boolean_2",
"to_port": 0
},
{
"from": "sdf3d_boolean",
"from_port": 0,
"to": "sdf3d_boolean_2",
"to_port": 1
},
{
"from": "sdf3d_box_2",
"from_port": 0,
"to": "sdf3d_translate_3_2_2",
"to_port": 0
},
{
"from": "sdf3d_boolean_2",
"from_port": 0,
"to": "gen_outputs",
"to_port": 0
}
],
"label": "Brick",
"name": "graph",
"node_position": {
"x": -427.111115,
"y": 2.638885
},
"nodes": [
{
"name": "sdf3d_box",
"node_position": {
"x": -564.5,
"y": -63
},
"parameters": {
"r": 0.01,
"sx": 0.26,
"sy": 0.15,
"sz": 0.1
},
"type": "sdf3d_box"
},
{
"name": "sdf3d_translate_3_2",
"node_position": {
"x": -554.5,
"y": -166
},
"parameters": {
"x": 0,
"y": 0,
"z": 0.45
},
"type": "sdf3d_translate"
},
{
"name": "sdf3d_box_2",
"node_position": {
"x": -570.5,
"y": -294.5
},
"parameters": {
"r": 0,
"sx": 0.21,
"sy": 0.1,
"sz": 0.36
},
"type": "sdf3d_box"
},
{
"name": "sdf3d_boolean",
"node_position": {
"x": -358.5,
"y": -118
},
"parameters": {
"bevel": 0,
"cx": 0,
"cy": 0,
"h": 0.08,
"op": 1,
"r": 0.3,
"w": 0.28
},
"type": "sdf3d_boolean"
},
{
"name": "sdf3d_translate_3_2_2",
"node_position": {
"x": -343.333344,
"y": -224.333344
},
"parameters": {
"x": 0,
"y": 0,
"z": -0.45
},
"type": "sdf3d_translate"
},
{
"name": "sdf3d_boolean_2",
"node_position": {
"x": -147.333344,
"y": -168.333344
},
"parameters": {
"bevel": 0,
"cx": 0,
"cy": 0,
"h": 0.08,
"op": 1,
"r": 0.3,
"w": 0.28
},
"type": "sdf3d_boolean"
},
{
"name": "gen_inputs",
"node_position": {
"x": -748.5,
"y": -159.361115
},
"parameters": {
},
"ports": [
],
"type": "ios"
},
{
"name": "gen_outputs",
"node_position": {
"x": 60.666656,
"y": -165.361115
},
"parameters": {
},
"ports": [
{
"name": "port0",
"type": "sdf3d"
}
],
"type": "ios"
},
{
"name": "gen_parameters",
"node_position": {
"x": -488.111115,
"y": -466.5
},
"parameters": {
},
"type": "remote",
"widgets": [
]
}
],
"parameters": {
},
"type": "graph"
},
{
"name": "sdf3d_repeat_2",
"node_position": {
"x": -225.542572,
"y": -52.060181
},
"parameters": {
"a": 0,
"r": 0.3,
"rx": 6,
"ry": 6,
"s": 0.3,
"x": 0.35,
"y": 0,
"z": 0
},
"type": "sdf3d_repeat"
},
{
"name": "sdf3d_translate_3_2",
"node_position": {
"x": -224.542572,
"y": 49.939819
},
"parameters": {
"x": 0.09,
"y": 0.09,
"z": 0
},
"type": "sdf3d_translate"
},
{
"name": "sdf3d_repeat_2_2",
"node_position": {
"x": -220.331467,
"y": 259.034729
},
"parameters": {
"a": 0,
"r": 0.3,
"rx": 6,
"ry": 6,
"s": 0.3,
"x": 0.35,
"y": 0,
"z": 0
},
"type": "sdf3d_repeat"
},
{
"name": "sdf3d_repeat_3",
"node_position": {
"x": -219.003677,
"y": 155.09491
},
"parameters": {
"a": 0,
"r": 0.3,
"rx": 6,
"ry": 6,
"s": 0.3,
"x": 0.35,
"y": 0,
"z": 0
},
"type": "sdf3d_repeat"
},
{
"name": "sdf3d_translate_3_2_2",
"node_position": {
"x": -219.331467,
"y": 361.034729
},
"parameters": {
"x": 0.09,
"y": 0.09,
"z": 0
},
"type": "sdf3d_translate"
},
{
"name": "sdf3d_boolean_3_2",
"node_position": {
"x": -19.003677,
"y": 251.09491
},
"parameters": {
"bevel": 0,
"cx": 0,
"cy": 0,
"h": 0.08,
"op": 0,
"r": 0.3,
"w": 0.28
},
"type": "sdf3d_boolean"
},
{
"name": "sdf3d_boolean_3_3",
"node_position": {
"x": 183.957428,
"y": 120.689819
},
"parameters": {
"bevel": 0,
"cx": 0,
"cy": 0,
"h": 0.08,
"op": 0,
"r": 0.3,
"w": 0.28
},
"type": "sdf3d_boolean"
},
{
"name": "sdf3d_translate_3_2_2_2",
"node_position": {
"x": 179.457428,
"y": 193.189819
},
"parameters": {
"x": 0,
"y": 0,
"z": 0.3
},
"type": "sdf3d_translate"
},
{
"name": "sdf3d_translate_3_2_3",
"node_position": {
"x": -19.542572,
"y": 10.189819
},
"parameters": {
"x": 0.04,
"y": 0.04,
"z": 0.15
},
"type": "sdf3d_translate"
},
{
"name": "raymarching",
"node_position": {
"x": 187.457397,
"y": 303.189819
},
"parameters": {
},
"type": "raymarching"
},
{
"name": "occlusion",
"node_position": {
"x": 410.234558,
"y": 303.189819
},
"parameters": {
"param0": 9,
"param1": 50,
"param2": 5.2
},
"type": "occlusion"
},
{
"name": "colorize",
"node_position": {
"x": 430.387573,
"y": 218.189819
},
"parameters": {
"gradient": {
"interpolation": 1,
"points": [
{
"a": 1,
"b": 1,
"g": 1,
"pos": 0,
"r": 1
},
{
"a": 1,
"b": 0,
"g": 0,
"pos": 0.563636,
"r": 0
}
],
"type": "Gradient"
}
},
"type": "colorize"
}
],
"parameters": {
},
"type": "graph"
}

View File

@ -0,0 +1,389 @@
{
"connections": [
{
"from": "sdbox",
"from_port": 0,
"to": "sdboolean",
"to_port": 1
},
{
"from": "sdrhombus_2",
"from_port": 0,
"to": "sdboolean",
"to_port": 0
},
{
"from": "sdboolean",
"from_port": 0,
"to": "_4_2_3",
"to_port": 0
},
{
"from": "_4_2_3",
"from_port": 0,
"to": "sdf3d_revolution",
"to_port": 0
},
{
"from": "sdf3d_revolution",
"from_port": 0,
"to": "sdrotate",
"to_port": 0
},
{
"from": "raymarching",
"from_port": 1,
"to": "Material",
"to_port": 4
},
{
"from": "sdrotate",
"from_port": 0,
"to": "raymarching",
"to_port": 0
},
{
"from": "uniform",
"from_port": 0,
"to": "Material",
"to_port": 0
},
{
"from": "uniform",
"from_port": 0,
"to": "Material",
"to_port": 1
}
],
"label": "Graph",
"name": "49",
"node_position": {
"x": 0,
"y": 0
},
"nodes": [
{
"name": "Material",
"node_position": {
"x": -336,
"y": 266
},
"parameters": {
"albedo_color": {
"a": 1,
"b": 1,
"g": 1,
"r": 1,
"type": "Color"
},
"ao_light_affect": 1,
"depth_scale": 1,
"emission_energy": 1,
"metallic": 1,
"normal_scale": 1,
"roughness": 1,
"size": 11,
"subsurf_scatter_strength": 0
},
"type": "material"
},
{
"name": "sdrotate",
"node_position": {
"x": -722.057617,
"y": 347.909668
},
"parameters": {
"a": 0,
"ax": 18,
"ay": -28,
"az": -29,
"x": 0.35,
"y": 0,
"z": 0
},
"shader_model": {
"code": "",
"global": "vec3 rotate3d(vec3 p, vec3 a) {\n\tvec3 rv;\n\tfloat c;\n\tfloat s;\n\tc = cos(a.x);\n\ts = sin(a.x);\n\trv.x = p.x;\n\trv.y = p.y*c+p.z*s;\n\trv.z = -p.y*s+p.z*c;\n\tc = cos(a.y);\n\ts = sin(a.y);\n\tp.x = rv.x*c+rv.z*s;\n\tp.y = rv.y;\n\tp.z = -rv.x*s+rv.z*c;\n\tc = cos(a.z);\n\ts = sin(a.z);\n\trv.x = p.x*c+p.y*s;\n\trv.y = -p.x*s+p.y*c;\n\trv.z = p.z;\n\treturn rv;\n}\n",
"inputs": [
{
"default": "0.0",
"label": "",
"name": "in",
"type": "sdf3d"
}
],
"instance": "",
"name": "Rotate",
"outputs": [
{
"sdf3d": "$in(rotate3d($uv, -vec3($ax, $ay, $az)*0.01745329251))",
"type": "sdf3d"
}
],
"parameters": [
{
"default": 0,
"label": "X",
"max": 180,
"min": -180,
"name": "ax",
"step": 1,
"type": "float"
},
{
"default": 0,
"label": "Y",
"max": 180,
"min": -180,
"name": "ay",
"step": 1,
"type": "float"
},
{
"default": 0,
"label": "Z",
"max": 180,
"min": -180,
"name": "az",
"step": 1,
"type": "float"
}
]
},
"type": "shader"
},
{
"name": "sdrhombus_2",
"node_position": {
"x": -1116.057617,
"y": 261.159668
},
"parameters": {
"cx": 0,
"cy": 0,
"h": 0.29,
"r": 0.3,
"w": 0.3
},
"type": "sdrhombus"
},
{
"name": "sdbox",
"node_position": {
"x": -1119.057617,
"y": 401.159668
},
"parameters": {
"cx": 0,
"cy": 0,
"h": 0.2,
"r": 0.3,
"w": 0.2
},
"shader_model": {
"code": "vec2 $(name_uv)_d = abs($uv-0.5*vec2($cx+1.0, $cy+1.0))-vec2($w, $h);\n",
"global": "",
"inputs": [
],
"instance": "",
"name": "sdBox",
"outputs": [
{
"sdf2d": "length(max($(name_uv)_d,vec2(0)))+min(max($(name_uv)_d.x,$(name_uv)_d.y),0.0)",
"type": "sdf2d"
}
],
"parameters": [
{
"default": 0.5,
"label": "Width",
"max": 1,
"min": 0,
"name": "w",
"step": 0.01,
"type": "float"
},
{
"default": 1,
"label": "Height",
"max": 1,
"min": 0,
"name": "h",
"step": 0.01,
"type": "float"
},
{
"default": 0,
"label": "Center X",
"max": 1,
"min": -1,
"name": "cx",
"step": 0.01,
"type": "float"
},
{
"default": 0,
"label": "Center Y",
"max": 1,
"min": -1,
"name": "cy",
"step": 0.01,
"type": "float"
}
]
},
"type": "shader"
},
{
"name": "sdboolean",
"node_position": {
"x": -894.057617,
"y": 297.159668
},
"parameters": {
"bevel": 0,
"cx": 0,
"cy": 0,
"h": 0.08,
"op": 0,
"r": 0.3,
"w": 0.28
},
"type": "sdboolean"
},
{
"name": "_4_2_3",
"node_position": {
"x": -903.047241,
"y": 363.697357
},
"parameters": {
"x": 0,
"y": 0,
"z": 0
},
"shader_model": {
"code": "",
"global": "",
"inputs": [
{
"default": "0.0",
"label": "",
"name": "in",
"type": "sdf2d"
}
],
"instance": "",
"name": "Translate",
"outputs": [
{
"sdf2d": "$in($uv-vec2($x, $y))",
"type": "sdf2d"
}
],
"parameters": [
{
"default": 0,
"label": "X",
"max": 1,
"min": -1,
"name": "x",
"step": 0.01,
"type": "float"
},
{
"default": 0,
"label": "Y",
"max": 1,
"min": -1,
"name": "y",
"step": 0.01,
"type": "float"
}
]
},
"type": "shader"
},
{
"name": "sdf3d_revolution",
"node_position": {
"x": -714.403931,
"y": 295.330994
},
"parameters": {
"a": 0,
"d": 0.43,
"s": 1,
"x": 0.35,
"y": 0,
"z": 0
},
"shader_model": {
"code": "vec2 $(name_uv)_w = vec2($in($uv.xz+vec2(0.5)),abs($uv.y)-$d);\n",
"global": "",
"inputs": [
{
"default": "0.0",
"label": "",
"name": "in",
"type": "sdf2d"
}
],
"instance": "",
"name": "Extrusion",
"outputs": [
{
"sdf3d": "min(max($(name_uv)_w.x,$(name_uv)_w.y),0.0)+length(max($(name_uv)_w,0.0))",
"type": "sdf3d"
}
],
"parameters": [
{
"default": 0.25,
"label": "",
"max": 1,
"min": 0,
"name": "d",
"step": 0.01,
"type": "float"
}
]
},
"type": "shader"
},
{
"name": "raymarching",
"node_position": {
"x": -522.23468,
"y": 348.748474
},
"parameters": {
},
"type": "raymarching"
},
{
"name": "uniform",
"node_position": {
"x": -576.760742,
"y": 211.755493
},
"parameters": {
"color": {
"a": 1,
"b": 1,
"g": 0.415686,
"r": 0,
"type": "Color"
}
},
"type": "uniform"
}
],
"parameters": {
},
"type": "graph"
}

File diff suppressed because it is too large Load Diff

View File

@ -22,6 +22,9 @@ signal graph_changed
func _ready() -> void: func _ready() -> void:
OS.low_processor_usage_mode = true OS.low_processor_usage_mode = true
center_view() center_view()
for t in range(5):
add_valid_connection_type(t, 42)
add_valid_connection_type(42, t)
func _gui_input(event) -> void: func _gui_input(event) -> void:
if event is InputEventKey and event.pressed: if event is InputEventKey and event.pressed:

View File

@ -64,8 +64,10 @@ func get_preview_texture(data : Dictionary) -> ImageTexture:
image_path = ProjectSettings.globalize_path(image_path) image_path = ProjectSettings.globalize_path(image_path)
t = ImageTexture.new() t = ImageTexture.new()
var image : Image = Image.new() var image : Image = Image.new()
image.load(image_path) if image.load(image_path) == OK:
t.create_from_image(image) t.create_from_image(image)
else:
print("Cannot load image "+image_path)
return t return t
return null return null

View File

@ -587,30 +587,7 @@
"parameters": { "parameters": {
}, },
"shader_model": { "type": "circle_map"
"code": "",
"global": "",
"inputs": [
{
"default": "vec4($uv, 0.0, 1.0)",
"label": "",
"name": "in",
"type": "rgba"
}
],
"instance": "",
"name": "CircleMap",
"outputs": [
{
"rgba": "$in(vec2(fract(atan($uv.y-0.5, $uv.x-0.5)*0.15915494309), 2.0*length($uv-vec2(0.5))))",
"type": "rgba"
}
],
"parameters": [
]
},
"type": "shader"
}, },
{ {
"name": "gen_parameters", "name": "gen_parameters",
@ -723,6 +700,25 @@
"tree_item": "Simple/Gradient/Circular", "tree_item": "Simple/Gradient/Circular",
"type": "graph" "type": "graph"
}, },
{
"collapsed": true,
"icon": "simple_sdf_sdshow",
"name": "sdshow",
"parameters": {
"bevel": 0.1,
"cx": 0,
"cy": 0,
"h": 0.08,
"r": 0.3,
"w": 0.28
},
"tree_item": "Simple/SDF/sdShow",
"type": "sdshow"
},
{
"collapsed": false,
"tree_item": "Simple/SDF/Shapes"
},
{ {
"collapsed": true, "collapsed": true,
"icon": "simple_sdf_shapes_sdcircle", "icon": "simple_sdf_shapes_sdcircle",
@ -730,7 +726,7 @@
"parameters": { "parameters": {
"cx": 0, "cx": 0,
"cy": 0, "cy": 0,
"r": 0.25 "r": 0.4
}, },
"tree_item": "Simple/SDF/Shapes/sdCircle", "tree_item": "Simple/SDF/Shapes/sdCircle",
"type": "sdcircle" "type": "sdcircle"
@ -781,6 +777,26 @@
"tree_item": "Simple/SDF/Shapes/sdRhombus", "tree_item": "Simple/SDF/Shapes/sdRhombus",
"type": "sdrhombus" "type": "sdrhombus"
}, },
{
"collapsed": true,
"icon": "simple_sdf_shapes_sdarc",
"name": "sdarc",
"parameters": {
"a1": 0,
"a2": 0,
"cx": 0,
"cy": 0,
"r": 0.4,
"r1": 0.3,
"r2": 0.1
},
"tree_item": "Simple/SDF/Shapes/sdArc",
"type": "sdarc"
},
{
"collapsed": false,
"tree_item": "Simple/SDF/Operators"
},
{ {
"collapsed": true, "collapsed": true,
"icon": "simple_sdf_operators_sdboolean", "icon": "simple_sdf_operators_sdboolean",
@ -811,65 +827,8 @@
"r": 0.3, "r": 0.3,
"w": 0.28 "w": 0.28
}, },
"shader_model": {
"code": "",
"global": "float sdSmoothUnion( float d1, float d2, float k ) {\n float h = clamp( 0.5 + 0.5*(d2-d1)/k, 0.0, 1.0 );\n return mix( d2, d1, h ) - k*h*(1.0-h); }\n\nfloat sdSmoothSubtraction( float d1, float d2, float k ) {\n float h = clamp( 0.5 - 0.5*(d2+d1)/k, 0.0, 1.0 );\n return mix( d2, -d1, h ) + k*h*(1.0-h); }\n\nfloat sdSmoothIntersection( float d1, float d2, float k ) {\n float h = clamp( 0.5 - 0.5*(d2-d1)/k, 0.0, 1.0 );\n return mix( d2, d1, h ) + k*h*(1.0-h); }\n",
"inputs": [
{
"default": "0.0",
"label": "",
"name": "in1",
"type": "f"
},
{
"default": "0.0",
"label": "",
"name": "in2",
"type": "f"
}
],
"instance": "",
"name": "sdSmoothBoolean",
"outputs": [
{
"f": "sdSmooth$op($in1($uv), $in2($uv), $k)",
"type": "f"
}
],
"parameters": [
{
"default": 0,
"label": "",
"name": "op",
"type": "enum",
"values": [
{
"name": "Union",
"value": "Union"
},
{
"name": "Subtraction",
"value": "Subtraction"
},
{
"name": "Intersection",
"value": "Intersection"
}
]
},
{
"default": 0,
"label": "",
"max": 1,
"min": 0,
"name": "k",
"step": 0.01,
"type": "float"
}
]
},
"tree_item": "Simple/SDF/Operators/sdSmoothBoolean", "tree_item": "Simple/SDF/Operators/sdSmoothBoolean",
"type": "shader" "type": "sdsmoothboolean"
}, },
{ {
"collapsed": true, "collapsed": true,
@ -882,7 +841,7 @@
"h": 0.08, "h": 0.08,
"k": 0.15, "k": 0.15,
"op": 0, "op": 0,
"r": 0.1, "r": 0.2,
"w": 0.28 "w": 0.28
}, },
"tree_item": "Simple/SDF/Operators/sdRoundedShape", "tree_item": "Simple/SDF/Operators/sdRoundedShape",
@ -899,57 +858,316 @@
"h": 0.08, "h": 0.08,
"k": 0.15, "k": 0.15,
"op": 0, "op": 0,
"r": 0.05, "r": 0.1,
"w": 0.28 "w": 0.28
}, },
"tree_item": "Simple/SDF/Operators/sdAnnularShape", "tree_item": "Simple/SDF/Operators/sdAnnularShape",
"type": "sdannularshape" "type": "sdannularshape"
}, },
{
"collapsed": false,
"tree_item": "Simple/SDF/Transforms"
},
{ {
"collapsed": true, "collapsed": true,
"icon": "simple_sdf_operators_sdshow", "icon": "simple_sdf_transforms_translate",
"name": "sdshow", "name": "sdtranslate",
"parameters": { "parameters": {
"bevel": 0.1, "x": 0,
"y": 0,
"z": 0
},
"tree_item": "Simple/SDF/Transforms/Translate",
"type": "sdtranslate"
},
{
"collapsed": true,
"icon": "simple_sdf_transforms_rotate",
"name": "sdrotate",
"parameters": {
"a": 0,
"x": 0.35,
"y": 0,
"z": 0
},
"tree_item": "Simple/SDF/Transforms/Rotate",
"type": "sdrotate"
},
{
"collapsed": true,
"icon": "simple_sdf_transforms_scale",
"name": "sdscale_2",
"parameters": {
"a": 0,
"s": 1,
"x": 0.35,
"y": 0,
"z": 0
},
"tree_item": "Simple/SDF/Transforms/Scale",
"type": "sdscale"
},
{
"collapsed": false,
"tree_item": "3D"
},
{
"collapsed": true,
"icon": "3d_sdf_render",
"name": "raymarching",
"parameters": {
},
"tree_item": "3D/SDF/Render",
"type": "raymarching"
},
{
"collapsed": false,
"tree_item": "3D/SDF/Shapes"
},
{
"collapsed": true,
"icon": "3d_sdf_shapes_sphere",
"name": "sdf3d_sphere",
"parameters": {
"r": 0.4
},
"tree_item": "3D/SDF/Shapes/Sphere",
"type": "sdf3d_sphere"
},
{
"collapsed": true,
"icon": "3d_sdf_shapes_box",
"name": "sdf3d_box",
"parameters": {
"r": 0.01,
"sx": 0.3,
"sy": 0.25,
"sz": 0.25
},
"tree_item": "3D/SDF/Shapes/Box",
"type": "sdf3d_box"
},
{
"collapsed": true,
"icon": "3d_sdf_shapes_cylinder",
"name": "sdf3d_cylinder",
"parameters": {
"l": 0.25,
"r": 0.25,
"sx": 0.25,
"sy": 0.25,
"sz": 0.5
},
"tree_item": "3D/SDF/Shapes/Cylinder",
"type": "sdf3d_cylinder"
},
{
"collapsed": true,
"icon": "3d_sdf_shapes_capsule",
"name": "sdf3d_capsule",
"parameters": {
"l": 0.3,
"r": 0.2,
"sx": 0.25,
"sy": 0.25,
"sz": 0.5
},
"tree_item": "3D/SDF/Shapes/Capsule",
"type": "sdf3d_capsule"
},
{
"collapsed": true,
"icon": "3d_sdf_shapes_cone",
"name": "sdf3d_cone",
"parameters": {
"a": 30,
"r": 0,
"sx": 0.01,
"sy": 0.01,
"sz": 0.015
},
"tree_item": "3D/SDF/Shapes/Cone",
"type": "sdf3d_cone"
},
{
"collapsed": true,
"icon": "3d_sdf_shapes_torus",
"name": "sdf3d_torus",
"parameters": {
"R": 0.3,
"r": 0.15,
"sx": 0.1,
"sy": 0.1,
"sz": 0.02
},
"tree_item": "3D/SDF/Shapes/Torus",
"type": "sdf3d_torus"
},
{
"collapsed": false,
"tree_item": "3D/SDF/Operators"
},
{
"collapsed": true,
"icon": "3d_sdf_operators_boolean",
"name": "sdf3d_boolean",
"parameters": {
"bevel": 0,
"cx": 0, "cx": 0,
"cy": 0, "cy": 0,
"h": 0.08, "h": 0.08,
"op": 0,
"r": 0.3, "r": 0.3,
"w": 0.28 "w": 0.28
}, },
"shader_model": { "tree_item": "3D/SDF/Operators/Boolean",
"code": "", "type": "sdf3d_boolean"
"global": "", },
"inputs": [ {
{ "collapsed": true,
"default": "0.0", "icon": "3d_sdf_operators_smoothboolean",
"label": "", "name": "sdf3d_smoothboolean",
"name": "in", "parameters": {
"type": "f" "bevel": 0,
} "cx": 0,
], "cy": 0,
"instance": "", "h": 0.08,
"name": "sdShow", "k": 0.15,
"outputs": [ "op": 0,
{ "r": 0.3,
"f": "clamp(-$in($uv)/max($bevel, 0.00001), 0.0, 1.0)", "w": 0.28
"type": "f"
}
],
"parameters": [
{
"default": 0,
"label": "Bevel",
"max": 1,
"min": 0,
"name": "bevel",
"step": 0.01,
"type": "float"
}
]
}, },
"tree_item": "Simple/SDF/Operators/sdShow", "tree_item": "3D/SDF/Operators/SmoothBoolean",
"type": "shader" "type": "sdf3d_smoothboolean"
},
{
"collapsed": true,
"icon": "3d_sdf_operators_rounded",
"name": "sdf3d_rounded",
"parameters": {
"bevel": 0,
"cx": 0,
"cy": 0,
"h": 0.08,
"k": 0.15,
"op": 0,
"r": 0.15,
"w": 0.28
},
"tree_item": "3D/SDF/Operators/Rounded",
"type": "sdf3d_rounded"
},
{
"collapsed": true,
"icon": "3d_sdf_operators_repeat",
"name": "sdf3d_repeat",
"parameters": {
"a": 0,
"r": 0.3,
"rx": 3,
"ry": 3,
"s": 0.3,
"x": 0.35,
"y": 0,
"z": 0
},
"tree_item": "3D/SDF/Operators/Repeat",
"type": "sdf3d_repeat"
},
{
"collapsed": true,
"icon": "3d_sdf_operators_circlerepeat",
"name": "sdf3d_circle_repeat",
"parameters": {
"a": 0,
"c": 5,
"r": 0.24,
"rx": 4,
"ry": 4,
"s": 0.3,
"x": 0.35,
"y": 0,
"z": 0
},
"tree_item": "3D/SDF/Operators/CircleRepeat",
"type": "sdf3d_circle_repeat"
},
{
"collapsed": true,
"icon": "3d_sdf_operators_extrusion",
"name": "sdf3d_extrusion",
"parameters": {
"a": 0,
"d": 0.3,
"s": 1,
"x": 0.35,
"y": 0,
"z": 0
},
"tree_item": "3D/SDF/Operators/Extrusion",
"type": "sdf3d_extrusion"
},
{
"collapsed": true,
"icon": "3d_sdf_operators_revolution",
"name": "sdf3d_revolution",
"parameters": {
"a": 0,
"d": 0.25,
"s": 1,
"x": 0.35,
"y": 0,
"z": 0
},
"tree_item": "3D/SDF/Operators/Revolution",
"type": "sdf3d_revolution"
},
{
"collapsed": false,
"tree_item": "3D/SDF/Transforms"
},
{
"collapsed": true,
"icon": "3d_sdf_transforms_translate",
"name": "sdf3d_translate_3_2",
"parameters": {
"x": 0,
"y": 0,
"z": 0
},
"tree_item": "3D/SDF/Transforms/Translate",
"type": "sdf3d_translate"
},
{
"collapsed": true,
"icon": "3d_sdf_transforms_scale",
"name": "sdf3d_scale_2",
"parameters": {
"a": 0,
"s": 1,
"x": 0.35,
"y": 0,
"z": 0
},
"tree_item": "3D/SDF/Transforms/Scale",
"type": "sdf3d_scale"
},
{
"collapsed": true,
"icon": "3d_sdf_transforms_rotate",
"name": "sdf3d_rotate_2",
"parameters": {
"a": 0,
"ax": 0,
"ay": 0,
"az": 0,
"x": 0.35,
"y": 0,
"z": 0
},
"tree_item": "3D/SDF/Transforms/Rotate",
"type": "sdf3d_rotate"
}, },
{ {
"collapsed": false, "collapsed": false,
@ -1130,7 +1348,7 @@
], ],
"icon": "pattern_fibers", "icon": "pattern_fibers",
"label": "Fibers", "label": "Fibers",
"name": "graph", "name": "graph_4",
"nodes": [ "nodes": [
{ {
"name": "transform", "name": "transform",
@ -1140,7 +1358,7 @@
}, },
"parameters": { "parameters": {
"repeat": true, "repeat": true,
"rotate": 45, "rotate": 30.125,
"scale_x": 0.5, "scale_x": 0.5,
"scale_y": 1, "scale_y": 1,
"translate_x": 0.975, "translate_x": 0.975,
@ -1156,6 +1374,7 @@
}, },
"parameters": { "parameters": {
"gradient": { "gradient": {
"interpolation": 1,
"points": [ "points": [
{ {
"a": 1, "a": 1,
@ -1186,9 +1405,11 @@
"parameters": { "parameters": {
"bevel": 0.1, "bevel": 0.1,
"columns": 4, "columns": 4,
"corner": 0,
"mortar": 0.1, "mortar": 0.1,
"pattern": 0, "pattern": 0,
"repeat": 1, "repeat": 1,
"round": 0,
"row_offset": 0.5, "row_offset": 0.5,
"rows": 1 "rows": 1
}, },
@ -1239,8 +1460,8 @@
{ {
"name": "gen_parameters", "name": "gen_parameters",
"node_position": { "node_position": {
"x": -433.557495, "x": -429.557495,
"y": -236.5 "y": -266.5
}, },
"parameters": { "parameters": {
"param0": 4 "param0": 4
@ -1322,6 +1543,17 @@
"tree_item": "Pattern/Scratches", "tree_item": "Pattern/Scratches",
"type": "scratches" "type": "scratches"
}, },
{
"collapsed": true,
"icon": "pattern_beehive",
"name": "beehive",
"parameters": {
"sx": 4,
"sy": 4
},
"tree_item": "Pattern/Beehive",
"type": "beehive"
},
{ {
"collapsed": false, "collapsed": false,
"icon": "noise", "icon": "noise",

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 860 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 730 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 864 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 904 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 745 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 643 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 814 B

After

Width:  |  Height:  |  Size: 984 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 951 B

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 750 B

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 723 B

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 679 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Some files were not shown because too many files have changed in this diff Show More