When making a gdshader the vertex code works fine, but I cannot figure out how to get the colours from the imported object, using either OBJ import or glTF import. The materials are just a baseColor for the glTF and a Kd diffuse colour for the OBJ’s mtl. The confusing part is the colours are fine when I use the default shader, but when i use ALBEDO = COLOR.xyz; in my shader, it just comes out white. There is no colouring. As far as I can tell, there are multiple “surfaces” with different colours, as when I use surface material override it only whites out one block of colour. How can I get the original colour, defined by the MTL/glTF, to output to ALBEDO
shader_type spatial;
render_mode world_vertex_coords;
global uniform float zFalloff = 1.0;
global uniform vec3 camPos;
void vertex() {
// Called for every vertex the material is visible on.
VERTEX.y -= pow(abs(VERTEX.z - camPos.z) / zFalloff, 2); //change height based on z position
}
void fragment() {
// Called for every pixel the material is visible on.
ALBEDO = COLOR.xyz;
}
Ok, so I fixed this by making a custom import script. First I converted a surface material to a Shader Material, and edited the shader to do what I want (y modification and sRGB conversion on the albedo colour). Then I saved this to another shader file, and used the following import script to copy over the albedo colour. This script only copies the albedo colour, but should be easy to modify to copy over other values, you just need to find their parameter name and material property name (i.e. Material.albedo_color corresponds to albedo in the shader).
extends EditorScenePostImport
# Called right after the scene is imported and gets the root node.
func _post_import(scene):
iterate(scene)
return scene # Remember to return the imported scene
# Recursive function that is called on every node
func iterate(node):
print("Processing scene");
if node != null:
if node is MeshInstance3D:
var myShader = load("res://Assets/Shaders and Materials/glTF_import.gdshader") as Shader #load the fixed shader
var mesh = node.mesh
for i in range(mesh.get_surface_count()): #iterate over every surface
var material = mesh.surface_get_material(i) as BaseMaterial3D #get and cast the material
var newMaterial = ShaderMaterial.new() #create new material
newMaterial.shader = myShader #use the fixed shader
newMaterial.set_shader_parameter("albedo", material.albedo_color) #copy over properties
mesh.surface_set_material(i, newMaterial) #set
for child in node.get_children():
iterate(child) #recurse