Integrated as a button in toolbar, and added a simple mesh painting tool

This commit is contained in:
Rodolphe Suescun 2018-08-16 15:08:09 +02:00
parent 4165fec6c3
commit 0191876430
36 changed files with 2235 additions and 14 deletions

View File

@ -1,6 +1,6 @@
tool
extends Tree
func get_drag_data(position):
var selected_item = get_selected()
if selected_item != null:

View File

@ -1,3 +1,4 @@
tool
extends Panel
var current_tab = -1
@ -28,6 +29,7 @@ func _ready():
new_material()
func create_menu(menu, menu_name):
menu.clear()
menu.connect("id_pressed", self, "_on_PopupMenu_id_pressed")
for i in MENU.size():
if MENU[i].menu != menu_name:
@ -110,8 +112,11 @@ func export_material():
graph_edit.export_textures(2048)
func quit():
get_tree().quit()
if Engine.editor_hint:
get_parent().hide()
get_parent().queue_free()
else:
get_tree().quit()
func add_to_user_library():
var graph_edit = $VBoxContainer/HBoxContainer/Projects.get_current_tab_control()

View File

@ -72,7 +72,7 @@ group = null
text = "File"
flat = true
align = 1
items = [ ]
items = [ "New material", null, 0, false, false, 0, 0, null, "", false, "Load material", null, 0, false, false, 1, 268435535, null, "", false, "", null, 0, false, false, -1, 0, null, "", true, "Save material", null, 0, false, false, 3, 268435539, null, "", false, "Save material as...", null, 0, false, false, 4, 301989971, null, "", false, "Save all materials...", null, 0, false, false, 5, 0, null, "", false, "", null, 0, false, false, -1, 0, null, "", true, "Export material", null, 0, false, false, 7, 268435525, null, "", false, "", null, 0, false, false, -1, 0, null, "", true, "Close material", null, 0, false, false, 9, 0, null, "", false, "Quit", null, 0, false, false, 10, 268435537, null, "", false ]
[node name="Edit" type="MenuButton" parent="VBoxContainer/Menu" index="1"]
@ -122,7 +122,7 @@ group = null
text = "Tools"
flat = true
align = 1
items = [ ]
items = [ "Add selected node to user library", null, 0, false, false, 11, 0, null, "", false, "Save user library", null, 0, false, false, 12, 0, null, "", false ]
[node name="Help" type="MenuButton" parent="VBoxContainer/Menu" index="3"]
@ -147,7 +147,7 @@ group = null
text = "Help"
flat = true
align = 1
items = [ ]
items = [ "Report a bug", null, 0, false, false, 13, 0, null, "", false, "", null, 0, false, false, -1, 0, null, "", true, "About", null, 0, false, false, 15, 0, null, "", false ]
[node name="HBoxContainer" type="HSplitContainer" parent="VBoxContainer" index="1"]
@ -246,4 +246,8 @@ _sections_unfolded = [ "Size Flags" ]
[connection signal="tab_selected" from="VBoxContainer/HBoxContainer/Projects" to="." method="_on_Projects_tab_changed"]
[connection signal="connection_request" from="VBoxContainer/HBoxContainer/Projects/GraphEdit" to="VBoxContainer/HBoxContainer/Projects/GraphEdit" method="connect_node"]
[connection signal="disconnection_request" from="VBoxContainer/HBoxContainer/Projects/GraphEdit" to="VBoxContainer/HBoxContainer/Projects/GraphEdit" method="disconnect_node"]

View File

