function TextureReader(name, expr, modifs, api) {
    this.expr = expr;
    this.api = api;
    this.modifs = modifs;

    this.evaluateProperties();
    let properties = this.properties;

    this.name = name;
    this.code =
        `uniform sampler2D _sampler${name};
uniform float _ratio${name};
uniform vec2 _cropfact${name};
vec4 _imagergba${name}(vec2 A, vec2 B, vec2 p) {
  p -= A; B -= A;
  float b = dot(B,B);
  p = vec2(dot(p,B),_ratio${name}*dot(p,vec2(-B.y,B.x)))/b;
  ${properties.repeat ? 'p = mod(p, vec2(1.));' : ''}
  ${properties.repeat && properties.mipmap ? 
    `vec4 color = vec4(0.);
    float totalWeight = 0.;
    for(int dx=0; dx<2; dx++) for(int dy=0; dy<2; dy++) {
      vec2 delta = .5*vec2(dx, dy);
      vec2 center = delta+vec2(.5);
      vec2 tc = fract(p-delta)+delta;
      float dst = dot(abs(tc-center),vec2(1.));
      float w = max(.5-dst,0.);
      w=w*w;
      color += w * texture2D(_sampler${name}, tc*_cropfact${name});
      totalWeight += w;
    }
    return color/totalWeight;` : (
      properties.repeat ?
      `return texture2D(_sampler${name}, p*_cropfact${name});` :
      `if(0. <= p.x && p.x <= 1. && 0. <= p.y && p.y <= 1.)
          return texture2D(_sampler${name}, p*_cropfact${name});
       else
          return vec4(0.);`)
  }
  }`;
}
/**
 * @param {string} name the uniform variable that describes the texture
 * @constructor
 */
@param {string} name the uniform variable that describes the texture
@constructor
@param { string } name the uniform variable that describes the texture @constructor
function TextureReader(name, expr, modifs, api) {
    this.expr = expr;
    this.api = api;
    this.modifs = modifs;
    this.evaluateProperties();
    let properties = this.properties;
    this.name = name;
    this.code =
        `uniform sampler2D _sampler${name};
uniform float _ratio${name};
uniform vec2 _cropfact${name};
vec4 _imagergba${name}(vec2 A, vec2 B, vec2 p) {
  p -= A; B -= A;
  float b = dot(B,B);
  p = vec2(dot(p,B),_ratio${name}*dot(p,vec2(-B.y,B.x)))/b;
  ${properties.repeat ? 'p = mod(p, vec2(1.));' : ''}
  ${properties.repeat && properties.mipmap ? 
    `vec4 color = vec4(0.);
    float totalWeight = 0.;
    for(int dx=0; dx<2; dx++) for(int dy=0; dy<2; dy++) {
      vec2 delta = .5*vec2(dx, dy);
      vec2 center = delta+vec2(.5);
      vec2 tc = fract(p-delta)+delta;
      float dst = dot(abs(tc-center),vec2(1.));
      float w = max(.5-dst,0.);
      w=w*w;
      color += w * texture2D(_sampler${name}, tc*_cropfact${name});
      totalWeight += w;
    }
    return color/totalWeight;` : (
      properties.repeat ?
      `return texture2D(_sampler${name}, p*_cropfact${name});` :
      `if(0. <= p.x && p.x <= 1. && 0. <= p.y && p.y <= 1.)
          return texture2D(_sampler${name}, p*_cropfact${name});
       else
          return vec4(0.);`)
  }
  }`;
}
function TextureReader ( name , expr , modifs , api ) { this . expr = expr ; this . api = api ; this . modifs = modifs ; this . evaluateProperties ( ) ; let properties = this . properties ; this . name = name ; this . code = ` ${ name } ${ name } ${ name } ${ name } ${ name } ${ properties . repeat ? 'p = mod(p, vec2(1.));' : '' } ${ properties . repeat && properties . mipmap ? ` ${ name } ${ name } ` : ( properties . repeat ? ` ${ name } ${ name } ` : ` ${ name } ${ name } ` ) } ` ; }
@param {string} name the uniform variable that describes the texture
 @constructor
@param { string } name the uniform variable that describes the texture @constructor