docs: function replaceTHREEShaderAttributes( shaderText, technique ) {
  
  		// Expected technique attributes
  		var attributes = {};
  
  		for ( var attributeId in technique.attributes ) {
  
  			var pname = technique.attributes[ attributeId ];
  
  			var param = technique.parameters[ pname ];
  			var atype = param.type;
  			var semantic = param.semantic;
  
  			attributes[ attributeId ] = {
  				type: atype,
  				semantic: semantic
  			};
  
  		}
  
  		// Figure out which attributes to change in technique
  
  		var shaderParams = technique.parameters;
  		var shaderAttributes = technique.attributes;
  		var params = {};
  
  		for ( var attributeId in attributes ) {
  
  			var pname = shaderAttributes[ attributeId ];
  			var shaderParam = shaderParams[ pname ];
  			var semantic = shaderParam.semantic;
  			if ( semantic ) {
  
  				params[ attributeId ] = shaderParam;
  
  			}
  
  		}
  
  		for ( var pname in params ) {
  
  			var param = params[ pname ];
  			var semantic = param.semantic;
  
  			var regEx = new RegExp( "\\b" + pname + "\\b", "g" );
  
  			switch ( semantic ) {
  
  				case "POSITION":
  
  					shaderText = shaderText.replace( regEx, 'position' );
  					break;
  
  				case "NORMAL":
  
  					shaderText = shaderText.replace( regEx, 'normal' );
  					break;
  
  				case 'TEXCOORD_0':
  				case 'TEXCOORD0':
  				case 'TEXCOORD':
  
  					shaderText = shaderText.replace( regEx, 'uv' );
  					break;
  
  				case 'COLOR_0':
  				case 'COLOR0':
  				case 'COLOR':
  
  					shaderText = shaderText.replace( regEx, 'color' );
  					break;
  
  				case "WEIGHT":
  
  					shaderText = shaderText.replace( regEx, 'skinWeight' );
  					break;
  
  				case "JOINT":
  
  					shaderText = shaderText.replace( regEx, 'skinIndex' );
  					break;
  
  			}
  
  		}
  
  		return shaderText;
  
  	}