@ -0,0 +1,270 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="210mm"
height="297mm"
viewBox="0 0 744.09448819 1052.3622047"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="icons.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.35"
inkscape:cx="-1174.504"
inkscape:cy="21.101772"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1920"
inkscape:window-height="1017"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Calque 1"
inkscape:groupmode="layer"
id="layer1">
<g
id="g4171"
inkscape:export-filename="paint.png"
inkscape:export-xdpi="10.23"
inkscape:export-ydpi="10.23">
<rect
ry="80"
y="-107.63779"
x="-1148.5714"
height="542.85712"
width="542.85712"
id="rect4136"
style="opacity:0.98999999;fill:#787878;fill-opacity:1;stroke:none;stroke-width:3.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.78025477" />
<path
sodipodi:nodetypes="ccccccc"
inkscape:connector-curvature="0"
id="path4149"
d="m -870.75149,203.83407 270.72088,-219.203106 -15.15229,-57.578695 -42.42641,-30.304579 -41.41625,-2.0203 -214.15234,265.67012 z"
style="fill:#0500ad;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1" />
<path
sodipodi:nodetypes="cssszc"
inkscape:connector-curvature="0"
id="path4138"
d="m -1091.9749,410.91533 c 14.3152,-81.6581 -13.0914,-120.15625 49.4975,-208.09142 32.8188,-46.10933 122.86561,-57.50049 155.31642,-27.01118 29.43616,27.6569 9.19363,101.31963 -11.87479,123.98582 -42.31904,45.5284 -83.39182,14.78704 -128.28943,43.43656 -44.8975,28.64951 -64.6497,67.68022 -64.6497,67.68022 z"
style="fill:#3b3b3b;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="zcscsz"
inkscape:connector-curvature="0"
id="path4140"
d="m -1054.3328,210.71275 c -40.6516,35.10051 -23.8771,121.67969 -37.6426,200.20195 0,0 19.7529,-39.03017 64.6504,-67.67968 38.06432,-24.28914 77.41961,0.16299 113.07577,-21.4176 19.08717,-18.91014 1.61734,-64.34589 -17.11103,-89.6995 -27.69006,-37.48554 -82.32094,-56.50568 -122.97254,-21.40517 z"
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0"
id="path4145"
d="m -918.22867,162.41781 c 5.05077,-3.03046 65.65991,-79.802048 65.65991,-79.802048 39.85558,7.631084 47.84972,17.851418 63.63962,57.578688 l -83.84266,67.68022 c -3.3998,-22.12992 -28.89589,-33.85589 -45.45687,-45.45686 z"
style="fill:#bcbcbc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<rect
style="opacity:0.98999999;fill:none;fill-opacity:1;stroke:#000000;stroke-width:20;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4147"
width="542.85712"
height="542.85712"
x="-1148.5714"
y="-107.63779"
ry="80" />
</g>
<g
id="g4179"
inkscape:export-filename="line.png"
inkscape:export-xdpi="10.23"
inkscape:export-ydpi="10.23">
<rect
style="opacity:0.98999999;fill:#787878;fill-opacity:1;stroke:none;stroke-width:3.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.78025477"
id="rect4151"
width="542.85712"
height="542.85712"
x="-1151.9188"
y="536.92365"
ry="80" />
<rect
ry="80"
y="536.92365"
x="-1151.9188"
height="542.85712"
width="542.85712"
id="rect4161"
style="opacity:0.98999999;fill:none;fill-opacity:1;stroke:#000000;stroke-width:20;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path4163"
d="M -1065.0895,1003.8545 -697.29497,653.54057"
style="fill:none;fill-rule:evenodd;stroke:#ff0000;stroke-width:40;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
<g
id="g4184"
inkscape:export-filename="line_strip.png"
inkscape:export-xdpi="10.23"
inkscape:export-ydpi="10.23">
<g
id="g4189">
<rect
style="opacity:0.98999999;fill:#787878;fill-opacity:1;stroke:none;stroke-width:3.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.78025477"
id="rect4165"
width="542.85712"
height="542.85712"
x="-1156.2046"
y="1201.2094"
ry="80" />
<rect
ry="80"
y="1201.2094"
x="-1156.2046"
height="542.85712"
width="542.85712"
id="rect4167"
style="opacity:0.98999999;fill:none;fill-opacity:1;stroke:#000000;stroke-width:20;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccccc"
inkscape:connector-curvature="0"
id="path4169"
d="m -1069.3752,1668.1402 36.3686,-351.7205 270.17762,336.4487 77.46155,-344.0815 -290.49896,284.7537"
style="fill:none;fill-rule:evenodd;stroke:#ff0000;stroke-width:40;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
</g>
<g
id="g4282"
inkscape:export-filename="paint_s.png"
inkscape:export-xdpi="10"
inkscape:export-ydpi="10">
<rect
style="opacity:0.98999999;fill:#d8d8d8;fill-opacity:1;stroke:#b3b3b3;stroke-width:3.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4196"
width="542.85712"
height="542.85712"
x="-362.85712"
y="-139.06636"
ry="80" />
<path
style="fill:#0500ad;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -85.0372,172.4055 270.72088,-219.203107 -15.15229,-57.578693 -42.42641,-30.30458 -41.41625,-2.0203 -214.15234,265.67012 z"
id="path4198"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccc" />
<path
style="fill:#3b3b3b;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -306.26061,379.48676 c 14.3152,-81.6581 -13.0914,-120.15625 49.4975,-208.09142 32.8188,-46.10933 122.86561,-57.50049 155.31642,-27.01118 29.43616,27.6569 9.19363,101.31963 -11.87479,123.98582 -42.31904,45.5284 -83.39182,14.78704 -128.28943,43.43656 -44.8975,28.64951 -64.6497,67.68022 -64.6497,67.68022 z"
id="path4200"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cssszc" />
<path
style="fill:#ff0000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -268.61851,179.28418 c -40.6516,35.10051 -23.8771,121.67969 -37.6426,200.20195 0,0 19.7529,-39.03017 64.6504,-67.67968 38.06432,-24.28914 77.41961,0.16299 113.07577,-21.4176 19.08717,-18.91014 1.61734,-64.34589 -17.11103,-89.6995 -27.69006,-37.48554 -82.32094,-56.50568 -122.97254,-21.40517 z"
id="path4202"
inkscape:connector-curvature="0"
sodipodi:nodetypes="zcscsz" />
<path
style="fill:#bcbcbc;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -132.51438,130.98924 c 5.05077,-3.03046 65.65991,-79.802049 65.65991,-79.802049 39.85558,7.631084 47.84972,17.851418 63.63962,57.578689 l -83.84266,67.68022 c -3.3998,-22.12992 -28.89589,-33.85589 -45.45687,-45.45686 z"
id="path4204"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
<rect
ry="80"
y="-139.06636"
x="-362.85712"
height="542.85712"
width="542.85712"
id="rect4206"
style="opacity:0.98999999;fill:none;fill-opacity:1;stroke:#000000;stroke-width:20;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
<g
id="g4277"
inkscape:export-filename="line_s.png"
inkscape:export-xdpi="10"
inkscape:export-ydpi="10">
<rect
ry="80"
y="505.49509"
x="-366.20453"
height="542.85712"
width="542.85712"
id="rect4210"
style="opacity:0.98999999;fill:#d8d8d8;fill-opacity:1;stroke:#b3b3b3;stroke-width:3.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
inkscape:export-filename="line_s.png"
inkscape:export-xdpi="10"
inkscape:export-ydpi="10" />
<rect
style="opacity:0.98999999;fill:none;fill-opacity:1;stroke:#000000;stroke-width:20;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4212"
width="542.85712"
height="542.85712"
x="-366.20453"
y="505.49509"
ry="80" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ff0000;stroke-width:40;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M -279.37521,972.42593 88.41932,622.112"
id="path4214"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
</g>
<g
id="g4271"
inkscape:export-filename="line_strip_s.png"
inkscape:export-xdpi="10"
inkscape:export-ydpi="10">
<g
transform="translate(785.71429,-31.428571)"
id="g4218">
<rect
ry="80"
y="1201.2094"
x="-1156.2046"
height="542.85712"
width="542.85712"
id="rect4220"
style="opacity:0.98999999;fill:#d8d8d8;fill-opacity:1;stroke:#b3b3b3;stroke-width:3.9000001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<rect
style="opacity:0.98999999;fill:none;fill-opacity:1;stroke:#000000;stroke-width:20;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="rect4222"
width="542.85712"
height="542.85712"
x="-1156.2046"
y="1201.2094"
ry="80" />
<path
style="fill:none;fill-rule:evenodd;stroke:#ff0000;stroke-width:40;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m -1069.3752,1668.1402 36.3686,-351.7205 270.17762,336.4487 77.46155,-344.0815 -290.49896,284.7537"
id="path4224"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 762 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1008 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 463 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 754 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 352 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 805 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 450 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

