Fixed opacity related problem in Material nodes

This commit is contained in:
Rodz Labs 2021-10-03 14:21:18 +02:00
parent 88fec56ed6
commit f0ab310e72
3 changed files with 36 additions and 27 deletions

View File

@ -127,7 +127,8 @@ func update_material(m, sequential : bool = false) -> void:
status = yield(status, "completed")
func update() -> void:
var result = process_shader(shader_model.preview_shader)
var processed_preview_shader = process_conditionals(shader_model.preview_shader)
var result = process_shader(processed_preview_shader)
preview_shader_code = result.shader_code
preview_texture_dependencies = result.texture_dependencies
@ -328,18 +329,19 @@ static func get_template_text(template : String) -> String:
return template
return in_file.get_as_text()
static func process_conditionals(template : String) -> String:
func process_conditionals(template : String) -> String:
var context = get_connections_and_parameters_context()
var processed : String = ""
var skip_state : Array = [ false ]
for l in template.split("\n"):
if l == "":
continue
elif l.left(4) == "$if ":
var condition = l.right(4)
var condition = subst_string(l.right(4), context)
var expr = Expression.new()
var error = expr.parse(condition, [])
if error != OK:
#print("Error in expression "+condition+": "+expr.get_error_text())
print("Error in expression "+condition+": "+expr.get_error_text())
continue
skip_state.push_back(!expr.execute())
elif l.left(3) == "$fi":
@ -423,32 +425,35 @@ func create_file_from_template(template : String, file_name : String, export_con
out_file.store_string(processed_template)
return true
func export_material(prefix : String, profile : String, size : int = 0) -> void:
reset_uids()
if size == 0:
size = get_image_size()
export_paths[profile] = prefix
var export_context : Dictionary = {
"$(path_prefix)":prefix,
"$(file_prefix)":prefix.get_file()
}
func get_connections_and_parameters_context() -> Dictionary:
var context : Dictionary = {}
for i in range(shader_model.inputs.size()):
var input = shader_model.inputs[i]
export_context["$(connected:"+input.name+")"] = "true" if get_source(i) != null else "false"
context["$(connected:"+input.name+")"] = "true" if get_source(i) != null else "false"
for p in shader_model.parameters:
var value = p.default
if parameters.has(p.name):
value = parameters[p.name]
match p.type:
"float", "size", "boolean":
export_context["$(param:"+p.name+")"] = str(value)
"float", "size":
context["$(param:"+p.name+")"] = str(value)
"boolean":
context["$(param:"+p.name+")"] = str(value).to_lower()
"color":
export_context["$(param:"+p.name+".r)"] = str(value.r)
export_context["$(param:"+p.name+".g)"] = str(value.g)
export_context["$(param:"+p.name+".b)"] = str(value.b)
export_context["$(param:"+p.name+".a)"] = str(value.a)
_:
print(p.type+" not supported in material")
context["$(param:"+p.name+".r)"] = str(value.r)
context["$(param:"+p.name+".g)"] = str(value.g)
context["$(param:"+p.name+".b)"] = str(value.b)
context["$(param:"+p.name+".a)"] = str(value.a)
return context
func export_material(prefix : String, profile : String, size : int = 0) -> void:
reset_uids()
if size == 0:
size = get_image_size()
export_paths[profile] = prefix
var export_context : Dictionary = get_connections_and_parameters_context()
export_context["$(path_prefix)"] = prefix
export_context["$(file_prefix)"] = prefix.get_file()
for f in shader_model.exports[profile].files:
if f.has("conditions"):
var condition = subst_string(f.conditions, export_context)

View File

@ -18,13 +18,15 @@
"ao": 1,
"depth_scale": 0.5,
"emission_energy": 1,
"flags_transparent": false,
"flags_transparent": true,
"metallic": 0,
"normal": 1,
"roughness": 1,
"size": 11,
"sss": 0
},
"seed": 0,
"seed_locked": false,
"shader_model": {
"code": "",
"custom": "",
@ -538,7 +540,7 @@
"type": "size"
}
],
"preview_shader": "shader_type spatial;\nrender_mode blend_mix,depth_draw_alpha_prepass,cull_back,diffuse_burley,specular_schlick_ggx;\nuniform sampler2D texture_albedo : hint_albedo; // $output(0)\nuniform sampler2D texture_emission : hint_black_albedo; // $output(2)\nuniform sampler2D texture_normal : hint_normal; // $output(3)\nuniform sampler2D texture_orm : hint_white; // $output(1)\nuniform sampler2D texture_subsurface_scattering : hint_white; // $output(5)\nuniform sampler2D texture_depth : hint_black; // $output(4)\nuniform int depth_min_layers = 8;\nuniform int depth_max_layers = 32;\nuniform vec2 depth_flip = vec2(1.0);\n\nuniform vec3 uv1_scale;\nuniform vec3 uv1_offset;\n\n$definitions\n\nvoid vertex() {\n\tUV=UV*uv1_scale.xy+uv1_offset.xy;\n}\n\nvoid fragment() {\n\tvec2 base_uv = UV;\n\t{\n$begin_generate\n\t\tfloat depth_scale = 0.2*$depth_scale;\n$end_generate\n\t\tvec3 view_dir = normalize(normalize(-VERTEX)*mat3(TANGENT*depth_flip.x,-BINORMAL*depth_flip.y,NORMAL));\n\t\tfloat num_layers = mix(float(depth_max_layers),float(depth_min_layers), abs(dot(vec3(0.0, 0.0, 1.0), view_dir)));\n\t\tfloat layer_depth = 1.0 / num_layers;\n\t\tfloat current_layer_depth = 0.0;\n\t\tvec2 P = view_dir.xy * depth_scale;\n\t\tvec2 delta = P / num_layers;\n\t\tvec2 ofs = base_uv;\n\t\tfloat depth = textureLod(texture_depth, ofs,0.0).r;\n\t\tfloat current_depth = 0.0;\n\t\twhile(current_depth < depth) {\n\t\t\tofs -= delta;\n\t\t\tdepth = textureLod(texture_depth, ofs,0.0).r;\n\t\t\tcurrent_depth += layer_depth;\n\t\t}\n\t\tvec2 prev_ofs = ofs + delta;\n\t\tfloat after_depth = depth - current_depth;\n\t\tfloat before_depth = textureLod(texture_depth, prev_ofs, 0.0).r - current_depth + layer_depth;\n\t\tfloat weight = after_depth / (after_depth - before_depth);\n\t\tofs = mix(ofs,prev_ofs,weight);\n\t\tbase_uv=ofs;\n\t}\n$begin_generate\n\tvec4 albedo_tex = texture(texture_albedo, base_uv);\n\tALBEDO = $albedo_color.rgb * albedo_tex.rgb;\n\tvec4 orm_tex = texture(texture_orm, base_uv);\n\tMETALLIC = $metallic*orm_tex.b;\n\tROUGHNESS = $roughness*orm_tex.g;\n\tSPECULAR = 0.5;\n\tNORMALMAP = texture(texture_normal, base_uv).rgb;\n\tNORMALMAP_DEPTH = $normal;\n\tvec3 emission_tex = texture(texture_emission, base_uv).rgb;\n\tEMISSION = emission_tex*$emission_energy;\n\tAO = orm_tex.r;\n\tAO_LIGHT_AFFECT = $ao;\n\tif ($flags_transparent) {\n\t\tALPHA = albedo_tex.a;\n\t}\n\tfloat sss_tex = texture(texture_subsurface_scattering, base_uv).r;\n\tSSS_STRENGTH=$sss*sss_tex;\n$end_generate\n}\n"
"preview_shader": "shader_type spatial;\nrender_mode blend_mix,cull_back,diffuse_burley,specular_schlick_ggx\n$if $(connected:opacity_tex) and $(param:flags_transparent)\n,depth_draw_alpha_prepass\n$fi\n;\n\nuniform sampler2D texture_albedo : hint_albedo; // $output(0)\nuniform sampler2D texture_emission : hint_black_albedo; // $output(2)\nuniform sampler2D texture_normal : hint_normal; // $output(3)\nuniform sampler2D texture_orm : hint_white; // $output(1)\nuniform sampler2D texture_subsurface_scattering : hint_white; // $output(5)\nuniform sampler2D texture_depth : hint_black; // $output(4)\nuniform int depth_min_layers = 8;\nuniform int depth_max_layers = 32;\nuniform vec2 depth_flip = vec2(1.0);\n\nuniform vec3 uv1_scale;\nuniform vec3 uv1_offset;\n\n$definitions\n\nvoid vertex() {\n\tUV=UV*uv1_scale.xy+uv1_offset.xy;\n}\n\nvoid fragment() {\n\tvec2 base_uv = UV;\n$if $(connected:depth_tex)\n\t{\n$begin_generate\n\t\tfloat depth_scale = 0.2*$depth_scale;\n$end_generate\n\t\tvec3 view_dir = normalize(normalize(-VERTEX)*mat3(TANGENT*depth_flip.x,-BINORMAL*depth_flip.y,NORMAL));\n\t\tfloat num_layers = mix(float(depth_max_layers),float(depth_min_layers), abs(dot(vec3(0.0, 0.0, 1.0), view_dir)));\n\t\tfloat layer_depth = 1.0 / num_layers;\n\t\tfloat current_layer_depth = 0.0;\n\t\tvec2 P = view_dir.xy * depth_scale;\n\t\tvec2 delta = P / num_layers;\n\t\tvec2 ofs = base_uv;\n\t\tfloat depth = textureLod(texture_depth, ofs,0.0).r;\n\t\tfloat current_depth = 0.0;\n\t\twhile(current_depth < depth) {\n\t\t\tofs -= delta;\n\t\t\tdepth = textureLod(texture_depth, ofs,0.0).r;\n\t\t\tcurrent_depth += layer_depth;\n\t\t}\n\t\tvec2 prev_ofs = ofs + delta;\n\t\tfloat after_depth = depth - current_depth;\n\t\tfloat before_depth = textureLod(texture_depth, prev_ofs, 0.0).r - current_depth + layer_depth;\n\t\tfloat weight = after_depth / (after_depth - before_depth);\n\t\tofs = mix(ofs,prev_ofs,weight);\n\t\tbase_uv=ofs;\n\t}\n$fi\n$begin_generate\n\tvec4 albedo_tex = texture(texture_albedo, base_uv);\n\tALBEDO = $albedo_color.rgb * albedo_tex.rgb;\n\tvec4 orm_tex = texture(texture_orm, base_uv);\n\tMETALLIC = $metallic*orm_tex.b;\n\tROUGHNESS = $roughness*orm_tex.g;\n\tSPECULAR = 0.5;\n\tNORMALMAP = texture(texture_normal, base_uv).rgb;\n\tNORMALMAP_DEPTH = $normal;\n\tvec3 emission_tex = texture(texture_emission, base_uv).rgb;\n\tEMISSION = emission_tex*$emission_energy;\n\tAO = orm_tex.r;\n\tAO_LIGHT_AFFECT = $ao;\n$if $(connected:opacity_tex) and $(param:flags_transparent)\n\tALPHA = albedo_tex.a;\n$fi\n\tfloat sss_tex = texture(texture_subsurface_scattering, base_uv).r;\n\tSSS_STRENGTH=$sss*sss_tex;\n$end_generate\n}\n"
},
"type": "material_export"
}

