kuligs2 What happens if you assign material directly to material_override property instead of calling set_surface_override_mateial()?

    xyz Some meshes have multiple materials hence the loop but i set it like this real quick

    func highlight_object(collider, is_mouse_entered:bool):
    	if collider is Item:
    		var mesh = collider.item_mesh
    		var material_count = mesh.get_surface_override_material_count()
    		for i in range(material_count):
    			var mat = mesh.get_active_material(i)
    			if is_mouse_entered:
    				var new_mat:Material = mat.duplicate()
    				new_mat.next_pass = HIGH_LIGHT
    				new_mat.resource_local_to_scene = true
    				mesh.material_override=new_mat #< --------------------------------------------
    				#mesh.set_surface_override_material(i,new_mat)
    				
    			else:
    				mat.next_pass = null
    			
    		
    	pass	

    Result the same

    • xyz replied to this.

      kuligs2 Print the item_mesh when you get it from the collider to see that it is indeed a different node for each instance.

        xyz
        Did more tests, it seems something is broken.

        As per some tutorial i generated "outline" mesh for the mesh, set the highlight material and set visibility to false.

        And i get the same behavior with setting the mesh visibility that i get setting materials.

        if i hover on one the other one lights up but not the one i hover on.

        func highlight_object(collider, is_mouse_entered:bool):
        	if collider is Item:
        		var mesh = collider.item_mesh
                        print("mesh : - ",mesh)
        		var outline_mesh = mesh.get_child(0)
        	
        		if is_mouse_entered:
        			outline_mesh.visible = true	
        			
        		else:
        			outline_mesh.visible = false	

        Printouts:

        entered player mouse
        mesh : - flask:<MeshInstance3D#47513077244>
        exited player mouse
        mesh : - flask:<MeshInstance3D#47513077244>
        exited player mouse
        mesh : - flask:<MeshInstance3D#47513077244>
        entered player mouse
        mesh : - flask:<MeshInstance3D#47513077244>

        The thing fired twice, not sure why but i hovered on 2 different potions, seems like they are the same instance..

        Yes i have duplicated them with CTRL + D and moved in the world tree.

        But i dont see how can i make it unique

        • xyz replied to this.

          kuligs2 The problem is likely in what (and when) is assigned to your item_mesh property since it apparently has the same value for all instances. If you're assigning in editor via exported reference you should instead assign upon instantiation in _ready(). Hard to debug from screenshots though, I'm guessing here. Make a minimal reproduction project and post it so we can take a look.

            xyz so there is no way to prototype with instnacing nodes manually using editor. Everything has to be preloaded in code then instnaced on _ready()? 🙁....

            • xyz replied to this.

              kuligs2 You can instance manually, just reassign the references in code at startup or try not duplicating instances via ctrl D, but instead drag each new instance to the scene from the file system window. This is a known pitfall and can be worked around in various ways depending on your project's setup and preferred workflow. Tbh I thought someone already complained about it at Godot's github. This was also discussed at length here before, so search around.

                xyz if you know what to search for then you can search for it. I dont, i just stumbled upon this issue so i asked why things not working the way they should. Many things that you do in the engine naturally have pitfalls it seems. Anyways, thanks for the info.

                The more you know..

                xyz but as you say, dragging from file browser on the scene tree works as it should. Materials/meshes are setting when i hover on with mouse and printouts give me different instance ID's. Wish ctrl + D did the same, instead of dragging with mouse. Maybe they could implement CTRL + Shift +D makes duplicate of the same instance and CTRL + D makes a new instance

                  kuligs2 don't change material, use a custom shader with instance uniform.

                  if you are using a standard material, you can click on it and do convert to shader.

                  In your shader, set the things that need to change, in this case the amount of vertex displacement and maybe color and alpha, to an instance uniform:

                  instance uniform vec3 albedo : source_color;
                  instance uniform float grow = 0.0

                  you can make the effect disappear by either setting the displacement very low, or using scissor transparency and setting the scissor or alpha to 0.

                  this will add a new tab in geometry where you can change the instance uniforms. these are unique to each object, so if you change one, the others will not be affected. It also has the best performance.

                  finally, in your script you can change the uniform instances of the meshInstance3D directly, and it will affect all materials with this uniform instance name in your mesh:
                  $metarig/Skeleton3D/Hair.set_instance_shader_parameter("albedo", Color.BLACK)

                    Jesusemora this does not work.

                    Code that sets stuff on mouse over:

                    	if collider is Item:
                    		var mesh :MeshInstance3D = collider.item_mesh
                    		
                    		var material_count = mesh.get_surface_override_material_count()
                    		if is_mouse_entered:
                    			print(mesh)
                    			mesh.set_instance_shader_parameter("uniform",1.0)
                    			mesh.set_instance_shader_parameter("grow",0.05)
                    			mesh.set_instance_shader_parameter("albedo",Color.CHARTREUSE)
                    			
                    		else:
                    			mesh.set_instance_shader_parameter("uniform",0.0)
                    			mesh.set_instance_shader_parameter("grow",0.0)
                    			mesh.set_instance_shader_parameter("albedo",Color.BLACK)

                    shader code:

                    // NOTE: Shader automatically converted from Godot Engine 4.2.1.stable's StandardMaterial3D.
                    
                    shader_type spatial;
                    render_mode blend_mix,depth_draw_opaque,cull_back,diffuse_burley,specular_schlick_ggx;
                    uniform vec4 albedo : source_color;
                    uniform sampler2D texture_albedo : source_color,filter_linear_mipmap,repeat_enable;
                    uniform float point_size : hint_range(0,128);
                    uniform float roughness : hint_range(0,1);
                    uniform sampler2D texture_metallic : hint_default_white,filter_linear_mipmap,repeat_enable;
                    uniform vec4 metallic_texture_channel;
                    uniform sampler2D texture_roughness : hint_roughness_r,filter_linear_mipmap,repeat_enable;
                    uniform float specular;
                    uniform float metallic;
                    uniform vec3 uv1_scale;
                    uniform vec3 uv1_offset;
                    uniform vec3 uv2_scale;
                    uniform vec3 uv2_offset;
                    
                    
                    instance uniform float grow = 0.0;
                    
                    void vertex() {
                    	UV=UV*uv1_scale.xy+uv1_offset.xy;
                    }
                    
                    
                    
                    
                    
                    
                    void fragment() {
                    	vec2 base_uv = UV;
                    	vec4 albedo_tex = texture(texture_albedo,base_uv);
                    	ALBEDO = albedo.rgb * albedo_tex.rgb;
                    	float metallic_tex = dot(texture(texture_metallic,base_uv),metallic_texture_channel);
                    	METALLIC = metallic_tex * metallic;
                    	vec4 roughness_texture_channel = vec4(1.0,0.0,0.0,0.0);
                    	float roughness_tex = dot(texture(texture_roughness,base_uv),roughness_texture_channel);
                    	ROUGHNESS = roughness_tex * roughness;
                    	SPECULAR = specular;
                    }

                      kuligs2 this does not work

                      You skipped a step

                      Jesusemora In your shader, set the things that need to change, in this case the amount of vertex displacement and maybe color and alpha, to an instance uniform:

                      instance uniform vec3 albedo : source_color;
                      instance uniform float grow = 0.0

                        Jesusemora
                        you mean albedo in shader?

                        it was already defined so i removed it otherwise it errors out

                        kuligs2 // NOTE: Shader automatically converted from Godot Engine 4.2.1.stable's StandardMaterial3D.

                        shader_type spatial;
                        render_mode blend_mix,depth_draw_opaque,cull_back,diffuse_burley,specular_schlick_ggx;
                        uniform vec4 albedo : source_color; <-----------------------------------------------------------------------------
                        uniform sampler2D texture_albedo : source_color,filter_linear_mipmap,repeat_enable;
                        uniform float point_size : hint_range(0,128);
                        uniform float roughness : hint_range(0,1);
                        uniform sampler2D texture_metallic : hint_default_white,filter_linear_mipmap,repeat_enable;
                        uniform vec4 metallic_texture_channel;
                        uniform sampler2D texture_roughness : hint_roughness_r,filter_linear_mipmap,repeat_enable;
                        uniform float specular;
                        uniform float metallic;
                        uniform vec3 uv1_scale;
                        uniform vec3 uv1_offset;
                        uniform vec3 uv2_scale;
                        uniform vec3 uv2_offset;

                          kuligs2 oh my bad, yeah the instance part..

                          // NOTE: Shader automatically converted from Godot Engine 4.2.1.stable's StandardMaterial3D.
                          
                          shader_type spatial;
                          render_mode blend_mix,depth_draw_opaque,cull_back,diffuse_burley,specular_schlick_ggx;
                          instance uniform vec4 albedo : source_color;
                          uniform sampler2D texture_albedo : source_color,filter_linear_mipmap,repeat_enable;
                          uniform float point_size : hint_range(0,128);
                          uniform float roughness : hint_range(0,1);
                          uniform sampler2D texture_metallic : hint_default_white,filter_linear_mipmap,repeat_enable;
                          uniform vec4 metallic_texture_channel;
                          uniform sampler2D texture_roughness : hint_roughness_r,filter_linear_mipmap,repeat_enable;
                          uniform float specular;
                          uniform float metallic;
                          uniform vec3 uv1_scale;
                          uniform vec3 uv1_offset;
                          uniform vec3 uv2_scale;
                          uniform vec3 uv2_offset;
                          
                          
                          instance uniform float grow = 0.0;
                          
                          void vertex() {
                          	UV=UV*uv1_scale.xy+uv1_offset.xy;
                          }
                          
                          
                          
                          
                          
                          
                          void fragment() {
                          	vec2 base_uv = UV;
                          	vec4 albedo_tex = texture(texture_albedo,base_uv);
                          	ALBEDO = albedo.rgb * albedo_tex.rgb;
                          	float metallic_tex = dot(texture(texture_metallic,base_uv),metallic_texture_channel);
                          	METALLIC = metallic_tex * metallic;
                          	vec4 roughness_texture_channel = vec4(1.0,0.0,0.0,0.0);
                          	float roughness_tex = dot(texture(texture_roughness,base_uv),roughness_texture_channel);
                          	ROUGHNESS = roughness_tex * roughness;
                          	SPECULAR = specular;
                          }

                          But then it looses color bydefault

                          But hover thing works, not as outline but a solid color

                          EDIT:
                          Maybe you meant create shader material - create material - the outline, set it to the nextpass of the base material, then convert it to shader material?

                            kuligs2 Maybe you meant create shader material - create material - the outline, set it to the nextpass of the base material, then convert it to shader material?

                            Yes.

                            Well i did this. Created standard material that is unshaded and outlines and cull mode it outlines.
                            Set it to the next pass of the main material:

                            Then convert it to shader.

                            // NOTE: Shader automatically converted from Godot Engine 4.2.1.stable's StandardMaterial3D.
                            
                            shader_type spatial;
                            render_mode blend_mix,depth_draw_opaque,cull_front,diffuse_burley,specular_schlick_ggx,unshaded;
                            instance uniform vec4 albedo : source_color;
                            uniform sampler2D texture_albedo : source_color,filter_linear_mipmap,repeat_enable;
                            //uniform float grow;
                            uniform float point_size : hint_range(0,128);
                            uniform float roughness : hint_range(0,1);
                            uniform sampler2D texture_metallic : hint_default_white,filter_linear_mipmap,repeat_enable;
                            uniform vec4 metallic_texture_channel;
                            uniform sampler2D texture_roughness : hint_roughness_r,filter_linear_mipmap,repeat_enable;
                            uniform float specular;
                            uniform float metallic;
                            uniform vec3 uv1_scale;
                            uniform vec3 uv1_offset;
                            uniform vec3 uv2_scale;
                            uniform vec3 uv2_offset;
                            
                            instance uniform float grow; //= 0.0;
                            
                            void vertex() {
                            	UV=UV*uv1_scale.xy+uv1_offset.xy;
                            	VERTEX+=NORMAL*grow;
                            }
                            
                            void fragment() {
                            	vec2 base_uv = UV;
                            	vec4 albedo_tex = texture(texture_albedo,base_uv);
                            	albedo_tex *= COLOR;
                            	ALBEDO = albedo.rgb * albedo_tex.rgb;
                            	float metallic_tex = dot(texture(texture_metallic,base_uv),metallic_texture_channel);
                            	METALLIC = metallic_tex * metallic;
                            	vec4 roughness_texture_channel = vec4(1.0,0.0,0.0,0.0);
                            	float roughness_tex = dot(texture(texture_roughness,base_uv),roughness_texture_channel);
                            	ROUGHNESS = roughness_tex * roughness;
                            	SPECULAR = specular;
                            }

                            The code for moose over:

                            	if collider is Item:
                            		var mesh :MeshInstance3D = collider.item_mesh
                            		
                            		var material_count = mesh.get_surface_override_material_count()
                            		if is_mouse_entered:
                            			print(mesh)
                            		for i in range(material_count):
                            			var mat = mesh.get_active_material(i)
                            			if mat.next_pass:
                            				if is_mouse_entered:
                            
                            					mat.next_pass.set_shader_parameter("albedo",Color.CHARTREUSE)
                            					mat.next_pass.set_shader_parameter("grow",0.05)
                            
                            					
                            				else:
                            					
                            					mat.next_pass.set_shader_parameter("albedo",Color.BLACK)
                            					mat.next_pass.set_shader_parameter("grow",0.00)

                            But it dont work

                              kuligs2 mat.next_pass.set_shader_parameter("albedo",Color.CHARTREUSE)

                              You are doing it wrong. You are getting a material and changing parameters.
                              You should change the instance uniforms of mesh:

                              Jesusemora the uniform instances of the meshInstance3D directly, and it will affect all materials with this uniform instance name in your mesh:
                              $metarig/Skeleton3D/Hair.set_instance_shader_parameter("albedo", Color.BLACK)

                              Delete everything in the for loop
                              Add the if mouse entered
                              The function is called on a meshinstance3D

                              Actually, you are already testing mouse entered, just add the code there and add an else.

                                Jesusemora but the meshinstance3d has multiple materials, not just one.
                                This means i need to set the shader for each of the materials in order to have the outline?

                                EDIT: YES i do have to set the shader material to all mesh material slots.

                                Ok so yeah it works the way you say.

                                func highlight_object(collider, is_mouse_entered:bool):
                                	if collider is Item:
                                		var mesh :MeshInstance3D = collider.item_mesh
                                		
                                		
                                		if is_mouse_entered:
                                			print(mesh)
                                			
                                			mesh.set_instance_shader_parameter("grow",0.01)
                                			mesh.set_instance_shader_parameter("albedo",Color.RED)
                                			
                                		else:
                                			
                                			mesh.set_instance_shader_parameter("grow",0.0)
                                			mesh.set_instance_shader_parameter("albedo",Color.BLACK)
                                	pass			



                                Its faint, but works

                                This works, thanks!