View File

@ -0,0 +1,287 @@
tool
extends ViewportContainer
const MODE_FREE = 0
const MODE_LINE = 1
const MODE_LINE_STRIP = 2
var mode = MODE_FREE
var brush_size = 50.0
var brush_strength = 0.5
var texture_albedo = null
var texture_mr = null
var texture_normal = null
var texture_scale = 2.0
var previous_position = null
var painting = false
var next_paint_to = null
var object_name = null
onready var albedo_viewport = $AlbedoPaint/Viewport
onready var mr_viewport = $MRPaint/Viewport
onready var normal_viewport = $NormalPaint/Viewport
onready var albedo_material = $AlbedoPaint/Viewport/ColorRect.get_material()
onready var mr_material = $MRPaint/Viewport/ColorRect.get_material()
onready var normal_material = $NormalPaint/Viewport/ColorRect.get_material()
onready var brush_material = $Brush.get_material()
const MATERIAL_OPTIONS = [ "none", "bricks", "metal_pattern", "rusted_metal", "wooden_floor" ]
signal update_material
func _ready():
# add View2Texture as input of Texture2View (to ignore non-visible parts of the mesh)
$Texture2View/Viewport/PaintedMesh.get_surface_material(0).set_shader_param("view2texture", $View2Texture/Viewport.get_texture())
# Add Texture2View as input to all painted textures
$FixSeams/Viewport.get_texture().flags |= Texture.FLAG_FILTER
albedo_material.set_shader_param("tex2view_tex", $FixSeams/Viewport.get_texture())
mr_material.set_shader_param("tex2view_tex", $FixSeams/Viewport.get_texture())
normal_material.set_shader_param("tex2view_tex", $FixSeams/Viewport.get_texture())
# Add all painted textures as input to themselves
albedo_material.set_shader_param("self_tex", albedo_viewport.get_texture())
mr_material.set_shader_param("self_tex", mr_viewport.get_texture())
normal_material.set_shader_param("self_tex", normal_viewport.get_texture())
# Assign all textures to painted mesh
albedo_viewport.get_texture().flags |= Texture.FLAG_FILTER
$Viewport/PaintedMesh.get_surface_material(0).albedo_texture = albedo_viewport.get_texture()
mr_viewport.get_texture().flags |= Texture.FLAG_FILTER
$Viewport/PaintedMesh.get_surface_material(0).metallic_texture = mr_viewport.get_texture()
$Viewport/PaintedMesh.get_surface_material(0).roughness_texture = mr_viewport.get_texture()
normal_viewport.get_texture().flags |= Texture.FLAG_FILTER
$Viewport/PaintedMesh.get_surface_material(0).normal_texture = normal_viewport.get_texture()
# Updated Texture2View wrt current camera position
update_tex2view()
# Set size of painted textures
set_texture_size(2048)
# update the material list
$Material/OptionButton.clear()
for m in MATERIAL_OPTIONS:
$Material/OptionButton.add_item(m)
select_material(0)
# Initialize brush related parameters in paint shaders
update_brush_parameters()
func set_mesh(n, m):
object_name = n
var mat
mat = $Viewport/PaintedMesh.get_surface_material(0)
$Viewport/PaintedMesh.mesh = m
$Viewport/PaintedMesh.set_surface_material(0, mat)
mat = $Texture2View/Viewport/PaintedMesh.get_surface_material(0)
$Texture2View/Viewport/PaintedMesh.mesh = m
$Texture2View/Viewport/PaintedMesh.set_surface_material(0, mat)
mat = $View2Texture/Viewport/PaintedMesh.get_surface_material(0)
$View2Texture/Viewport/PaintedMesh.mesh = m
$View2Texture/Viewport/PaintedMesh.set_surface_material(0, mat)
update_tex2view()
save()
func set_mode(m):
mode = m
for i in $Tools.get_child_count():
$Tools.get_child(i).pressed = (i == m)
func set_texture_size(s):
$Texture2View/Viewport.size = Vector2(s, s)
$FixSeams/Viewport.size = Vector2(s, s)
$FixSeams/Viewport/TextureRect1.rect_size = Vector2(s, s)
$FixSeams/Viewport/TextureRect2.rect_size = Vector2(s, s)
$FixSeams/Viewport/TextureRect3.rect_size = Vector2(s, s)
$FixSeams/Viewport/TextureRect4.rect_size = Vector2(s, s)
$FixSeams/Viewport/TextureRect5.rect_size = Vector2(s, s)
$AlbedoPaint/Viewport.size = Vector2(s, s)
$AlbedoPaint/Viewport/ColorRect.rect_size = Vector2(s, s)
$MRPaint/Viewport.size = Vector2(s, s)
$MRPaint/Viewport/ColorRect.rect_size = Vector2(s, s)
func _on_Test_gui_input(ev):
if ev is InputEventWithModifiers:
if ev.control:
$Texture.show()
else:
$Texture.hide()
if ev is InputEventMouseMotion:
show_brush(ev.position, previous_position)
if ev.button_mask & BUTTON_MASK_RIGHT != 0:
$Viewport/CameraStand.rotate_y(-0.01*ev.relative.x)
$Viewport/CameraStand.rotate_x(-0.01*ev.relative.y)
if ev.button_mask & BUTTON_MASK_LEFT != 0:
if ev.control:
previous_position = null
texture_scale += ev.relative.x*0.1
texture_scale = clamp(texture_scale, 0.01, 20.0)
elif ev.shift:
previous_position = null
brush_size += ev.relative.x*0.1
brush_size = clamp(brush_size, 0.0, 250.0)
brush_strength += ev.relative.y*0.01
brush_strength = clamp(brush_strength, 0.0, 0.999)
update_brush_parameters()
elif mode == MODE_FREE:
paint(ev.position)
elif mode != MODE_LINE_STRIP:
previous_position = null
elif ev is InputEventMouseButton and !ev.shift:
var pos = ev.position
if ev.pressed:
var zoom = 0.0
if ev.button_index == BUTTON_WHEEL_UP:
zoom += 0.1
$Viewport/CameraStand/Camera.translate(Vector3(0.0, 0.0, zoom))
update_tex2view()
elif ev.button_index == BUTTON_WHEEL_DOWN:
zoom -= 0.1
$Viewport/CameraStand/Camera.translate(Vector3(0.0, 0.0, zoom))
update_tex2view()
elif ev.button_index == BUTTON_LEFT:
if mode == MODE_LINE_STRIP && previous_position != null:
paint(pos)
if ev.doubleclick:
pos = null
previous_position = pos
else:
if ev.button_index == BUTTON_RIGHT:
update_tex2view()
elif ev.button_index == BUTTON_LEFT:
if mode != MODE_LINE_STRIP:
paint(pos)
previous_position = null
func show_brush(p, op = null):
if op == null:
op = p
var position = p/rect_size
var old_position = op/rect_size
brush_material.set_shader_param("brush_pos", position)
brush_material.set_shader_param("brush_ppos", old_position)
func update_brush_parameters():
var brush_size_vector = Vector2(brush_size, brush_size)/rect_size
if brush_material != null:
brush_material.set_shader_param("brush_size", Vector2(brush_size, brush_size)/rect_size)
brush_material.set_shader_param("brush_strength", brush_strength)
if albedo_material != null:
albedo_material.set_shader_param("brush_size", brush_size_vector)
albedo_material.set_shader_param("brush_strength", brush_strength)
if mr_material != null:
mr_material.set_shader_param("brush_size", brush_size_vector)
mr_material.set_shader_param("brush_strength", brush_strength)
if normal_material != null:
normal_material.set_shader_param("brush_size", brush_size_vector)
normal_material.set_shader_param("brush_strength", brush_strength)
func paint(p):
if painting:
# if not available for painting, record a paint order
next_paint_to = p
return
painting = true
if previous_position == null:
previous_position = p
var position = p/rect_size
var prev_position = previous_position/rect_size
albedo_material.set_shader_param("brush_pos", position)
albedo_material.set_shader_param("brush_ppos", prev_position)
albedo_material.set_shader_param("brush_color", $Material/AlbedoColor.color)
albedo_viewport.render_target_update_mode = Viewport.UPDATE_ONCE
albedo_viewport.update_worlds()
mr_material.set_shader_param("brush_pos", position)
mr_material.set_shader_param("brush_ppos", prev_position)
mr_material.set_shader_param("brush_color", $Material/MRColor.color)
mr_viewport.render_target_update_mode = Viewport.UPDATE_ONCE
mr_viewport.update_worlds()
normal_material.set_shader_param("brush_pos", position)
normal_material.set_shader_param("brush_ppos", prev_position)
normal_viewport.render_target_update_mode = Viewport.UPDATE_ONCE
normal_viewport.update_worlds()
previous_position = p
yield(get_tree(), "idle_frame")
yield(get_tree(), "idle_frame")
painting = false
# execute recorded paint order if any
if next_paint_to != null:
p = next_paint_to
next_paint_to = null
paint(p)
func update_tex2view():
var camera = $Viewport/CameraStand/Camera
var transform = camera.global_transform.affine_inverse()*$Viewport/PaintedMesh.global_transform
# View to texture
$View2Texture/Viewport.size = $Viewport.size
$View2Texture/Viewport/Camera.transform = camera.global_transform
$View2Texture/Viewport.render_target_update_mode = Viewport.UPDATE_ALWAYS
$View2Texture/Viewport.update_worlds()
yield(get_tree(), "idle_frame")
yield(get_tree(), "idle_frame")
yield(get_tree(), "idle_frame")
var t2v_shader_material = $Texture2View/Viewport/PaintedMesh.get_surface_material(0)
t2v_shader_material.set_shader_param("model_transform", transform)
t2v_shader_material.set_shader_param("fovy_degrees", camera.fov)
t2v_shader_material.set_shader_param("z_near", camera.near)
t2v_shader_material.set_shader_param("z_far", camera.far)
t2v_shader_material.set_shader_param("aspect", rect_size.x/rect_size.y)
$Texture2View/Viewport.render_target_update_mode = Viewport.UPDATE_ALWAYS
$Texture2View/Viewport.update_worlds()
yield(get_tree(), "idle_frame")
yield(get_tree(), "idle_frame")
yield(get_tree(), "idle_frame")
$Texture2View/Viewport.render_target_update_mode = Viewport.UPDATE_DISABLED
$FixSeams/Viewport.render_target_update_mode = Viewport.UPDATE_ALWAYS
$FixSeams/Viewport.update_worlds()
yield(get_tree(), "idle_frame")
yield(get_tree(), "idle_frame")
yield(get_tree(), "idle_frame")
$FixSeams/Viewport.render_target_update_mode = Viewport.UPDATE_DISABLED
func load_material():
var dialog = FileDialog.new()
add_child(dialog)
dialog.rect_min_size = Vector2(500, 500)
dialog.access = FileDialog.ACCESS_FILESYSTEM
dialog.mode = FileDialog.MODE_OPEN_FILE
dialog.add_filter("*.paintmat;Paint material")
dialog.connect("file_selected", self, "do_load_material")
dialog.popup_centered()
func do_load_material(filename):
pass
func select_material(id):
var m = $Material/OptionButton.get_item_text(id)
if m == "none":
texture_albedo = null
texture_mr = null
texture_normal = null
else:
texture_albedo = load("res://addons/procedural_material/paint_tool/materials/%s_albedo.png" % m)
texture_mr = load("res://addons/procedural_material/paint_tool/materials/%s_mr.png" % m)
texture_normal = load("res://addons/procedural_material/paint_tool/materials/%s_normal_map.png" % m)
albedo_material.set_shader_param("brush_texture", texture_albedo)
mr_material.set_shader_param("brush_texture", texture_mr)
normal_material.set_shader_param("brush_texture", texture_normal)
func _on_resized():
update_brush_parameters()
func dump_viewport(viewport, filename):
var viewport_texture = viewport.get_texture()
var viewport_image = viewport_texture.get_data()
viewport_image.save_png(filename)
func debug():
dump_viewport($View2Texture/Viewport, "view2texture.png")
dump_viewport($Texture2View/Viewport, "texture2view.png")
dump_viewport($FixSeams/Viewport, "seamsfixed.png")
func save():
var mat = $Viewport/PaintedMesh.get_surface_material(0).duplicate()
dump_viewport($AlbedoPaint/Viewport, object_name+"_albedo.png")
dump_viewport($MRPaint/Viewport, object_name+"_mr.png")
dump_viewport($NormalPaint/Viewport, object_name+"_nm.png")
emit_signal("update_material", { material=mat, albedo=object_name+"_albedo.png", mr=object_name+"_mr.png", nm=object_name+"_nm.png" })

