@tool extends ShaderMaterial class_name VFEZMaterial2D enum BlendModeEnum { Mix = 0, Add = 1, Subtract = 2, Multiply = 3, Premultiplied_Alpha= 4 } enum LightModeEnum { Normal = 0, Unshaded = 1, LightOnly = 2 } @export_group("Render Options") @export var BlendMode: BlendModeEnum: get: return _blendMode set(value): _blendMode = value _update_shader_code() @export var LightMode: LightModeEnum: get: return _lightMode set(value): _lightMode = value _update_shader_code() var _blendMode: BlendModeEnum = BlendModeEnum.Mix var _lightMode: LightModeEnum = LightModeEnum.Normal # handle property gets. # if is shader property set it in shader # and if it starts with use_ update shader code to include new definitions # if is render property set new value and update shader code func _set(property, value): if property.begins_with("shader_parameter/"): set_shader_parameter(property.replace("shader_parameter/", ""), value) if property.begins_with("shader_parameter/use_"): _update_shader_code() func generate_render_options_definition_string() -> String: var definition_string: String = "" match _blendMode: BlendModeEnum.Mix: definition_string += "#define BLEND_MIX\n" BlendModeEnum.Add: definition_string += "#define BLEND_ADD\n" BlendModeEnum.Subtract: definition_string += "#define BLEND_SUB\n" BlendModeEnum.Multiply: definition_string += "#define BLEND_MUL\n" BlendModeEnum.Premultiplied_Alpha: definition_string += "#define BLEND_PREMUL_ALPHA\n" match _lightMode: LightModeEnum.Unshaded: definition_string += "#define UNSHADED\n" LightModeEnum.LightOnly: definition_string += "#define LIGHT_ONLY\n" return definition_string # update shader code to include new option definitions func _update_shader_code(): if not Engine.is_editor_hint(): return var template_header = """ // This shader was dynamically generated by the VFEZ material. // ********************************** // Every change to the VFEZ material Render Options or // Include Options generates a new shader. After every change // you can click on the new exported shader in the editor to view // the latest changes. Only the definitions (#define) actually change. // ********************************** """ # find current directory name and create absolute include path for template shader var base_dir_name = get_script().get_path().get_base_dir() var shader_include_str: String = "#include \"" + base_dir_name + "/Shaders/vfez_2d_template.gdshaderinc\"\n" var template_code: String = "shader_type canvas_item;\n" # we duplicate the shader, else the code bugs # if the generated shader is open in the editor shader = shader.duplicate() # initialize the shader code with the included shader template. # This is necessary to be able to read the shader uniforms later. shader.code = template_code + shader_include_str template_code += generate_render_options_definition_string() # set all shader definition options based on the relevant use_X uniform values for uniform in shader.get_shader_uniform_list(): var uniform_name: String = uniform["name"] # if start with use_ there is a relevant define options if uniform_name.begins_with("use_"): var shader_parameter = get_shader_parameter(uniform_name) # if use_ shader parameter is true (1) then set the define option # to enable the effect if shader_parameter != null && int(shader_parameter) == 1: # extract define option from shader_parameter name # for example use_uv_wave becomes -> UV_WAVE var define_option = uniform_name.replace("use_", "").to_upper() template_code += "#define %s\n" % define_option # update final code to include description template, the define options # and the shader include string at the end shader.code = template_header + template_code + shader_include_str func _init() -> void: if Engine.is_editor_hint(): shader = Shader.new() shader.resource_name = "VFEZ2DPreview" _update_shader_code()