Optimization for scene with custom shader

I have a three.js scene made with rogue engine, which im using to make a VR experience.
In that im using a fairly complex shader, it takes world space location of two locators for transitioning between their normal shader and just some color, the transition is using noise for some effect (see video below, its showing the effect of the first locator but the second one is also similar, it goes bottom to top),
the location of the object is passed as Vector 3 uniforms., the shader itself im injecting to a MeshStandardMaterial using onBeforeCompile.

the performance is already bad and really tanks when im using textures, im using three texture sets for the scene, im using diffuse,rough,metal,emission and AO so each is sampled thrice and then masked using vertex colors. (not present in the code below)

 varying vec3 W_Pos; //world position vector
        varying vec3 F_Nrml; //normal vector
        varying vec3 camDir; // cam facing
        varying vec3 vertexColor; 

        uniform vec3 astral_locator; // First locator
        uniform vec3 astral_spread; // i pass the locator's scale here and scale it up for the transition
        uniform vec3 starScatter_starScale_nScale; //three float parameters im passing as vector for easier control in rogue engine
        uniform vec3 breakPoints;
        uniform vec3 c1;
        uniform vec3 c2;
        uniform vec3 c3;
        uniform vec3 noise_locator; //Second locator
        uniform vec3 nStretch_nScale_emSharp;// same as above, three floats passed as a vector
        uniform vec3 emCol;

        vec4 mod289(vec4 x){return x - floor(x * (1.0 / 289.0)) * 289.0;}
        vec4 perm(vec4 x){return mod289(((x * 34.0) + 1.0) * x);}
        vec3 rand2( vec3 p ) {
            return fract(
        float mapping(float number, float inMin, float inMax, float outMin, float outMax){return (number - inMin) * (outMax - outMin) / (inMax - inMin) + outMin;}
        vec4 vertexMask(vec4 map1, vec4 map2, vec4 map3, vec3 vertMask){vec4 me1 = mix(vec4(0.0), map1,vertMask.r); vec4 me2 = mix(me1, map2,vertMask.g); vec4 me3 = mix(me2, map3,vertMask.b); return me3;}
float noise(vec3 p){
    vec3 a = floor(p);
    vec3 d = p - a;
    d = d * d * (3.0 - 2.0 * d);

    vec4 b = a.xxyy + vec4(0.0, 1.0, 0.0, 1.0);
    vec4 k1 = perm(b.xyxy);
    vec4 k2 = perm(k1.xyxy + b.zzww);

    vec4 c = k2 + a.zzzz;
    vec4 k3 = perm(c);
    vec4 k4 = perm(c + 1.0);

    vec4 o1 = fract(k3 * (1.0 / 41.0));
    vec4 o2 = fract(k4 * (1.0 / 41.0));

    vec4 o3 = o2 * d.z + o1 * (1.0 - d.z);
    vec2 o4 = o3.yw * d.x + o3.xz * (1.0 - d.x);

    return o4.y * d.y + o4.x * (1.0 - d.y);
float facing(){
    vec3 nrml = F_Nrml;
    vec3 cam = camDir;
    vec3 normal = normalize(nrml.xyz);
    vec3 eye = normalize(-cam);
    float rim = smoothstep(-0.75, 1.0, 1.0 - dot(normal, eye));
    return clamp(rim, 0.0, 1.0);

//Function for the second locatior
vec2 noiseMove(vec3 loc,vec3 noiseDat){
    float noise_stretch = noiseDat.x;
    float noise_scale = noiseDat.y;
    float emission_sharp = noiseDat.z;
    float noise_move = -loc.y;
    float gen_Pattern;
    float gen_Pattern_invert;
    float emi_sharp_fac;
    float transparency;
    float emission;
    gen_Pattern = ((W_Pos.y+noise_move)*noise_stretch) + noise(W_Pos.xyz*noise_scale);
    gen_Pattern_invert = 1.0 - gen_Pattern;
    emi_sharp_fac =  clamp(emission_sharp*1000.0,1.0,1000.0)*gen_Pattern;
    emission = emission_sharp*gen_Pattern;
    emission = 1.0 - emission;
    emission = emission * emi_sharp_fac;
    emission = clamp(emission,0.0,1.0);
    transparency = clamp(gen_Pattern_invert,0.0,1.0);
    return vec2(emission,transparency);

//Function for the first locator
vec4 astral(vec3 loc, vec3 spr,vec3 cee1,vec3 cee2,vec3 cee3, vec3 breakks, vec3 star){//star is WIP
float f = facing();
float re1 = mapping(f,breakks.x,1.0,0.0,1.0);
float re2 = mapping(f,breakks.y,1.0,0.0,1.0);
float re3 = mapping(f,breakks.z,1.0,0.0,1.0);
vec3 me1 = mix(vec3(0.,0.,0.),cee1,re1);
vec3 me2 = mix(me1,cee2,re2);
vec3 me3 = mix(me2,cee3,re3);

float dist = distance(W_Pos.xyz + (noise(W_Pos.xyz*star.z)-0.5),loc);
float val = step(dist,spr.x);
return vec4(me3,val);

void main(){
  vec4 ast = astral(astral_locator,astral_spread,c1,c2,c3,breakPoints,starScatter_starScale_nScale);
vec2 noice = noiseMove(noise_locator,nStretch_nScale_emSharp);
vec3 outp =  mix(mix(outgoingLight,ast.xyz,ast.w),emCol,noice.x); //Take output light from the three.js shader and mix it with the custom shader
float t = noice.y;
    t = 1.0 - noice.y;
t *= diffuseColor.a;

gl_FragColor = vec4(outp*t,t);

is there a way to optimize it better? a couple things i can think of is storing the noise and then using it instead of calculating every frame, and figuring out occlusion culling (renderpass doesnt work well in VR so cant store the depth pass, gotta figure a way), objects in the scene are already instances to reduce draw calls. im assuming making some objects static might help, including the locators but i dont know if it will stop the uniform from updating every frame.
is there anything else that can be done?

also i apologize for the structure of the question, i rarely post questions thanks to stackoverflow :stuck_out_tongue: