Added .tres file generation for Godot.

This commit is contained in:
RodZill4 2020-02-18 08:47:44 +01:00
parent c9aab3e831
commit 88340b5502
3 changed files with 190 additions and 31 deletions

View File

@ -6,12 +6,12 @@ var material : SpatialMaterial
var generated_textures = {} var generated_textures = {}
const TEXTURE_LIST = [ const TEXTURE_LIST = [
{ port=0, texture="albedo" }, { port=0, texture="albedo", sources=[0] },
{ port=1, texture="orm" }, { port=1, texture="orm", sources=[1, 2, 5] },
{ port=2, texture="emission" }, { port=2, texture="emission", sources=[3] },
{ port=3, texture="normal" }, { port=3, texture="normal", sources=[4] },
{ port=4, texture="depth" }, { port=4, texture="depth", sources=[6] },
{ port=5, texture="sss" } { port=5, texture="sss", sources=[7] }
] ]
const INPUT_ALBEDO : int = 0 const INPUT_ALBEDO : int = 0
@ -47,7 +47,7 @@ func get_type() -> String:
func get_type_name() -> String: func get_type_name() -> String:
return "Material" return "Material"
func get_output_defs__() -> Array: func get_output_defs() -> Array:
return [] return []
func get_image_size() -> int: func get_image_size() -> int:
@ -70,10 +70,9 @@ func set_parameter(p, v) -> void:
update_preview() update_preview()
func source_changed(input_index : int) -> void: func source_changed(input_index : int) -> void:
print("source_changed "+str(input_index))
for t in TEXTURE_LIST: for t in TEXTURE_LIST:
if t.has("port") and t.port == input_index: if t.has("sources") and t.sources.find(input_index) != -1:
generated_textures[t.texture] = null
elif t.has("ports") and t.ports.has(input_index):
generated_textures[t.texture] = null generated_textures[t.texture] = null
update_preview() update_preview()
@ -104,6 +103,7 @@ func render_textures() -> void:
generated_textures[t.texture] = texture generated_textures[t.texture] = texture
func update_materials(material_list) -> void: func update_materials(material_list) -> void:
render_textures()
for m in material_list: for m in material_list:
update_material(m) update_material(m)
@ -124,7 +124,7 @@ func update_material(m, file_prefix = null) -> void:
# Make the material double-sided for better visiblity in the preview # Make the material double-sided for better visiblity in the preview
m.params_cull_mode = SpatialMaterial.CULL_DISABLED m.params_cull_mode = SpatialMaterial.CULL_DISABLED
# Albedo # Albedo
m.albedo_color = parameters.albedo m.albedo_color = parameters.albedo_color
m.albedo_texture = get_generated_texture("albedo", file_prefix) m.albedo_texture = get_generated_texture("albedo", file_prefix)
# Ambient occlusion # Ambient occlusion
if get_source(INPUT_OCCLUSION) != null: if get_source(INPUT_OCCLUSION) != null:
@ -143,7 +143,7 @@ func update_material(m, file_prefix = null) -> void:
m.roughness_texture = null m.roughness_texture = null
# Metallic # Metallic
m.metallic = parameters.metallic m.metallic = parameters.metallic
if get_source(INPUT_ROUGHNESS) != null: if get_source(INPUT_METALLIC) != null:
m.metallic_texture = get_generated_texture("orm", file_prefix) m.metallic_texture = get_generated_texture("orm", file_prefix)
m.metallic_texture_channel = SpatialMaterial.TEXTURE_CHANNEL_BLUE m.metallic_texture_channel = SpatialMaterial.TEXTURE_CHANNEL_BLUE
else: else:
@ -151,7 +151,7 @@ func update_material(m, file_prefix = null) -> void:
# Emission # Emission
if get_source(INPUT_EMISSION) != null: if get_source(INPUT_EMISSION) != null:
m.emission_enabled = true m.emission_enabled = true
m.emission_energy = parameters.emission m.emission_energy = parameters.emission_energy
m.emission_texture = get_generated_texture("emission", file_prefix) m.emission_texture = get_generated_texture("emission", file_prefix)
else: else:
m.emission_enabled = false m.emission_enabled = false
@ -159,13 +159,14 @@ func update_material(m, file_prefix = null) -> void:
if get_source(INPUT_NORMAL) != null: if get_source(INPUT_NORMAL) != null:
m.normal_enabled = true m.normal_enabled = true
m.normal_texture = get_generated_texture("normal", file_prefix) m.normal_texture = get_generated_texture("normal", file_prefix)
m.normal_scale = parameters.normal
else: else:
m.normal_enabled = false m.normal_enabled = false
# Depth # Depth
if get_source(INPUT_DEPTH) != null and parameters.depth > 0: if get_source(INPUT_DEPTH) != null and parameters.depth > 0:
m.depth_enabled = true m.depth_enabled = true
m.depth_deep_parallax = true m.depth_deep_parallax = true
m.depth_scale = parameters.depth * 0.2 m.depth_scale = parameters.depth_scale * 0.2
m.depth_texture = get_generated_texture("depth", file_prefix) m.depth_texture = get_generated_texture("depth", file_prefix)
else: else:
m.depth_enabled = false m.depth_enabled = false
@ -200,17 +201,55 @@ func get_export_profiles() -> Array:
func get_export_extension(profile : String) -> String: func get_export_extension(profile : String) -> String:
return shader_model.exports[profile].export_extension return shader_model.exports[profile].export_extension
func subst_string(s : String, export_context : Dictionary) -> String:
for k in export_context.keys():
s = s.replace("$("+k+")", export_context[k])
for input_index in range(shader_model.inputs.size()):
var input = shader_model.inputs[input_index]
var is_input_connected = "true" if get_source(input_index) != null else "false"
s = s.replace("$(connected:"+input.name+")", is_input_connected)
return s
func create_file_from_template(template : String, file_name : String, export_context : Dictionary) -> bool:
var in_file = File.new()
var out_file = File.new()
if in_file.open(mm_loader.STD_GENDEF_PATH+"/"+template, File.READ) != OK:
if in_file.open(OS.get_executable_path().get_base_dir()+"/generators/"+template, File.READ) != OK:
print("Cannot find template file "+template)
return false
if out_file.open(file_name, File.WRITE):
print("Cannot write file '"+file_name+"'")
return false
var skip_state : Array = [ false ]
while ! in_file.eof_reached():
var l = in_file.get_line()
if l.left(4) == "$if ":
var condition = subst_string(l.right(4), export_context)
var expr = Expression.new()
var error = expr.parse(condition, [])
if error != OK:
print("Error in expression: "+expr.get_error_text())
continue
skip_state.push_back(!expr.execute())
elif l.left(3) == "$fi":
skip_state.pop_back()
elif l.left(5) == "$else":
skip_state.push_back(!skip_state.pop_back())
elif ! skip_state.back():
out_file.store_line(subst_string(l, export_context))
return true
func export_material(prefix, profile) -> void: func export_material(prefix, profile) -> void:
var export_context : Dictionary = {
path_prefix=prefix,
file_prefix=prefix.get_file()
}
for f in shader_model.exports[profile].files: for f in shader_model.exports[profile].files:
match f.type: match f.type:
"texture": "texture":
var file_name = f.file_name.replace("$(file_prefix)", prefix) var file_name = subst_string(f.file_name, export_context)
if f.has("conditions"): if f.has("conditions"):
var condition = f.conditions var condition = subst_string(f.conditions, export_context)
for input_index in range(shader_model.inputs.size()):
var input = shader_model.inputs[input_index]
var is_input_connected = "true" if get_source(input_index) != null else "false"
condition = condition.replace("$(connected:"+input.name+")", is_input_connected)
var expr = Expression.new() var expr = Expression.new()
var error = expr.parse(condition, []) var error = expr.parse(condition, [])
if error != OK: if error != OK:
@ -223,6 +262,9 @@ func export_material(prefix, profile) -> void:
result = yield(result, "completed") result = yield(result, "completed")
result.save_to_file(file_name) result.save_to_file(file_name)
result.release() result.release()
"template":
var file_name = f.file_name.replace("$(path_prefix)", prefix)
create_file_from_template(f.template, file_name, export_context)
func _serialize(data: Dictionary) -> Dictionary: func _serialize(data: Dictionary) -> Dictionary:
return data return data

