                     attribute_asgn += v+"="+a.varname+";\n"
                     @attrib_locs[a.varname] = -1
                 when CD_TANGENT # tangent vectors
-                    attribute_decl += "attribute vec4 tangent;\n"\
+                    attribute_decl += "attribute vec4 "+a.varname+";\n"\
                         +"varying vec4 "+v+";\n"
                     #attribute_asgn += v+".xyz = normalize("\
                         #+var_model_view_matrix+"*vec4("+a.varname+",0.0)).xyz;\n"
-                    attribute_asgn += v+".xyz = normalize(("+var_model_view_matrix+"*vec4(tangent.xyz,0)).xyz);\n"
-                    attribute_asgn += v+".w = tangent.w;\n"
-                    @attrib_locs["tangent"] = -1
-                when 99 # shape key
+                    attribute_asgn += v+".xyz = normalize(("+var_model_view_matrix+"*vec4("+a.varname+".xyz,0)).xyz);\n"
+                    attribute_asgn += v+".w = "+a.varname+".w;\n"
+                    @attrib_locs[a.varname] = -1
+                when CD_SHAPE_KEY # shape key
                     num_shapes = a.count
                     for i in [0...num_shapes]
                         attribute_decl += "attribute vec3 shape"+i+";\n"

                    # holds mesh -> armature transformation and use that in the code above
                    # but add an optimization pass at export to apply mesh transformations
                    # where possible.
                when 86 # armature deform, 6 weights
                    num_bones = a.count
                    @num_bone_uniforms = num_bones
                    attribute_decl += "attribute vec4 weights;\n"

        @alpha = params.alpha

class Material
    # data is an object with:
    # * vertex: string with vertex shader code
    #       (optional, auto generated here for blender materials)
    # * fragment: string with vertex shader code,
    #       or list of strings (concatenated here)
    # * uniforms: list of uniforms, each have this format:
    #   {
    #       varname: name of GLSL variable
    #       type: (optional) supply a GPU_DYNAMIC_* constant
    #             to have it assigned to some scene parameter
    #             Otherwise, mesh.custom_uniform_values will be used instead.
    #       image: If type is GPU_DYNAMIC_SAMPLER_2DIMAGE, put the texture name
    #             here, it must be defined in context.textures
    #   }
    #   Data type of each uniform is inferred from the type or the custom value.
    # * attributes: list of vertex attributes, each have this format:
    #   {
    #       varname: name of GLSL variable
    #       type: one of these:
    #        * CD_MTFACE: Texture UV coordinates, vec2
    #        * CD_MCOL: Vertex color, vec4
    #        * CD_TANGENT: Vertex tangent vector (for normal mapping), vec4
    #        * there are more types but of limited use outside Blender for now
    #   }
    #   There are two implicit vec3 attributes: vertex, vnormal.
    constructor: (@context, data, @scene) ->
        if @context.all_materials.indexOf(@) == -1
            @context.all_materials.push @
