mat2x3 getDisplacementMatrix(vec2 coords)
{
    vec2 s = 1.0 / cFieldSize;
    vec2 h = s * 0.5;

    vec3 dXn = texture(sDisplacement, coords + vec2(-h.x, 0.0)).xyz;
    vec3 dXp = texture(sDisplacement, coords + vec2(+h.x, 0.0)).xyz;
    vec3 dYn = texture(sDisplacement, coords + vec2( 0.0,-h.y)).xyz;
    vec3 dYp = texture(sDisplacement, coords + vec2( 0.0,+h.y)).xyz;

    vec3 dX = (dXp - dXn) / s.x;
    vec3 dY = (dYp - dYn) / s.y;

    /*vec3 d = texture(sDisplacement, coords).xyz;
    vec3 dX = (dXp - 2.0 * d + dXn) / s.x;
    vec3 dY = (dYp - 2.0 * d + dYn) / s.y;*/

    return mat2x3(dX, dY);
}

vec3 computeNormal()
{
    mat2x3 Jext = getDisplacementMatrix(vTexCoord);
    mat2 J = mat2(Jext);
    float Jdet = determinant(J);

    const float L = 1.0;

    mat2 Jalt = L * J;
#if 0 //< I don't remember what I was doing here.
    Jalt[0][0] += 1.0;
    Jalt[1][1] += 1.0;
#else
    Jalt[0][0] = 1.0 + L * J[0][0];
    Jalt[1][1] = 1.0 + L * J[1][1];
    Jalt[0][1] = 1.0 + L * J[0][1];
    Jalt[1][0] = Jalt[0][1];
#endif
    float Jdetalt = determinant(Jalt);

    vec3 epsilon = vec3(Jext[0].z, Jext[1].z, 0.0);
    vec3 normal = normalize(vWorldNormal - epsilon);
}