#Applying Color array to shader PackedArrayVector4 does not work

1 messages · Page 1 of 1 (latest)

celest hazel
#

anyone that could tell me how I can get this working with this shader + script? the color array doesnt seem to be passed to the shader from the gd script and I do not understand why ```swift
extends Node

@export var colors: Array[Color] = [Color.from_rgba8(172, 67, 47)]

var shader_material: ShaderMaterial;

func _ready() -> void:
shader_material = get_child(0, true).get_active_material(0) as ShaderMaterial;
var texture: CompressedTexture2D = shader_material.get_shader_parameter("albedo_texture");
colors = FileUtils.get_colors_from_palette(texture, 4, 8);

shader_material.set_shader_parameter("fallback_color", Color(1, 1, 1, 1))
apply_palette_to_shader()

func apply_palette_to_shader() -> void:
var packed_array := PackedVector4Array()
for color in colors:
packed_array.append(Vector4(color.r, color.g, color.b, color.a))

shader_material.set_shader_parameter("filter_colors", packed_array)
shader_material.set_shader_parameter("palette_size", colors.size())
```swift
shader_type spatial;
render_mode depth_prepass_alpha;

uniform sampler2D albedo_texture : source_color;
uniform vec4 filter_colors[1];
uniform vec4 fallback_color : source_color = vec4(0.0, 0.0, 0.0, 0.0);
uniform int palette_size = 1;

const float COLOR_THRESHOLD = 0.01;

bool is_allowed(vec4 color) {
    for (int i = 0; i < palette_size; i++) {
        if (distance(color.rgb, filter_colors[i].rgb) < COLOR_THRESHOLD) {
            return true;
        }
    }
    return false;
}

void fragment() {
    vec4 tex_color = texture(albedo_texture, UV);

    if (is_allowed(tex_color)) {
        ALBEDO = fallback_color.rgb;
        ALPHA = fallback_color.a;
    } else {
        ALBEDO = tex_color.rgb;
        ALPHA = tex_color.a;
    }
}
static quarry
#

I don't think shaders allow you to set dynamically sized arrays.
You might need to declare the size of the array in the shader code as the maximum size:
uniform vec4 filter_colors[64];
Then set palette_size the same way you are now.
On the GDScript size, send an array of colors that is the maximum size (64), padded with empty colors to the max size.

#

I can't remember the exact limitations of fixed size arrays in shaders at the moment

celest hazel
#

like that then?

#

hm

celest hazel
celest hazel
#

@static quarry the array is being passed correctly, its just not processing the actual properties I tihnk

static quarry
#

What do you mean not processing the actual properties?

celest hazel
#

I meant that I thought there was somethign wrong with the shader itself but I was just looking in the wrong location

#

@static quarry seems perfectly capable of assigning them

static quarry
#

I can't test the code that you already have in text form here, I don't have FileUtils

celest hazel
#

it works fine without it, thats to extract the color values from the texture

#

but its this one, though I have it disabled in my code atm and just hardcoded a color value```swift
static func get_colors_from_palette(texture: Texture2D, row_count: int, column_count: int) -> Array[Color]:
var image := texture.get_image()
var color_array: Array[Color] = []

for row in range(row_count):
    for col in range(column_count):
        var x := int((col / float(column_count)) * image.get_width())
        var y := int((row / float(row_count)) * image.get_height())
        var color := image.get_pixel(x, y)
        color_array.append(color)
return color_array;
static quarry
#

So is the problem now in processing the image in GDScript? I'm much less familiar with what might be going wrong there

celest hazel
#

no that part is working, but is irrelevant to the issue. The issue I cant solve is that the shader parameters for filter_colors and palette_size dont assign at all

#

@static quarry if you assign it with just a color array, not a packed array it works

#

bit hard to see maybe over discord, but the first leaves are gray

static quarry
#

That kind of makes sense, actually

celest hazel
#

if you can explain it I would love to hear why cuz I have no clue

static quarry
#

packed vs "normal" arrays? Just that a lot of GDScript stuff is implemented in a kind of straightforward way. If the initial implementation of set_shader_parameter() only considered normal arrays, it makes sense that packed arrays might not be supported. But I haven't looked at the code or anything

#

Like, I'm not surprised when stuff in Godot fails in edge cases, I guess.

celest hazel
#

I guess its my bad assuming the vec4 array in shader language was a packed array