View File

@ -18,11 +18,13 @@
"ao": 1,
"depth_scale": 0.5,
"emission_energy": 1,
"flags_transparent": false,
"flags_transparent": true,
"metallic": 0,
"normal": 1,
"roughness": 1
},
"seed": 0,
"seed_locked": false,
"shader_model": {
"code": "",
"custom": "",
@ -37,7 +39,7 @@
},
{
"file_name": "$(path_prefix).shader",
"template": "shader_type spatial;\nuniform vec3 uv1_scale = vec3(1.0, 1.0, 1.0);\nuniform int depth_min_layers = 8;\nuniform int depth_max_layers = 16;\nuniform vec2 depth_flip = vec2(1.0);\nuniform float variation = 0.0;\nvarying float elapsed_time;\nvoid vertex() {\n\telapsed_time = TIME;\n}\n$definitions float_uniform_to_const,rename_buffers\nvoid fragment() {\n\tfloat _seed_variation_ = variation;\n\tvec2 uv = fract(UV*uv1_scale.xy);\n$if $(connected:depth_tex)\n$begin_generate rename_buffers\n\t{\n\t\tfloat depth_scale = 0.2*$depth_scale;\n\t\tvec3 view_dir = normalize(normalize(-VERTEX)*mat3(TANGENT*depth_flip.x,-BINORMAL*depth_flip.y,NORMAL));\n\t\tfloat num_layers = mix(float(depth_max_layers),float(depth_min_layers), abs(dot(vec3(0.0, 0.0, 1.0), view_dir)));\n\t\tfloat layer_depth = 1.0 / num_layers;\n\t\tfloat current_layer_depth = 0.0;\n\t\tvec2 P = view_dir.xy * depth_scale;\n\t\tvec2 delta = P / num_layers;\n\t\tvec2 ofs = uv;\n\t\tfloat depth = $depth_tex(ofs);\n\t\tfloat current_depth = 0.0;\n\t\twhile(current_depth < depth) {\n\t\t\tofs -= delta;\n\t\t\tdepth = $depth_tex(ofs);\n\t\t\tcurrent_depth += layer_depth;\n\t\t}\n\t\tvec2 prev_ofs = ofs + delta;\n\t\tfloat after_depth = depth - current_depth;\n\t\tfloat before_depth = $depth_tex(prev_ofs) - current_depth + layer_depth;\n\t\tfloat weight = after_depth / (after_depth - before_depth);\n\t\tofs = mix(ofs,prev_ofs,weight);\n\t\tuv = ofs;\n\t}\n$end_generate\n$fi\n$begin_generate rename_buffers\n\tvec3 albedo_tex = $albedo_tex(uv).rgb;\n\talbedo_tex = mix(pow((albedo_tex + vec3(0.055)) * (1.0 / (1.0 + 0.055)),vec3(2.4)),albedo_tex * (1.0 / 12.92),lessThan(albedo_tex,vec3(0.04045)));\n\tALBEDO = albedo_tex*$albedo_color.rgb;\n\tMETALLIC = $metallic_tex(uv)*$metallic;\n\tROUGHNESS = $roughness_tex(uv)*$roughness;\n\tNORMALMAP = $normal_tex(uv);\n\tEMISSION = $emission_tex(uv)*$emission_energy;\n\tALPHA = $opacity_tex(uv);\n$end_generate\n}\n",
"template": "shader_type spatial;\nrender_mode blend_mix,cull_back,diffuse_burley,specular_schlick_ggx\n$if $(connected:opacity_tex) and $(param:flags_transparent)\n,depth_draw_alpha_prepass\n$fi\n;\n\nuniform vec3 uv1_offset = vec3(1.0, 1.0, 1.0);\nuniform vec3 uv1_scale = vec3(1.0, 1.0, 1.0);\nuniform int depth_min_layers = 8;\nuniform int depth_max_layers = 16;\nuniform vec2 depth_flip = vec2(1.0);\nuniform float variation = 0.0;\nvarying float elapsed_time;\n\nvoid vertex() {\n\telapsed_time = TIME;\n\tUV = UV*uv1_scale.xy+uv1_offset.xy;\n}\n\n$definitions float_uniform_to_const,rename_buffers\n\nvoid fragment() {\n\tfloat _seed_variation_ = variation;\n\tvec2 uv = fract(UV);\n$if $(connected:depth_tex)\n\t{\n$begin_generate\n\t\tfloat depth_scale = 0.2*$depth_scale;\n$end_generate\n\t\tvec3 view_dir = normalize(normalize(-VERTEX)*mat3(TANGENT*depth_flip.x,-BINORMAL*depth_flip.y,NORMAL));\n\t\tfloat num_layers = mix(float(depth_max_layers),float(depth_min_layers), abs(dot(vec3(0.0, 0.0, 1.0), view_dir)));\n\t\tfloat layer_depth = 1.0 / num_layers;\n\t\tfloat current_layer_depth = 0.0;\n\t\tvec2 P = view_dir.xy * depth_scale;\n\t\tvec2 delta = P / num_layers;\n\t\tvec2 ofs = uv;\n$begin_generate\n\t\tfloat depth = $depth_tex(ofs);\n$end_generate\n\t\tfloat current_depth = 0.0;\n\t\twhile(current_depth < depth) {\n\t\t\tofs -= delta;\n$begin_generate\n\t\t\tdepth = $depth_tex(ofs);\n$end_generate\n\t\t\tcurrent_depth += layer_depth;\n\t\t}\n\t\tvec2 prev_ofs = ofs + delta;\n\t\tfloat after_depth = depth - current_depth;\n$begin_generate\n\t\tfloat before_depth = $depth_tex(prev_ofs) - current_depth + layer_depth;\n$end_generate\n\t\tfloat weight = after_depth / (after_depth - before_depth);\n\t\tofs = mix(ofs, prev_ofs, weight);\n\t\tuv = ofs;\n\t}\n$fi\n$begin_generate rename_buffers\n\tvec3 albedo_tex = $albedo_tex(uv).rgb;\n\talbedo_tex = mix(pow((albedo_tex + vec3(0.055)) * (1.0 / (1.0 + 0.055)),vec3(2.4)),albedo_tex * (1.0 / 12.92),lessThan(albedo_tex,vec3(0.04045)));\n\tALBEDO = albedo_tex*$albedo_color.rgb;\n\tMETALLIC = $metallic_tex(uv)*$metallic;\n\tROUGHNESS = $roughness_tex(uv)*$roughness;\n\tNORMALMAP = $normal_tex(uv);\n\tEMISSION = $emission_tex(uv)*$emission_energy;\n$if $(connected:opacity_tex) and $(param:flags_transparent)\n\tALPHA = $opacity_tex(uv);\n$fi\n$end_generate\n}\n",
"type": "template"
},
{
@ -227,7 +229,7 @@
"type": "boolean"
}
],
"preview_shader": "shader_type spatial;\nrender_mode blend_mix,depth_draw_alpha_prepass,cull_back,diffuse_burley,specular_schlick_ggx;\n\nuniform vec3 uv1_offset = vec3(1.0, 1.0, 1.0);\nuniform vec3 uv1_scale = vec3(1.0, 1.0, 1.0);\nuniform int depth_min_layers = 8;\nuniform int depth_max_layers = 32;\nuniform vec2 depth_flip = vec2(1.0);\nuniform float variation = 0.0;\n\nvarying float elapsed_time;\n\nvoid vertex() {\n\telapsed_time = TIME;\n\tUV = UV*uv1_scale.xy+uv1_offset.xy;\n}\n\n//---\n\n\n$definitions\n\nvoid fragment() {\n\tfloat _seed_variation_ = variation;\n\tvec2 uv = fract(UV);\n$begin_generate\n\t{\n\t\tfloat depth_scale = 0.2*$depth_scale;\n\t\tvec3 view_dir = normalize(normalize(-VERTEX)*mat3(TANGENT*depth_flip.x,-BINORMAL*depth_flip.y,NORMAL));\n\t\tfloat num_layers = mix(float(depth_max_layers),float(depth_min_layers), abs(dot(vec3(0.0, 0.0, 1.0), view_dir)));\n\t\tfloat layer_depth = 1.0 / num_layers;\n\t\tfloat current_layer_depth = 0.0;\n\t\tvec2 P = view_dir.xy * depth_scale;\n\t\tvec2 delta = P / num_layers;\n\t\tvec2 ofs = uv;\n\t\tfloat depth = $depth_tex(ofs);\n\t\tfloat current_depth = 0.0;\n\t\twhile(current_depth < depth) {\n\t\t\tofs -= delta;\n\t\t\tdepth = $depth_tex(ofs);\n\t\t\tcurrent_depth += layer_depth;\n\t\t}\n\t\tvec2 prev_ofs = ofs + delta;\n\t\tfloat after_depth = depth - current_depth;\n\t\tfloat before_depth = $depth_tex(prev_ofs) - current_depth + layer_depth;\n\t\tfloat weight = after_depth / (after_depth - before_depth);\n\t\tofs = mix(ofs,prev_ofs,weight);\n\t\tuv = ofs;\n\t}\n$end_generate\n$begin_generate\n\tvec3 albedo_tex = $albedo_tex(uv);\n\talbedo_tex = mix(pow((albedo_tex + vec3(0.055)) * (1.0 / (1.0 + 0.055)),vec3(2.4)),albedo_tex * (1.0 / 12.92),lessThan(albedo_tex,vec3(0.04045)));\n\tALBEDO = albedo_tex.rgb*$albedo_color.rgb;\n\tMETALLIC = $metallic_tex(uv)*$metallic;\n\tROUGHNESS = $roughness_tex(uv)*$roughness;\n\tNORMALMAP = $normal_tex(uv);\n\tNORMALMAP_DEPTH = $normal;\n\tEMISSION = $emission_tex(uv)*$emission_energy;\n\tAO = $ao*$ao_tex(uv);\n\tif ($flags_transparent) {\n\t\tALPHA = $opacity_tex(uv);\n\t}\n$end_generate\n}\n"
"preview_shader": "shader_type spatial;\nrender_mode blend_mix,cull_back,diffuse_burley,specular_schlick_ggx\n$if $(connected:opacity_tex) and $(param:flags_transparent)\n,depth_draw_alpha_prepass\n$fi\n;\n\nuniform vec3 uv1_offset = vec3(1.0, 1.0, 1.0);\nuniform vec3 uv1_scale = vec3(1.0, 1.0, 1.0);\nuniform int depth_min_layers = 8;\nuniform int depth_max_layers = 32;\nuniform vec2 depth_flip = vec2(1.0);\nuniform float variation = 0.0;\n\nvarying float elapsed_time;\n\nvoid vertex() {\n\telapsed_time = TIME;\n\tUV = UV*uv1_scale.xy+uv1_offset.xy;\n}\n\n//---\n\n\n$definitions\n\nvoid fragment() {\n\tfloat _seed_variation_ = variation;\n\tvec2 uv = fract(UV);\n\n$if $(connected:depth_tex)\n\t{\n$begin_generate\n\t\tfloat depth_scale = 0.2*$depth_scale;\n$end_generate\n\t\tvec3 view_dir = normalize(normalize(-VERTEX)*mat3(TANGENT*depth_flip.x,-BINORMAL*depth_flip.y,NORMAL));\n\t\tfloat num_layers = mix(float(depth_max_layers),float(depth_min_layers), abs(dot(vec3(0.0, 0.0, 1.0), view_dir)));\n\t\tfloat layer_depth = 1.0 / num_layers;\n\t\tfloat current_layer_depth = 0.0;\n\t\tvec2 P = view_dir.xy * depth_scale;\n\t\tvec2 delta = P / num_layers;\n\t\tvec2 ofs = uv;\n$begin_generate\n\t\tfloat depth = $depth_tex(ofs);\n$end_generate\n\t\tfloat current_depth = 0.0;\n\t\twhile(current_depth < depth) {\n\t\t\tofs -= delta;\n$begin_generate\n\t\t\tdepth = $depth_tex(ofs);\n$end_generate\n\t\t\tcurrent_depth += layer_depth;\n\t\t}\n\t\tvec2 prev_ofs = ofs + delta;\n\t\tfloat after_depth = depth - current_depth;\n$begin_generate\n\t\tfloat before_depth = $depth_tex(prev_ofs) - current_depth + layer_depth;\n$end_generate\n\t\tfloat weight = after_depth / (after_depth - before_depth);\n\t\tofs = mix(ofs,prev_ofs,weight);\n\t\tuv = ofs;\n\t}\n$fi\n$begin_generate\n\tvec3 albedo_tex = $albedo_tex(uv);\n\talbedo_tex = mix(pow((albedo_tex + vec3(0.055)) * (1.0 / (1.0 + 0.055)),vec3(2.4)),albedo_tex * (1.0 / 12.92),lessThan(albedo_tex,vec3(0.04045)));\n\tALBEDO = albedo_tex.rgb*$albedo_color.rgb;\n\tMETALLIC = $metallic_tex(uv)*$metallic;\n\tROUGHNESS = $roughness_tex(uv)*$roughness;\n\tNORMALMAP = $normal_tex(uv);\n\tNORMALMAP_DEPTH = $normal;\n\tEMISSION = $emission_tex(uv)*$emission_energy;\n\tAO = $ao*$ao_tex(uv);\n$if $(connected:opacity_tex) and $(param:flags_transparent)\n\tALPHA = $opacity_tex(uv);\n$fi\n$end_generate\n}\n"
},
"type": "material_export"
}