Merge branch 'master' into dev-ui

This commit is contained in:
Rodolphe Suescun 2019-12-25 20:16:50 +01:00
commit a806ea19a3
141 changed files with 6879 additions and 743 deletions

View File

@ -8,6 +8,7 @@ to describe procedural materials.
:maxdepth: 2
nodes_simple
nodes_3d
nodes_pattern
nodes_noise
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
shapes.
@ -7,7 +7,7 @@ shapes.
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.
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
`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:
* 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
editable so the subgraph inputs and outputs can be added, removed reordered or
renamed. Please note that all those operations will (when possible) keep
connectivity inside and outside the subgraph.
editable so the subgraph inputs and outputs can be added, removed, reordered,
renamed or have their types modified.
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
parameters to the parent graph. When grouping nodes with a **remote**, the
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_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:
init_parameters()
@ -151,14 +162,18 @@ func get_input_shader(input_index : int) -> Dictionary:
func get_shader(output_index : int, context) -> Dictionary:
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 source = get_shader_code("UV", output_index, context)
var source = get_shader_code("uv", output_index, context)
while source is GDScriptFunctionState:
source = yield(source, "completed")
if source.empty():
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)
while result is GDScriptFunctionState:
result = yield(result, "completed")
@ -174,14 +189,13 @@ func get_shader_code(uv : String, output_index : int, context : MMGenContext) ->
rv.f = "(dot("+rv.rgb+", vec3(1.0))/3.0)"
elif rv.has("rgba"):
rv.f = "(dot("+rv.rgba+".rgb, vec3(1.0))/3.0)"
else:
rv.f = "0.0"
if !rv.has("rgb"):
if rv.has("rgba"):
rv.rgb = rv.rgba+".rgb"
else:
elif rv.has("f"):
rv.rgb = "vec3("+rv.f+")"
if !rv.has("rgba"):
if rv.has("rgb"):
rv.rgba = "vec4("+rv.rgb+", 1.0)"
return rv

View File

@ -4,10 +4,19 @@ class_name MMGenContext
var variants : Dictionary = {}
var parent_context : MMGenContext = null
func _init(p = null) -> void:
parent_context = p
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:
var rv = -1
@ -17,4 +26,5 @@ func get_variant(generator, variant) -> int:
variants[generator].push_back(variant)
else:
variants[generator] = [variant]
touch_variant(generator)
return rv

View File

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

View File

@ -27,7 +27,7 @@ func get_type_name() -> String:
func get_io_defs() -> Array:
var rv : Array = []
for p in ports:
rv.push_back({ name=p.name, type="rgba" })
rv.push_back({ name=p.name, type=p.type })
return rv
func get_input_defs() -> Array:
@ -54,6 +54,11 @@ func add_port() -> void:
func set_port_name(i : int, n : String) -> void:
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:
ports.remove(i)
var input_gen = get_parent() if name == "gen_inputs" else self

View File

@ -2,11 +2,13 @@ tool
extends MMGenBase
class_name MMGenShader
var shader_model : Dictionary = {}
var uses_seed = false
var editable = false
func toggle_editable() -> bool:
editable = !editable
if editable:
@ -53,16 +55,12 @@ func set_shader_model(data: Dictionary) -> void:
for i in range(shader_model.outputs.size()):
var output = shader_model.outputs[i]
var output_code = ""
if output.has("rgba"):
shader_model.outputs[i].type = "rgba"
output_code = output.rgba
elif output.has("rgb"):
shader_model.outputs[i].type = "rgb"
output_code = output.rgb
elif output.has("f"):
shader_model.outputs[i].type = "f"
output_code = output.f
else:
for f in PORT_TYPES.keys():
if output.has(f):
shader_model.outputs[i].type = f
output_code = output[f]
break
if output_code == "":
print("Unsupported output type")
if output_code.find("$seed") != -1 or output_code.find("$(seed)") != -1:
uses_seed = true
@ -90,7 +88,19 @@ func find_keyword_call(string, keyword):
parenthesis_level -= 1
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_defs = ""
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)
while src_code is GDScriptFunctionState:
src_code = yield(src_code, "completed")
if src_code.has(type):
src_code.string = src_code[type]
else:
src_code.string = "*error*"
# Add global definitions
if src_code.has("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:
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)
var keyword_size = variable.length()+1
var new_string = ""
@ -152,7 +165,7 @@ func replace_variable(string, variable, value) -> String:
string = string.right(keyword_size)
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 required_globals = []
var required_defs = ""
@ -199,6 +212,9 @@ func subst(string, context, uv = "") -> Dictionary:
for i in range(shader_model.inputs.size()):
var input = shader_model.inputs[i]
var source = get_source(i)
if input.has("function") and input.function:
string = replace_input_with_function_call(string, input.name)
else:
var result = replace_input(string, context, input.name, input.type, source, input.default)
while result is GDScriptFunctionState:
result = yield(result, "completed")
@ -220,19 +236,17 @@ func subst(string, context, uv = "") -> Dictionary:
cont = changed and new_pass_required
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:
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={} }
if shader_model != null and shader_model.has("outputs") and shader_model.outputs.size() > output_index:
var output = shader_model.outputs[output_index]
if shader_model.has("instance") && !context.has_variant(self):
var subst_output = subst(shader_model.instance, context, "")
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]
if !context.has_variant(self):
# Generate functions for gradients
for p in shader_model.parameters:
if p.type == "gradient":
var g = parameters[p.name]
@ -240,6 +254,37 @@ func _get_shader_code(uv : String, output_index : int, context : MMGenContext) -
g = MMGradient.new()
g.deserialize(parameters[p.name])
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
if shader_model.has("code"):
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)
if variant_index == -1:
variant_index = context.get_variant(self, variant_string)
for t in output_info:
if output.has(t.field):
var subst_output = subst(output[t.field], context, uv)
for f in PORT_TYPES.keys():
if output.has(f):
var subst_output = subst(output[f], context, uv)
while subst_output is GDScriptFunctionState:
subst_output = yield(subst_output, "completed")
# Add global definitions
@ -275,12 +320,12 @@ func _get_shader_code(uv : String, output_index : int, context : MMGenContext) -
rv.defs += subst_output.defs
# Add generated 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():
rv.textures[t] = subst_output.textures[t]
for t in output_info:
if output.has(t.field):
rv[t.field] = "%s_%d_%d_%s" % [ genname, output_index, variant_index, t.field ]
for f in PORT_TYPES.keys():
if output.has(f):
rv[f] = "%s_%d_%d_%s" % [ genname, output_index, variant_index, f ]
if shader_model.has("global") && rv.globals.find(shader_model.global) == -1:
rv.globals.push_back(shader_model.global)
return rv

View File

@ -34,14 +34,14 @@ func get_input_defs() -> Array:
for c in range(parameters.choices):
for o in range(parameters.outputs):
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
func get_output_defs() -> Array:
var rv : Array = []
for o in range(parameters.outputs):
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
func set_parameter(p, v) -> void:

View File

@ -27,9 +27,82 @@ static func generate_shader(src_code) -> String:
code += g
var shader_code = src_code.defs
shader_code += "\nvoid fragment() {\n"
shader_code += "vec2 uv = UV;\n"
shader_code += src_code.code
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"
#print("GENERATED SHADER:\n"+shader_code)
code += shader_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
@ -44,6 +117,7 @@ static func generate_combined_shader(red_code, green_code, blue_code) -> String:
code += "\n"
var globals = []
var textures = {}
var output = []
for c in [ red_code, green_code, blue_code ]:
if c.has("textures"):
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:
if globals.find(g) == -1:
globals.push_back(g)
if c.has("f"):
output.push_back(c.f)
else:
output.push_back("1.0")
for t in textures.keys():
code += "uniform sampler2D "+t+";\n"
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 += green_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"
#print("GENERATED COMBINED SHADER:\n"+shader_code)
code += shader_code
@ -95,6 +173,7 @@ func render_shader(shader, textures, render_size) -> Object:
if textures != null:
for k in textures.keys():
shader_material.set_shader_param(k, textures[k])
shader_material.set_shader_param("preview_size", render_size)
render_target_update_mode = Viewport.UPDATE_ONCE
update_worlds()
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

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

View File

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

View File

@ -587,30 +587,7 @@
"parameters": {
},
"shader_model": {
"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"
"type": "circle_map"
},
{
"name": "gen_parameters",
@ -723,6 +700,25 @@
"tree_item": "Simple/Gradient/Circular",
"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,
"icon": "simple_sdf_shapes_sdcircle",
@ -730,7 +726,7 @@
"parameters": {
"cx": 0,
"cy": 0,
"r": 0.25
"r": 0.4
},
"tree_item": "Simple/SDF/Shapes/sdCircle",
"type": "sdcircle"
@ -781,6 +777,26 @@
"tree_item": "Simple/SDF/Shapes/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,
"icon": "simple_sdf_operators_sdboolean",
@ -811,65 +827,8 @@
"r": 0.3,
"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",
"type": "shader"
"type": "sdsmoothboolean"
},
{
"collapsed": true,
@ -882,7 +841,7 @@
"h": 0.08,
"k": 0.15,
"op": 0,
"r": 0.1,
"r": 0.2,
"w": 0.28
},
"tree_item": "Simple/SDF/Operators/sdRoundedShape",
@ -899,57 +858,316 @@
"h": 0.08,
"k": 0.15,
"op": 0,
"r": 0.05,
"r": 0.1,
"w": 0.28
},
"tree_item": "Simple/SDF/Operators/sdAnnularShape",
"type": "sdannularshape"
},
{
"collapsed": false,
"tree_item": "Simple/SDF/Transforms"
},
{
"collapsed": true,
"icon": "simple_sdf_operators_sdshow",
"name": "sdshow",
"icon": "simple_sdf_transforms_translate",
"name": "sdtranslate",
"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,
"cy": 0,
"h": 0.08,
"op": 0,
"r": 0.3,
"w": 0.28
},
"shader_model": {
"code": "",
"global": "",
"inputs": [
{
"default": "0.0",
"label": "",
"name": "in",
"type": "f"
}
],
"instance": "",
"name": "sdShow",
"outputs": [
{
"f": "clamp(-$in($uv)/max($bevel, 0.00001), 0.0, 1.0)",
"type": "f"
}
],
"parameters": [
{
"default": 0,
"label": "Bevel",
"max": 1,
"min": 0,
"name": "bevel",
"step": 0.01,
"type": "float"
}
]
"tree_item": "3D/SDF/Operators/Boolean",
"type": "sdf3d_boolean"
},
"tree_item": "Simple/SDF/Operators/sdShow",
"type": "shader"
{
"collapsed": true,
"icon": "3d_sdf_operators_smoothboolean",
"name": "sdf3d_smoothboolean",
"parameters": {
"bevel": 0,
"cx": 0,
"cy": 0,
"h": 0.08,
"k": 0.15,
"op": 0,
"r": 0.3,
"w": 0.28
},
"tree_item": "3D/SDF/Operators/SmoothBoolean",
"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,
@ -1130,7 +1348,7 @@
],
"icon": "pattern_fibers",
"label": "Fibers",
"name": "graph",
"name": "graph_4",
"nodes": [
{
"name": "transform",
@ -1140,7 +1358,7 @@
},
"parameters": {
"repeat": true,
"rotate": 45,
"rotate": 30.125,
"scale_x": 0.5,
"scale_y": 1,
"translate_x": 0.975,
@ -1156,6 +1374,7 @@
},
"parameters": {
"gradient": {
"interpolation": 1,
"points": [
{
"a": 1,
@ -1186,9 +1405,11 @@
"parameters": {
"bevel": 0.1,
"columns": 4,
"corner": 0,
"mortar": 0.1,
"pattern": 0,
"repeat": 1,
"round": 0,
"row_offset": 0.5,
"rows": 1
},
@ -1239,8 +1460,8 @@
{
"name": "gen_parameters",
"node_position": {
"x": -433.557495,
"y": -236.5
"x": -429.557495,
"y": -266.5
},
"parameters": {
"param0": 4
@ -1322,6 +1543,17 @@
"tree_item": "Pattern/Scratches",
"type": "scratches"
},
{
"collapsed": true,
"icon": "pattern_beehive",
"name": "beehive",
"parameters": {
"sx": 4,
"sy": 4
},
"tree_item": "Pattern/Beehive",
"type": "beehive"
},
{
"collapsed": false,
"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