View File

@ -0,0 +1,48 @@
[gd_resource type="SpatialMaterial" load_steps=5 format=2]
$if $(connected:albedo_tex)
[ext_resource path="$(file_prefix)_albedo.png" type="Texture" id=1]
$fi
$if $(connected:ao_tex) or $(connected:roughness_tex) or $(connected:metallic_tex)
[ext_resource path="$(file_prefix)_orm.png" type="Texture" id=2]
$fi
$if $(connected:normal_tex)
[ext_resource path="$(file_prefix)_normal.png" type="Texture" id=3]
$fi
$if $(connected:depth_tex)
[ext_resource path="$(file_prefix)_depth.png" type="Texture" id=4]
$fi
[resource]
$if $(connected:albedo_tex)
albedo_texture = ExtResource( 1 )
$fi
metallic = 1.0
$if $(connected:metallic_tex)
metallic_texture = ExtResource( 2 )
metallic_texture_channel = 2
$fi
$if $(connected:ao_tex) or $(connected:roughness_tex) or $(connected:metallic_tex)
roughness_texture = ExtResource( 2 )
roughness_texture_channel = 1
$fi
$if $(connected:normal_tex)
normal_enabled = true
normal_scale = 1.0
normal_texture = ExtResource( 3 )
$fi
$if $(connected:ao_tex)
ao_enabled = true
ao_light_affect = 0.0
ao_texture = ExtResource( 2 )
ao_on_uv2 = false
ao_texture_channel = 0
$fi
$if $(connected:depth_tex)
depth_enabled = true
depth_scale = 0.05
depth_deep_parallax = false
depth_flip_tangent = false
depth_flip_binormal = false
depth_texture = ExtResource( 4 )
$fi

