function vertexShader(compiledExpression) {
return `
precision mediump float;
attribute vec2 a_position;
uniform mat4 projection, view;
uniform mat4 u_viewInverseTranspose;
// A "varying" is a value that we want to export to the fragment shader.
varying vec3 v_color;
varying vec3 v_normal;
${compiledExpression.glsl}
void main() {
vec3 pos = evaluate(a_position);
// calculate normal
vec3 normal = evaluateNormal(a_position, pos);
// Multiply our transformation matrices to set the vertex's position in screen space.
gl_Position = projection * view * vec4(pos, 1.0);
// Export the v_color varying to just be the color that we assigned for this vertex.
v_color = vec3(${compiledExpression.color.map(n => n.toFixed(3))});
v_normal = (mat3(u_viewInverseTranspose) * normal).xyz;
}
`}