static const char* BumpFragmentShader = STRINGIFY(

varying mediump vec2 TextureCoord;
varying mediump vec3 ObjectSpaceNormal;
varying mediump vec3 ObjectSpaceTangent;

uniform sampler2D Sampler;

void main(void)
{
    // テクスチャから摂動法線ベクトルを取り出す
    highp vec3 tangentSpaceNormal = texture2D(Sampler, TextureCoord).yxz * 2.0 - 1.0;

    // 基底ベクトルの組を生成する
    highp vec3 n = normalize(ObjectSpaceNormal);
    highp vec3 t = normalize(ObjectSpaceTangent);
    highp vec3 b = normalize(cross(n, t));

    // 摂動法線ベクトルを接空間からオブジェクト空間へ変換する
    highp mat3 basis = mat3(n, t, b);
    highp vec3 N = basis * tangentSpaceNormal;
    
    // 法線ベクトルをベクトル空間から色空間へ変換する
    gl_FragColor = vec4((N + 1.0) * 0.5, 1);
}
);