View File

@ -34,13 +34,13 @@
"type": "rgb" "type": "rgb"
}, },
{ {
"default": "1", "default": "1.0",
"label": "", "label": "",
"name": "metallic_tex", "name": "metallic_tex",
"type": "f" "type": "f"
}, },
{ {
"default": "1", "default": "1.0",
"label": "", "label": "",
"name": "roughness_tex", "name": "roughness_tex",
"type": "f" "type": "f"
@ -96,7 +96,7 @@
}, },
{ {
"desc":"3: normal map for Godot", "desc":"3: normal map for Godot",
"rgb": "$normal_tex($uv)", "rgb": "$normal_tex($uv)*vec3(-1.0, 1.0, 1.0)+vec3(1.0, 0.0, 0.0)",
"type": "rgb" "type": "rgb"
}, },
{ {
@ -108,6 +108,31 @@
"desc":"5: sub surface scattering", "desc":"5: sub surface scattering",
"f": "$sss_tex($uv)", "f": "$sss_tex($uv)",
"type": "f" "type": "f"
},
{
"desc":"6: unity metallic/smoothness",
"rgba": "vec4(vec3($metallic_tex($uv)), 1.0-$roughness_tex($uv))",
"type": "rgba"
},
{
"desc":"7: unity normal",
"rgb": "$normal_tex($uv)*vec3(1.0, 1.0, -1.0)+vec3(0.0, 0.0, 1.0)",
"type": "rgb"
},
{
"desc":"8: unity height",
"f": "1.0-$depth_tex($uv)",
"type": "f"
},
{
"desc":"9: unity occlusion",
"f": "$ao_tex($uv)",
"type": "f"
},
{
"desc":"10: unreal normal",
"rgb": "$normal_tex($uv)*vec3(-1.0)+vec3(1.0)",
"type": "rgb"
} }
], ],
"exports": { "exports": {
@ -116,43 +141,87 @@
"files": [ "files": [
{ {
"type":"texture", "type":"texture",
"file_name":"$(file_prefix)_albedo.png", "file_name":"$(path_prefix)_albedo.png",
"output":0, "output":0,
"conditions":"$(connected:albedo_tex)" "conditions":"$(connected:albedo_tex)"
}, },
{ {
"type":"texture", "type":"texture",
"file_name":"$(file_prefix)_orm.png", "file_name":"$(path_prefix)_orm.png",
"output":1, "output":1,
"conditions":"$(connected:ao_tex) or $(connected:roughness_tex) or $(connected:metallic_tex)" "conditions":"$(connected:ao_tex) or $(connected:roughness_tex) or $(connected:metallic_tex)"
}, },
{ {
"type":"texture", "type":"texture",
"file_name":"$(file_prefix)_emission.png", "file_name":"$(path_prefix)_emission.png",
"output":2, "output":2,
"conditions":"$(connected:emission_tex)" "conditions":"$(connected:emission_tex)"
}, },
{ {
"type":"texture", "type":"texture",
"file_name":"$(file_prefix)_normal.png", "file_name":"$(path_prefix)_normal.png",
"output":3, "output":3,
"conditions":"$(connected:normal_tex)" "conditions":"$(connected:normal_tex)"
}, },
{ {
"type":"texture", "type":"texture",
"file_name":"$(file_prefix)_depth.png", "file_name":"$(path_prefix)_depth.png",
"output":4, "output":4,
"conditions":"$(connected:depth_tex)" "conditions":"$(connected:depth_tex)"
}, },
{ {
"type":"texture", "type":"texture",
"file_name":"$(file_prefix)_sss.png", "file_name":"$(path_prefix)_sss.png",
"output":5, "output":5,
"conditions":"$(connected:sss_tex)" "conditions":"$(connected:sss_tex)"
},
{
"type":"template",
"file_name":"$(path_prefix).tres",
"template":"godot.tres.tmpl"
} }
] ]
}, },
"Unity": { "Unity": {
"export_extension":"mat",
"files": [
{
"type":"texture",
"file_name":"$(path_prefix)_albedo.png",
"output":0,
"conditions":"$(connected:albedo_tex)"
},
{
"type":"texture",
"file_name":"$(path_prefix)_metal_smoothness.png",
"output":6,
"conditions":"$(connected:roughness_tex) or $(connected:metallic_tex)"
},
{
"type":"texture",
"file_name":"$(path_prefix)_normal.png",
"output":7,
"conditions":"$(connected:normal_tex)"
},
{
"type":"texture",
"file_name":"$(path_prefix)_height.png",
"output":8,
"conditions":"$(connected:depth_tex)"
},
{
"type":"texture",
"file_name":"$(path_prefix)_occlusion.png",
"output":9,
"conditions":"$(connected:ao_tex)"
},
{
"type":"texture",
"file_name":"$(path_prefix)_emission.png",
"output":2,
"conditions":"$(connected:emission_tex)"
}
]
}, },
"Unreal": { "Unreal": {
} }
@ -166,7 +235,7 @@
"r": 1 "r": 1
}, },
"label": "Albedo", "label": "Albedo",
"name": "albeco_color", "name": "albedo_color",
"type": "color" "type": "color"
}, },
{ {
@ -195,7 +264,7 @@
"label": "Emission", "label": "Emission",
"max": 1, "max": 1,
"min": 0, "min": 0,
"name": "emission", "name": "emission_energy",
"step": 0.01, "step": 0.01,
"type": "float" "type": "float"
}, },