From 1496de8262b104ad7dd52b9f6e936fcd6ed1d384 Mon Sep 17 00:00:00 2001 From: hop311 Date: Mon, 8 Jul 2024 22:34:57 +0100 Subject: Scrolling model materials (tank tracks and smoke) --- game/src/Game/Model/UnitModel.gd | 46 ++++++++++------ game/src/Game/Model/XACLoader.gd | 89 ++++++++++++++++++++++++------- game/src/Game/Model/flag.gdshader | 9 ++-- game/src/Game/Model/scrolling.gdshader | 19 +++++++ game/src/Game/Model/scrolling_mat.tres | 9 ++++ game/src/Game/Model/unit_colours.gdshader | 10 ++-- game/src/Game/Model/unit_colours_mat.tres | 2 +- 7 files changed, 139 insertions(+), 45 deletions(-) create mode 100644 game/src/Game/Model/scrolling.gdshader create mode 100644 game/src/Game/Model/scrolling_mat.tres (limited to 'game/src/Game/Model') diff --git a/game/src/Game/Model/UnitModel.gd b/game/src/Game/Model/UnitModel.gd index 0a4fe2f..e98d22a 100644 --- a/game/src/Game/Model/UnitModel.gd +++ b/game/src/Game/Model/UnitModel.gd @@ -12,21 +12,21 @@ var meshes : Array[MeshInstance3D] @export var primary_colour : Color: set(col_in): primary_colour = col_in - change_colour_prop(&"colour_primary", primary_colour) + _set_shader_parameter(&"colour_primary", primary_colour) for unit : UnitModel in sub_units: unit.primary_colour = col_in @export var secondary_colour: Color: set(col_in): secondary_colour = col_in - change_colour_prop(&"colour_secondary", secondary_colour) + _set_shader_parameter(&"colour_secondary", secondary_colour) for unit : UnitModel in sub_units: unit.secondary_colour = col_in @export var tertiary_colour : Color: set(col_in): tertiary_colour = col_in - change_colour_prop(&"colour_tertiary", tertiary_colour) + _set_shader_parameter(&"colour_tertiary", tertiary_colour) for unit : UnitModel in sub_units: unit.tertiary_colour = col_in @@ -64,16 +64,19 @@ const ANIMATION_ATTACK : String = ANIMATION_LIBRARY + "/attack" Anim.IDLE: if idle_anim: anim_player.set_current_animation(ANIMATION_IDLE) + _set_tex_scroll(scroll_speed_idle) current_anim = Anim.IDLE return Anim.MOVE: if move_anim: anim_player.set_current_animation(ANIMATION_MOVE) + _set_tex_scroll(scroll_speed_move) current_anim = Anim.MOVE return Anim.ATTACK: if attack_anim: anim_player.set_current_animation(ANIMATION_ATTACK) + _set_tex_scroll(scroll_speed_attack) current_anim = Anim.ATTACK return _: #None @@ -81,13 +84,28 @@ const ANIMATION_ATTACK : String = ANIMATION_LIBRARY + "/attack" anim_player.stop() + _set_tex_scroll(0.0) current_anim = Anim.NONE # TEXTURE SCROLL SPEEDS (TANKS TRACKS AND SMOKE) @export_subgroup("Texture_Scroll") -@export var scroll_speed_idle : float = 0.0 -@export var scroll_speed_move : float = 0.0 -@export var scroll_speed_attack : float = 0.0 +@export var scroll_speed_idle : float: + set(speed_in): + scroll_speed_idle = speed_in + for unit : UnitModel in sub_units: + unit.scroll_speed_idle = speed_in + +@export var scroll_speed_move : float: + set(speed_in): + scroll_speed_move = speed_in + for unit : UnitModel in sub_units: + unit.scroll_speed_move = speed_in + +@export var scroll_speed_attack : float: + set(speed_in): + scroll_speed_attack = speed_in + for unit : UnitModel in sub_units: + unit.scroll_speed_attack = speed_in func unit_init() -> void: for child : Node in get_children(): @@ -138,19 +156,15 @@ func attach_model(bone_name : String, model : Node3D) -> Error: return OK -func _set_tex_scroll(speed : float) -> void: +func _set_shader_parameter(param_name : StringName, param_val : Variant) -> void: for mesh : MeshInstance3D in meshes: - if mesh.get_active_material(0) is ShaderMaterial: - mesh.set_instance_shader_parameter(&"scroll", Vector2(0, speed)) + mesh.set_instance_shader_parameter(param_name, param_val) -func set_flag_index(index : int) -> void: - for mesh : MeshInstance3D in meshes: - mesh.set_instance_shader_parameter(&"flag_index", index) +func _set_tex_scroll(speed : float) -> void: + _set_shader_parameter(&"scroll_speed", speed) -func change_colour_prop(prop_name : StringName, prop_val : Color) -> void: - for mesh : MeshInstance3D in meshes: - if mesh.get_active_material(0) is ShaderMaterial: - mesh.set_instance_shader_parameter(prop_name, prop_val) +func set_flag_index(index : int) -> void: + _set_shader_parameter(&"flag_index", index) func load_animation(prop_name : String, animIn : Animation) -> void: if not animIn: diff --git a/game/src/Game/Model/XACLoader.gd b/game/src/Game/Model/XACLoader.gd index 330384b..b003296 100644 --- a/game/src/Game/Model/XACLoader.gd +++ b/game/src/Game/Model/XACLoader.gd @@ -1,12 +1,20 @@ class_name XACLoader -static var shader : ShaderMaterial = preload("res://src/Game/Model/unit_colours_mat.tres") +static var unit_shader : ShaderMaterial = preload("res://src/Game/Model/unit_colours_mat.tres") const MAX_UNIT_TEXTURES : int = 32 # max number of textures supported by the shader -static var added_textures_spec : PackedStringArray -static var added_textures_diffuse : PackedStringArray +static var added_unit_textures_spec : PackedStringArray +static var added_unit_textures_diffuse : PackedStringArray static var flag_shader : ShaderMaterial = preload("res://src/Game/Model/flag_mat.tres") +static var scrolling_shader : ShaderMaterial = preload("res://src/Game/Model/scrolling_mat.tres") +const MAX_SCROLLING_TEXTURES : int = 32 # max number of textures supported by the shader +static var added_scrolling_textures_diffuse : PackedStringArray +const SCROLLING_MATERIAL_FACTORS : Dictionary = { + "TexAnim" : 2.5, # Tank tracks + "Smoke" : 0.3 # Buildings, factories, steam ships, sieges +} + static func setup_flag_shader() -> void: flag_shader.set_shader_parameter(&"flag_dims", GameSingleton.get_flag_dims()) flag_shader.set_shader_parameter(&"texture_flag_sheet_diffuse", GameSingleton.get_flag_sheet_texture()) @@ -266,6 +274,9 @@ static func _load_xac_model(source_file : String, is_unit : bool) -> Node3D: if materials[submesh.materialId].diffuse_index != -1: meshInstance.set_instance_shader_parameter(&"tex_index_diffuse", materials[submesh.materialId].diffuse_index) + if materials[submesh.materialId].scroll_index != -1: + meshInstance.set_instance_shader_parameter(&"scroll_tex_index_diffuse", materials[submesh.materialId].scroll_index) + return node # Information needed to set up a material @@ -273,14 +284,14 @@ static func _load_xac_model(source_file : String, is_unit : bool) -> Node3D: class MaterialDefinition: var spec_index : int = -1 var diffuse_index : int = -1 - var normal_index : int = -1 + var scroll_index : int = -1 var mat : Material - func _init(mat : Material, diffuse_ind : int = -1, spec_ind : int = -1, normal_ind : int = -1) -> void: + func _init(mat : Material, diffuse_ind : int = -1, spec_ind : int = -1, scroll_ind : int = -1) -> void: self.mat = mat self.diffuse_index = diffuse_ind self.spec_index = spec_ind - self.normal_index = normal_ind + self.scroll_index = scroll_ind static func make_materials(materialDefinitionChunks : Array[MaterialDefinitionChunk]) -> Array[MaterialDefinition]: const TEXTURES_PATH : String = "gfx/anims/%s.dds" @@ -328,41 +339,45 @@ static func make_materials(materialDefinitionChunks : Array[MaterialDefinitionCh if normal_name: push_error("Normal texture present in unit colours material: ", normal_name) - var textures_index_spec : int = added_textures_spec.find(specular_name) + var textures_index_spec : int = added_unit_textures_spec.find(specular_name) if textures_index_spec < 0: var unit_colours_mask_texture : ImageTexture = AssetManager.get_texture(TEXTURES_PATH % specular_name) if unit_colours_mask_texture: - added_textures_spec.push_back(specular_name) + added_unit_textures_spec.push_back(specular_name) # Should we still attempt to add the texture to the shader? - if len(added_textures_spec) >= MAX_UNIT_TEXTURES: + if len(added_unit_textures_spec) >= MAX_UNIT_TEXTURES: push_error("Colour masks have exceeded max number of textures supported by unit shader!") - var colour_masks : Array = shader.get_shader_parameter(&"texture_nation_colors_mask") + const param_texture_nation_colors_mask : StringName = &"texture_nation_colors_mask" + + var colour_masks : Array = unit_shader.get_shader_parameter(param_texture_nation_colors_mask) colour_masks.push_back(unit_colours_mask_texture) textures_index_spec = len(colour_masks) - 1 - shader.set_shader_parameter(&"texture_nation_colors_mask", colour_masks) + unit_shader.set_shader_parameter(param_texture_nation_colors_mask, colour_masks) else: push_error("Failed to load specular texture: ", specular_name) - var textures_index_diffuse : int = added_textures_diffuse.find(diffuse_name) + var textures_index_diffuse : int = added_unit_textures_diffuse.find(diffuse_name) if textures_index_diffuse < 0: var diffuse_texture : ImageTexture = AssetManager.get_texture(TEXTURES_PATH % diffuse_name) if diffuse_texture: - added_textures_diffuse.push_back(diffuse_name) + added_unit_textures_diffuse.push_back(diffuse_name) # Should we still attempt to add the texture to the shader? - if len(added_textures_diffuse) >= MAX_UNIT_TEXTURES: - push_error("Albedos have exceeded max number of textures supported by unit shader!") + if len(added_unit_textures_diffuse) >= MAX_UNIT_TEXTURES: + push_error("Diffuse textures have exceeded max number supported by unit shader!") - var albedoes : Array = shader.get_shader_parameter(&"texture_albedo") - albedoes.push_back(diffuse_texture) - textures_index_diffuse = len(albedoes) - 1 - shader.set_shader_parameter(&"texture_albedo", albedoes) + const param_texture_diffuse : StringName = &"texture_diffuse" + + var diffuse_textures : Array = unit_shader.get_shader_parameter(param_texture_diffuse) + diffuse_textures.push_back(diffuse_texture) + textures_index_diffuse = len(diffuse_textures) - 1 + unit_shader.set_shader_parameter(param_texture_diffuse, diffuse_textures) else: push_error("Failed to load diffuse texture: ", diffuse_name) - materials.push_back(MaterialDefinition.new(shader, textures_index_diffuse, textures_index_spec)) + materials.push_back(MaterialDefinition.new(unit_shader, textures_index_diffuse, textures_index_spec)) # Flag (diffuse is unionjacksquare which is ignored) elif normal_name and not diffuse_name: @@ -377,6 +392,40 @@ static func make_materials(materialDefinitionChunks : Array[MaterialDefinitionCh materials.push_back(MaterialDefinition.new(flag_shader)) + # Scrolling texture + elif diffuse_name and matdef.name in SCROLLING_MATERIAL_FACTORS: + if specular_name: + push_error("Specular texture present in scrolling material: ", specular_name) + if normal_name: + push_error("Normal texture present in scrolling material: ", normal_name) + + var scroll_textures_index_diffuse : int = added_scrolling_textures_diffuse.find(diffuse_name) + if scroll_textures_index_diffuse < 0: + var diffuse_texture : ImageTexture = AssetManager.get_texture(TEXTURES_PATH % diffuse_name) + if diffuse_texture: + added_scrolling_textures_diffuse.push_back(diffuse_name) + + # Should we still attempt to add the texture to the shader? + if len(added_scrolling_textures_diffuse) >= MAX_SCROLLING_TEXTURES: + push_error("Diffuse textures have exceeded max number supported by scrolling shader!") + + const param_scroll_texture_diffuse : StringName = &"scroll_texture_diffuse" + + var scroll_diffuse_textures : Array = scrolling_shader.get_shader_parameter(param_scroll_texture_diffuse) + scroll_diffuse_textures.push_back(diffuse_texture) + scroll_textures_index_diffuse = len(scroll_diffuse_textures) - 1 + scrolling_shader.set_shader_parameter(param_scroll_texture_diffuse, scroll_diffuse_textures) + + const param_scroll_factor : StringName = &"scroll_factor" + + var scroll_factors : Array = scrolling_shader.get_shader_parameter(param_scroll_factor) + scroll_factors.push_back(SCROLLING_MATERIAL_FACTORS[matdef.name]) + scrolling_shader.set_shader_parameter(param_scroll_factor, scroll_factors) + else: + push_error("Failed to load diffuse texture: ", diffuse_name) + + materials.push_back(MaterialDefinition.new(scrolling_shader, -1, -1, scroll_textures_index_diffuse)) + # Standard material else: if specular_name: diff --git a/game/src/Game/Model/flag.gdshader b/game/src/Game/Model/flag.gdshader index d338e36..bf9ca18 100644 --- a/game/src/Game/Model/flag.gdshader +++ b/game/src/Game/Model/flag.gdshader @@ -9,7 +9,7 @@ uniform sampler2D texture_normal : hint_normal; instance uniform uint flag_index; -uniform vec2 scroll_speed = vec2(-0.25,0); +const float normal_scroll_speed = 0.3; // Scroll the Normal map, but leave the albedo alone void fragment() { @@ -21,6 +21,9 @@ void fragment() { vec2 flag_uv = (vec2(flag_pos) + UV * vec2(flag_dims)) / vec2(flag_sheet_dims); ALBEDO = texture(texture_flag_sheet_diffuse, flag_uv).rgb; - //ALBEDO = vec3(1, 0, 0); - NORMAL_MAP = texture(texture_normal, UV + TIME*scroll_speed).rgb; + + vec2 normal_uv = UV; + normal_uv.x -= TIME * normal_scroll_speed; + + NORMAL_MAP = texture(texture_normal, normal_uv).rgb; } diff --git a/game/src/Game/Model/scrolling.gdshader b/game/src/Game/Model/scrolling.gdshader new file mode 100644 index 0000000..c90ee19 --- /dev/null +++ b/game/src/Game/Model/scrolling.gdshader @@ -0,0 +1,19 @@ +shader_type spatial; + +// depth_prepass_alpha is to ensure opaque scrolling textures +// (e.g. tank tracks) are rendered correctly +render_mode cull_disabled, depth_prepass_alpha; + +uniform sampler2D scroll_texture_diffuse[32] : source_color, filter_linear_mipmap, repeat_enable; +uniform float scroll_factor[32]; + +instance uniform uint scroll_tex_index_diffuse; +instance uniform float scroll_speed; + +void fragment() { + vec2 uv_scrolled = UV; + uv_scrolled.y += TIME * scroll_speed * scroll_factor[scroll_tex_index_diffuse]; + + ALBEDO = texture(scroll_texture_diffuse[scroll_tex_index_diffuse], uv_scrolled).rgb; + ALPHA = texture(scroll_texture_diffuse[scroll_tex_index_diffuse], UV).a; +} diff --git a/game/src/Game/Model/scrolling_mat.tres b/game/src/Game/Model/scrolling_mat.tres new file mode 100644 index 0000000..ec58e70 --- /dev/null +++ b/game/src/Game/Model/scrolling_mat.tres @@ -0,0 +1,9 @@ +[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://5utra6tpdqag"] + +[ext_resource type="Shader" path="res://src/Game/Model/scrolling.gdshader" id="1_oqkkj"] + +[resource] +render_priority = 0 +shader = ExtResource("1_oqkkj") +shader_parameter/scroll_texture_diffuse = [] +shader_parameter/scroll_factor = [] diff --git a/game/src/Game/Model/unit_colours.gdshader b/game/src/Game/Model/unit_colours.gdshader index dd0f5e2..2ffc771 100644 --- a/game/src/Game/Model/unit_colours.gdshader +++ b/game/src/Game/Model/unit_colours.gdshader @@ -1,11 +1,11 @@ shader_type spatial; -render_mode blend_mix, depth_draw_opaque, cull_disabled, diffuse_burley, specular_schlick_ggx; +render_mode cull_disabled; //hold all the textures for the units that need this shader to mix in their //nation colours (mostly generic infantry units) -uniform sampler2D texture_albedo[32] : source_color, filter_linear_mipmap, repeat_enable; +uniform sampler2D texture_diffuse[32] : source_color, filter_linear_mipmap, repeat_enable; uniform sampler2D texture_nation_colors_mask[32] : source_color, filter_linear_mipmap, repeat_enable; instance uniform vec3 colour_primary : source_color; @@ -14,12 +14,12 @@ instance uniform vec3 colour_tertiary : source_color; //used to access the right textures since different units (with different textures) //will use this same shader -instance uniform uint tex_index_specular; instance uniform uint tex_index_diffuse; +instance uniform uint tex_index_specular; void fragment() { vec2 base_uv = UV; - vec4 albedo_tex = texture(texture_albedo[tex_index_diffuse], base_uv); + vec4 diffuse_tex = texture(texture_diffuse[tex_index_diffuse], base_uv); vec4 nation_colours_tex = texture(texture_nation_colors_mask[tex_index_specular], base_uv); //set colours to either be white (1,1,1) or the nation colour based on the mask @@ -27,5 +27,5 @@ void fragment() { vec3 secondary_col = mix(vec3(1.0, 1.0, 1.0), colour_secondary, nation_colours_tex.b); vec3 tertiary_col = mix(vec3(1.0, 1.0, 1.0), colour_tertiary, nation_colours_tex.r); - ALBEDO = albedo_tex.rgb * primary_col * secondary_col * tertiary_col; + ALBEDO = diffuse_tex.rgb * primary_col * secondary_col * tertiary_col; } diff --git a/game/src/Game/Model/unit_colours_mat.tres b/game/src/Game/Model/unit_colours_mat.tres index 43ca523..fa89766 100644 --- a/game/src/Game/Model/unit_colours_mat.tres +++ b/game/src/Game/Model/unit_colours_mat.tres @@ -5,5 +5,5 @@ [resource] render_priority = 0 shader = ExtResource("1_axmiw") -shader_parameter/texture_albedo = [] +shader_parameter/texture_diffuse = [] shader_parameter/texture_nation_colors_mask = [] -- cgit v1.2.3-56-ga3b1