mirror of
https://github.com/Relintai/material-maker.git
synced 2024-11-13 06:27:18 +01:00
2621ff4b46
Exporting a material will now create a SpatialMaterial. The Material graph node now generates different textures when used as a Godot addon (metallic, roughness and ambient occlusion are merged into a single texture). Rendering code (that was in graph_edit and node_base scenes) is now in a single "renderer scene" attached to the main window.
99 lines
3.4 KiB
GDScript
99 lines
3.4 KiB
GDScript
tool
|
|
extends Viewport
|
|
|
|
var render_queue = []
|
|
|
|
func _ready():
|
|
$ColorRect.material = $ColorRect.material.duplicate(true)
|
|
|
|
# Save shader to image, create image texture
|
|
|
|
static func generate_shader(src_code):
|
|
var code
|
|
code = "shader_type canvas_item;\n"
|
|
var file = File.new()
|
|
file.open("res://addons/material_maker/common.shader", File.READ)
|
|
code += file.get_as_text()
|
|
code += "\n"
|
|
var shader_code = src_code.defs
|
|
shader_code += "void fragment() {\n"
|
|
shader_code += src_code.code
|
|
shader_code += "COLOR = vec4("+src_code.rgb+", 1.0);\n"
|
|
shader_code += "}\n"
|
|
#print("GENERATED SHADER:\n"+shader_code)
|
|
code += shader_code
|
|
return code
|
|
|
|
static func generate_combined_shader(red_code, green_code, blue_code):
|
|
var code
|
|
code = "shader_type canvas_item;\n"
|
|
var file = File.new()
|
|
file.open("res://addons/material_maker/common.shader", File.READ)
|
|
code += file.get_as_text()
|
|
code += "\n"
|
|
var shader_code = ""
|
|
shader_code += red_code.defs
|
|
shader_code += green_code.defs
|
|
shader_code += blue_code.defs
|
|
shader_code += "void fragment() {\n"
|
|
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 += "}\n"
|
|
#print("GENERATED COMBINED SHADER:\n"+shader_code)
|
|
code += shader_code
|
|
return code
|
|
|
|
func setup_material(shader_material, textures, shader_code):
|
|
for k in textures.keys():
|
|
shader_material.set_shader_param(k+"_tex", textures[k])
|
|
shader_material.shader.code = shader_code
|
|
|
|
func render_shader_to_viewport(shader, textures, render_size, method, args):
|
|
render_queue.append( { shader=shader, textures=textures, size=render_size, method=method, args=args } )
|
|
if render_queue.size() == 1:
|
|
while !render_queue.empty():
|
|
var job = render_queue.front()
|
|
size = Vector2(job.size, job.size)
|
|
$ColorRect.rect_position = Vector2(0, 0)
|
|
$ColorRect.rect_size = Vector2(job.size, job.size)
|
|
var shader_material = $ColorRect.material
|
|
shader_material.shader.code = job.shader
|
|
if job.textures != null:
|
|
for k in job.textures.keys():
|
|
shader_material.set_shader_param(k+"_tex", job.textures[k])
|
|
render_target_update_mode = Viewport.UPDATE_ALWAYS
|
|
update_worlds()
|
|
yield(get_tree(), "idle_frame")
|
|
yield(get_tree(), "idle_frame")
|
|
render_target_update_mode = Viewport.UPDATE_DISABLED
|
|
callv(job.method, job.args)
|
|
render_queue.pop_front()
|
|
|
|
func render_to_viewport(node, render_size, method, args):
|
|
render_shader_to_viewport(node.generate_shader(), node.get_textures(), render_size, method, args)
|
|
|
|
func export_texture(node, filename, render_size = 256):
|
|
if node == null:
|
|
return null
|
|
render_to_viewport(node, render_size, "do_export_texture", [ filename ])
|
|
|
|
func do_export_texture(filename):
|
|
var viewport_texture = get_texture()
|
|
var viewport_image = viewport_texture.get_data()
|
|
viewport_image.save_png(filename)
|
|
|
|
func precalculate_node(node, render_size, target_texture, object, method, args):
|
|
if node == null:
|
|
return null
|
|
render_to_viewport(node, render_size, "do_precalculate_texture", [ object, method, args ])
|
|
|
|
func precalculate_shader(shader, textures, render_size, target_texture, object, method, args):
|
|
render_shader_to_viewport(shader, textures, render_size, "do_precalculate_texture", [ target_texture, object, method, args ])
|
|
|
|
func do_precalculate_texture(target_texture, object, method, args):
|
|
var viewport_texture = get_texture()
|
|
target_texture.create_from_image(viewport_texture.get_data())
|
|
object.callv(method, args)
|