material-maker/addons/material_maker/renderer.gd
RodZill4 bf4a125386 Node editor updates and support for alpha channel
Added initial support for alpha channel (in combine, decompose and blend nodes). Textures with alpha channels can be exported using the material node albedo input.
Updated node editor with a simple editor for enumerated parameters.
2018-10-26 22:44:47 +02:00

111 lines
3.7 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"
if src_code.has("globals"):
for g in src_code.globals:
code += g
var shader_code = src_code.defs
shader_code += "void fragment() {\n"
shader_code += src_code.code
shader_code += "COLOR = "+src_code.rgba+";\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"
if red_code.has("globals"):
for g in red_code.globals:
code += g
if green_code.has("globals"):
for g in green_code.globals:
code += g
if blue_code.has("globals"):
for g in blue_code.globals:
code += g
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_with_globals(), 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)