View File

@ -0,0 +1,27 @@
shader_type canvas_item;
uniform sampler2D self_tex;
uniform sampler2D tex2view_tex;
uniform sampler2D brush_texture : hint_white;
uniform vec2 brush_pos = vec2(0.5, 0.5);
uniform vec2 brush_ppos = vec2(0.5, 0.5);
uniform vec2 brush_size = vec2(0.25, 0.25);
uniform float brush_strength = 1.0;
uniform vec4 brush_color = vec4(1.0, 0.0, 0.0, 1.0);
float brush(float v) {
return clamp(v / (1.0-brush_strength), 0.0, 1.0);
}
void fragment() {
vec4 t2v = texture(tex2view_tex, UV);
vec2 xy = t2v.xy;
vec2 b = brush_pos/brush_size;
vec2 bv = (brush_ppos-brush_pos)/brush_size;
vec2 p = xy/brush_size;
float x = clamp(dot(p-b, bv)/dot(bv, bv), 0.0, 1.0);
float a = 1.0-length(p-(b+x*bv));
a = brush(max(0.0, a))*brush_color.w*t2v.z;
vec4 color = brush_color*texture(brush_texture, 2.0*vec2(brush_size.y/brush_size.x, 1.0)*xy);
COLOR = vec4(mix(texture(self_tex, UV).xyz, color.xyz, a), 1.0);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,28 @@
shader_type canvas_item;
uniform sampler2D self_tex;
uniform sampler2D tex2view_tex;
uniform sampler2D brush_texture : hint_normal;
uniform vec2 brush_pos = vec2(0.5, 0.5);
uniform vec2 brush_ppos = vec2(0.5, 0.5);
uniform vec2 brush_size = vec2(0.25, 0.25);
uniform float brush_strength = 1.0;
float brush(float v) {
return clamp(v / (1.0-brush_strength), 0.0, 1.0);
}
void fragment() {
vec4 t2v = textureLod(tex2view_tex, UV, 0.0);
vec2 xy = t2v.xy;
vec2 b = brush_pos/brush_size;
vec2 bv = (brush_ppos-brush_pos)/brush_size;
vec2 p = xy/brush_size;
float x = clamp(dot(p-b, bv)/dot(bv, bv), 0.0, 1.0);
float a = 1.0-length(p-(b+x*bv));
a = brush(max(0.0, a))*t2v.z;
vec3 old = texture(self_tex, UV).xyz;
vec3 new = texture(brush_texture, 2.0*vec2(brush_size.y/brush_size.x, 1.0)*xy).xyz;
vec3 color = normalize(mix(old, new, a)-vec3(0.5));
COLOR = vec4(0.5*color+0.5, 1.0);
}

View File

@ -0,0 +1,8 @@
tool
extends WindowDialog
func _ready():
pass
func set_object(o):
$PaintTool.set_mesh(o.name, o.mesh)

View File

@ -0,0 +1,28 @@
[gd_scene load_steps=3 format=2]
[ext_resource path="res://addons/procedural_material/paint_tool/paint_window.gd" type="Script" id=1]
[ext_resource path="res://addons/procedural_material/paint_tool/paint.tscn" type="PackedScene" id=2]
[node name="PaintWindow" type="WindowDialog" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_right = 1277.0
margin_bottom = 721.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
popup_exclusive = true
window_title = "Material Spray"
resizable = true
script = ExtResource( 1 )
_sections_unfolded = [ "Popup" ]
[node name="PaintTool" parent="." index="1" instance=ExtResource( 2 )]

View File

@ -0,0 +1,29 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://addons/procedural_material/paint_tool/icons/paint.png" type="Texture" id=1]
[node name="TextureButton" type="TextureButton"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_right = 24.0
margin_bottom = 24.0
rect_min_size = Vector2( 24, 24 )
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
focus_mode = 2
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
toggle_mode = false
enabled_focus_mode = 2
shortcut = null
group = null
texture_normal = ExtResource( 1 )
expand = true
_sections_unfolded = [ "Rect", "Textures" ]

View File

@ -0,0 +1,6 @@
shader_type spatial;
render_mode unshaded;
void fragment() {
ALBEDO = vec3(UV, 0.0);
}

View File

@ -0,0 +1,21 @@
shader_type canvas_item;
uniform sampler2D brush_texture : hint_albedo;
uniform vec2 brush_pos = vec2(0.5, 0.5);
uniform vec2 brush_ppos = vec2(0.5, 0.5);
uniform vec2 brush_size = vec2(0.25, 0.25);
uniform float brush_strength = 0.5;
float brush(float v) {
return clamp(v / (1.0-brush_strength), 0.0, 1.0);
}
void fragment() {
vec2 b = brush_pos/brush_size;
vec2 bv = (brush_ppos-brush_pos)/brush_size;
vec2 p = UV/brush_size;
float x = clamp(dot(p-b, bv)/dot(bv, bv), 0.0, 1.0);
float a = 1.0-length(p-(b+x*bv));
a = brush(max(0.0, a));
COLOR = vec4(vec3(1.0), 0.5*a);
}

View File

@ -0,0 +1,61 @@
shader_type spatial;
render_mode unshaded, cull_front;
uniform sampler2D view2texture;
uniform mat4 model_transform;
uniform float fovy_degrees = 45;
uniform float z_near = 0.01;
uniform float z_far = 60.0;
uniform float aspect = 1.0;
varying vec4 global_position;
varying vec3 normal;
mat4 get_projection_matrix() {
float PI = 3.14159265359;
float rads = fovy_degrees / 2.0 * PI / 180.0;
float deltaZ = z_far - z_near;
float sine = sin(rads);
if (deltaZ == 0.0 || sine == 0.0 || aspect == 0.0)
return mat4(0.0);
float cotangent = cos(rads) / sine;
mat4 matrix = mat4(1.0);
matrix[0][0] = cotangent / aspect;
matrix[1][1] = cotangent;
matrix[2][2] = (z_far + z_near) / deltaZ;
matrix[2][3] = 1.0; //try +1
matrix[3][2] = 2.0 * z_near * z_far / deltaZ;
matrix[3][3] = 0.0;
return matrix;
}
void vertex() {
global_position = model_transform*vec4(VERTEX, 1.0);
normal = (model_transform*vec4(NORMAL, 0.0)).xyz;
VERTEX=vec3(UV.x, UV.y, 0.0);
COLOR=vec4(1.0);
}
vec2 fix_unshaded(vec2 xy) {
return 0.9999857*pow(xy, vec2(2.223058));
}
void fragment() {
vec4 color = get_projection_matrix()*vec4(global_position.xyz, 1.0);
color.xyz /= color.w;
vec3 xyz = vec3(0.5-0.5*color.x, 0.5+0.5*color.y, -0.5*color.z);
vec4 v2t = textureLod(view2texture, xyz.xy, 0.0);
vec2 delta = v2t.xy-UV.xy;
float visible = 0.0;
if (color.x > -1.0 && color.x < 1.0 && color.y > -1.0 && color.y < 1.0) {
visible = clamp(10.0*dot(normalize(normal), normalize(color.xyz)), 0.0, 1.0)*max(0.0, 1.0-4.0*pow(dot(delta, delta), 0.3));
}
ALBEDO = vec3(fix_unshaded(xyz.xy), visible);
}

View File

@ -0,0 +1,21 @@
shader_type spatial;
render_mode unshaded;
/*
0 0
0.025 0.173
0.05 0.247
0.1 0.349
0.2 0.486
0.3 0.584
0.4 0.663
0.5 0.733
1 1
*/
vec3 fix_unshaded(vec3 xy) {
return 0.9999857*pow(xy, vec3(2.223058));
}
void fragment() {
ALBEDO = fix_unshaded(vec3(UV, VERTEX.z));
}

View File

@ -1,20 +1,96 @@
tool
extends EditorPlugin
var editor = null
var mm_button = null
var material_maker = null
var edited_object = null
var pt_button = null
var paint_tool = null
func _enter_tree():
editor = preload("res://addons/procedural_material/pm_editor.tscn").instance()
add_control_to_bottom_panel(editor, "ProceduralMaterial")
#material_maker = preload("res://addons/procedural_material/pm_material_maker.tscn").instance()
#add_control_to_bottom_panel(material_maker, "ProceduralMaterial")
print("Adding menu item")
mm_button = Button.new()
mm_button.connect("pressed", self, "open_material_maker")
mm_button.text = "Material Maker"
add_control_to_container(CONTAINER_TOOLBAR, mm_button)
print("done")
func _exit_tree():
remove_control_from_bottom_panel(editor)
editor.queue_free()
editor = null
#remove_control_from_bottom_panel(material_maker)
if mm_button != null:
remove_control_from_container(CONTAINER_TOOLBAR, mm_button)
mm_button.queue_free()
if pt_button != null:
remove_control_from_container(CONTAINER_SPATIAL_EDITOR_MENU, pt_button)
pt_button.queue_free()
pt_button = null
if material_maker != null:
material_maker.hide()
material_maker.queue_free()
material_maker = null
if paint_tool != null:
paint_tool.hide()
paint_tool.queue_free()
paint_tool = null
func _get_state():
var s = {}
var s = { mm_button=mm_button, material_maker=material_maker }
return s
func _set_state(s):
pass
mm_button = s.mm_button
material_maker = s.material_maker
func open_material_maker():
material_maker = load("res://addons/procedural_material/window_dialog.tscn").instance()
add_child(material_maker)
material_maker.popup_centered()
func handles(object):
return object is MeshInstance
func edit(object):
edited_object = object
func make_visible(b):
if b:
pt_button = preload("res://addons/procedural_material/paint_tool/pt_button.tscn").instance()
pt_button.connect("pressed", self, "paint")
add_control_to_container(CONTAINER_SPATIAL_EDITOR_MENU, pt_button)
else:
edited_object = null
remove_control_from_container(CONTAINER_SPATIAL_EDITOR_MENU, pt_button)
pt_button.queue_free()
pt_button = null
print(pt_button)
func paint():
paint_tool = preload("res://addons/procedural_material/paint_tool/paint_window.tscn").instance()
add_child(paint_tool)
paint_tool.set_object(edited_object)
paint_tool.connect("popup_hide", self, "free_paint_tool")
paint_tool.get_node("PaintTool").connect("update_material", self, "assign_material")
paint_tool.popup_centered()
func free_paint_tool():
paint_tool.queue_free()
paint_tool = null
func assign_material(m):
var texture
var editor_file_system = get_editor_interface().get_resource_filesystem()
editor_file_system.scan()
editor_file_system.update_file(m.albedo)
texture = load(m.albedo)
m.material.albedo_texture = texture
editor_file_system.update_file(m.mr)
texture = load(m.mr)
m.material.metallic_texture = texture
m.material.roughness_texture = texture
editor_file_system.update_file(m.nm)
texture = load(m.nm)
m.material.normal_texture = texture
edited_object.set_surface_material(0, m.material)

View File

@ -0,0 +1,26 @@
[gd_scene load_steps=2 format=2]
[ext_resource path="res://addons/procedural_material/main_window.tscn" type="PackedScene" id=1]
[node name="WindowDialog" type="WindowDialog" index="0"]
anchor_left = 0.0
anchor_top = 0.0
anchor_right = 0.0
anchor_bottom = 0.0
margin_right = 1124.0
margin_bottom = 619.0
rect_pivot_offset = Vector2( 0, 0 )
rect_clip_content = false
mouse_filter = 0
mouse_default_cursor_shape = 0
size_flags_horizontal = 1
size_flags_vertical = 1
popup_exclusive = true
window_title = "Material Maker"
resizable = true
_sections_unfolded = [ "Popup" ]
[node name="MainWindow" parent="." index="1" instance=ExtResource( 1 )]

BIN
test/suzanne.mesh Normal file

Binary file not shown.

244
test/test.tscn Normal file
View File

@ -0,0 +1,244 @@
[gd_scene load_steps=8 format=2]
[ext_resource path="res://test/suzanne.mesh" type="ArrayMesh" id=1]
[ext_resource path="res://addons/procedural_material/panoramas/park.hdr" type="Texture" id=2]
[sub_resource type="CubeMesh" id=1]
custom_aabb = AABB( 0, 0, 0, 0, 0, 0 )
size = Vector3( 2, 2, 2 )
subdivide_width = 0
subdivide_height = 0
subdivide_depth = 0
[sub_resource type="SpatialMaterial" id=2]
render_priority = 0
flags_transparent = false
flags_unshaded = false
flags_vertex_lighting = false
flags_no_depth_test = false
flags_use_point_size = false
flags_world_triplanar = false
flags_fixed_size = false
flags_albedo_tex_force_srgb = false
vertex_color_use_as_albedo = false
vertex_color_is_srgb = false
params_diffuse_mode = 0
params_specular_mode = 0
params_blend_mode = 0
params_cull_mode = 0
params_depth_draw_mode = 0
params_line_width = 1.0
params_point_size = 1.0
params_billboard_mode = 0
params_grow = false
params_use_alpha_scissor = false
albedo_color = Color( 1, 1, 1, 1 )
metallic = 1.0
metallic_specular = 0.5
metallic_texture_channel = 0
roughness = 1.0
roughness_texture_channel = 0
emission_enabled = false
normal_enabled = false
rim_enabled = false
clearcoat_enabled = false
anisotropy_enabled = false
ao_enabled = false
depth_enabled = false
subsurf_scatter_enabled = false
transmission_enabled = false
refraction_enabled = false
detail_enabled = false
uv1_scale = Vector3( 1, 1, 1 )
uv1_offset = Vector3( 0, 0, 0 )
uv1_triplanar = false
uv1_triplanar_sharpness = 1.0
uv2_scale = Vector3( 1, 1, 1 )
uv2_offset = Vector3( 0, 0, 0 )
uv2_triplanar = false
uv2_triplanar_sharpness = 1.0
proximity_fade_enable = false
distance_fade_enable = false
_sections_unfolded = [ "Albedo", "Detail" ]
[sub_resource type="PrismMesh" id=3]
custom_aabb = AABB( 0, 0, 0, 0, 0, 0 )
left_to_right = 0.5
size = Vector3( 2, 2, 2 )
subdivide_width = 0
subdivide_height = 0
subdivide_depth = 0
[sub_resource type="PanoramaSky" id=4]
radiance_size = 4
panorama = ExtResource( 2 )
[sub_resource type="Environment" id=5]
background_mode = 2
background_sky = SubResource( 4 )
background_sky_custom_fov = 0.0
background_color = Color( 0, 0, 0, 1 )
background_energy = 1.0
background_canvas_max_layer = 0
ambient_light_color = Color( 0, 0, 0, 1 )
ambient_light_energy = 1.0
ambient_light_sky_contribution = 1.0
fog_enabled = false
fog_color = Color( 0.5, 0.6, 0.7, 1 )
fog_sun_color = Color( 1, 0.9, 0.7, 1 )
fog_sun_amount = 0.0
fog_depth_enabled = true
fog_depth_begin = 10.0
fog_depth_curve = 1.0
fog_transmit_enabled = false
fog_transmit_curve = 1.0
fog_height_enabled = false
fog_height_min = 0.0
fog_height_max = 100.0
fog_height_curve = 1.0
tonemap_mode = 0
tonemap_exposure = 1.0
tonemap_white = 1.0
auto_exposure_enabled = false
auto_exposure_scale = 0.4
auto_exposure_min_luma = 0.05
auto_exposure_max_luma = 8.0
auto_exposure_speed = 0.5
ss_reflections_enabled = false
ss_reflections_max_steps = 64
ss_reflections_fade_in = 0.15
ss_reflections_fade_out = 2.0
ss_reflections_depth_tolerance = 0.2
ss_reflections_roughness = true
ssao_enabled = false
ssao_radius = 1.0
ssao_intensity = 1.0
ssao_radius2 = 0.0
ssao_intensity2 = 1.0
ssao_bias = 0.01
ssao_light_affect = 0.0
ssao_color = Color( 0, 0, 0, 1 )
ssao_quality = 0
ssao_blur = 3
ssao_edge_sharpness = 4.0
dof_blur_far_enabled = false
dof_blur_far_distance = 10.0
dof_blur_far_transition = 5.0
dof_blur_far_amount = 0.1
dof_blur_far_quality = 1
dof_blur_near_enabled = false
dof_blur_near_distance = 2.0
dof_blur_near_transition = 1.0
dof_blur_near_amount = 0.1
dof_blur_near_quality = 1
glow_enabled = false
glow_levels/1 = false
glow_levels/2 = false
glow_levels/3 = true
glow_levels/4 = false
glow_levels/5 = true
glow_levels/6 = false
glow_levels/7 = false
glow_intensity = 0.8
glow_strength = 1.0
glow_bloom = 0.19
glow_blend_mode = 2
glow_hdr_threshold = 1.0
glow_hdr_scale = 2.0
glow_bicubic_upscale = false
adjustment_enabled = false
adjustment_brightness = 1.0
adjustment_contrast = 1.0
adjustment_saturation = 1.0
_sections_unfolded = [ "Background" ]
[node name="Spatial" type="Spatial" index="0"]
[node name="Cube" type="MeshInstance" parent="." index="0"]
layers = 1
material_override = null
cast_shadow = 1
extra_cull_margin = 0.0
use_in_baked_light = false
lod_min_distance = 0.0
lod_min_hysteresis = 0.0
lod_max_distance = 0.0
lod_max_hysteresis = 0.0
mesh = SubResource( 1 )
skeleton = NodePath("..")
material/0 = SubResource( 2 )
_sections_unfolded = [ "material" ]
[node name="Suzanne" type="MeshInstance" parent="." index="1"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 4, 1, 0 )
layers = 1
material_override = null
cast_shadow = 1
extra_cull_margin = 0.0
use_in_baked_light = false
lod_min_distance = 0.0
lod_min_hysteresis = 0.0
lod_max_distance = 0.0
lod_max_hysteresis = 0.0
mesh = ExtResource( 1 )
skeleton = NodePath("..")
material/0 = null
_sections_unfolded = [ "material" ]
[node name="Prism" type="MeshInstance" parent="." index="2"]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, -4, 0, 0 )
layers = 1
material_override = null
cast_shadow = 1
extra_cull_margin = 0.0
use_in_baked_light = false
lod_min_distance = 0.0
lod_min_hysteresis = 0.0
lod_max_distance = 0.0
lod_max_hysteresis = 0.0
mesh = SubResource( 3 )
skeleton = NodePath("..")
material/0 = SubResource( 2 )
_sections_unfolded = [ "material" ]
[node name="WorldEnvironment" type="WorldEnvironment" parent="." index="3"]
environment = SubResource( 5 )
[node name="DirectionalLight" type="DirectionalLight" parent="." index="4"]
transform = Transform( 1, 0, 0, 0, -4.37114e-008, 1, 0, -1, -4.37114e-008, 0, 6, 0 )
layers = 1
light_color = Color( 1, 1, 1, 1 )
light_energy = 1.0
light_indirect_energy = 1.0
light_negative = false
light_specular = 0.5
light_bake_mode = 1
light_cull_mask = -1
shadow_enabled = false
shadow_color = Color( 0, 0, 0, 1 )
shadow_bias = 0.1
shadow_contact = 0.0
shadow_reverse_cull_face = false
editor_only = false
directional_shadow_mode = 2
directional_shadow_split_1 = 0.1
directional_shadow_split_2 = 0.2
directional_shadow_split_3 = 0.5
directional_shadow_blend_splits = false
directional_shadow_normal_bias = 0.8
directional_shadow_bias_split_scale = 0.25
directional_shadow_depth_range = 0
directional_shadow_max_distance = 200.0
_sections_unfolded = [ "Light" ]