float rand(float seed) {
    return fract(sin(seed) * 43758.5453123);
}

float rand(vec2 seed){
    return fract(sin(dot(seed.xy, vec2(12.9898, 78.233))) * 43758.5453123);
}

float rand(vec3 seed) {
    return fract(sin(dot(seed, vec3(12.9898, 78.233, 45.164))) * 43758.5453123);
}

vec2 rand2(vec3 seed) {
    vec3 dot_product = vec3(dot(seed, vec3(12.9898,78.233,45.164)),
                            dot(seed, vec3(39.346,11.135,83.157)),
                            dot(seed, vec3(73.156,52.235,12.365)));
    return fract(sin(dot_product) * 43758.5453).xy;
}

vec3 rand3(float seed) {
    float scaledSeed = seed / 1000000.0;
    float x = rand(scaledSeed);
    float y = rand(scaledSeed + 1.0);
    float z = rand(scaledSeed + 2.0);
    return vec3(x, y, z);
}

vec3 rand3(vec2 seed) {
    // Generate pseudorandom numbers for x, y, z using slightly varied dot products
    float x = fract(sin(dot(seed, vec2(12.9898, 78.233))) * 43758.5453);
    float y = fract(sin(dot(seed, vec2(39.346, 11.135))) * 43758.5453);
    float z = fract(sin(dot(seed, vec2(73.156, 52.235))) * 43758.5453);

    // Return the random 3D vector
    return vec3(x, y, z);
}

vec3 rand3(vec3 seed) {
    float j = fract(sin(dot(seed, vec3(17.0, 59.4, 15.0))) * 43758.5453);
    return fract(vec3(1.0, 57.0, 113.0) * j);
}

vec4 rand4(vec4 seed) {
    float j = fract(sin(dot(seed, vec4(17.0, 59.4, 15.0, 33.1))) * 43758.5453);
    return fract(vec4(1.0, 57.0, 113.0, 209.0) * j);
}
