float aspect(vec2 v) {
    return v.x / v.y;
}

vec3 indexedTexture(float i) {
    vec2 uv = _position.xy;
    uv += 0.5;
    uv.y = 1.0 - uv.y;
    
    float targetAspect = iWorldScale.x / iWorldScale.y;
    float sourceAspect = 1.0;
    if (i > 3.0) {
        sourceAspect = aspect(iChannelResolution[0].xy);
    } else if (i > 2.0) {
        sourceAspect = aspect(iChannelResolution[1].xy);
    } else if (i > 1.0) {
        sourceAspect = aspect(iChannelResolution[2].xy);
    } else {
        sourceAspect = aspect(iChannelResolution[3].xy);
    }
    float aspectCorrection = sourceAspect / targetAspect;
    if (aspectCorrection > 1.0) {
        float offset = aspectCorrection - 1.0;
        float halfOffset = offset / 2.0;
        uv.y -= halfOffset;
        uv.y *= aspectCorrection;
    } else {
        float offset = 1.0 - aspectCorrection;
        float halfOffset = offset / 2.0;
        uv.x -= halfOffset;
        uv.x /= aspectCorrection;
    }
    
    if (any(lessThan(uv, vec2(0.0)))) {
        return vec3(0.0);
    }

    if (any(greaterThan(uv, vec2(1.0)))) {
        return vec3(0.0);
    }

    

    vec4 color;
    if (i > 3.0) {
        color = texture(iChannel0, uv);
    } else if (i > 2.0) {
        color = texture(iChannel1, uv);
    } else if (i > 1.0) {
        color = texture(iChannel2, uv);
    } else {
        color = texture(iChannel3, uv);
    }
    return color.rgb * max(0.5, sourceAspect) * max(0.9, fract(iWorldPosition.x));
}

float getProceduralColors(inout vec3 diffuse, inout vec3 specular, inout float shininess) {
    if (_position.z > -0.49) {
        discard;
    }

    float t = mod(iGlobalTime / 5.0, 4.0);
    float f = fract(t);
    vec3 color = indexedTexture(6.0); // t
    if (f > 0.9) {
        t = mod(t + 1.0, 4.0);
        vec3 color2 = indexedTexture(t);
        color = mix(color, color2, smoothstep(0.9, 1.0, f));
    }
    specular = color;
    return 1.0;
}