JavaScript
let phong = {
// phong vertex shader
vert :
`
// vertex attributes
attribute highp vec3 aPosition;
attribute highp vec3 aNormal;
attribute highp vec2 aTexCoord;
// uniforms
uniform highp mat4 uModelMatrix;
uniform highp mat4 uViewMatrix;
uniform highp mat4 uProjectionMatrix;
// varyings
varying highp vec3 vMVPosition;
varying highp vec3 vMVNormal;
varying highp vec2 vTexCoord;
void main() {
highp vec4 mvPos = uViewMatrix * uModelMatrix * vec4(aPosition, 1.0);
gl_Position = uProjectionMatrix * mvPos;
vMVPosition = vec3(mvPos) / mvPos.w;
vMVNormal = mat3(uViewMatrix * uModelMatrix) * aNormal;
vTexCoord = aTexCoord;
}
`,
// phong fragment shader
frag :
`
// uniforms
uniform highp mat4 uViewMatrix;
uniform highp vec3 uLightPosition;
uniform highp sampler2D uTextureSampler;
// varyings
varying highp vec3 vMVPosition;
varying highp vec3 vMVNormal;
varying highp vec2 vTexCoord;
void main() {
highp vec4 texelColor = texture2D(uTextureSampler, vTexCoord);
highp vec3 vLight = vec3(uViewMatrix * vec4(uLightPosition, 1.0));
highp vec3 lightDir = normalize(vLight - vMVPosition);
highp vec3 normal = normalize(vMVNormal);
highp float diffuse = max(dot(lightDir, normal), 0.0);
gl_FragColor = vec4(texelColor.rgb * 0.1 + diffuse * texelColor.rgb, texelColor.a);
}
`
};
let cube = {
positions: [
// front face
[ -1/2, -1/2, 1/2 ],
[ 1/2, -1/2, 1/2 ],
[ 1/2, 1/2, 1/2 ],
[ -1/2, 1/2, 1/2 ],
// back face
[ -1/2, -1/2, -1/2 ],
[ -1/2, 1/2, -1/2 ],
[ 1/2, 1/2, -1/2 ],
[ 1/2, -1/2, -1/2 ],
// top face
[ -1/2, 1/2, -1/2 ],
[ -1/2, 1/2, 1/2 ],
[ 1/2, 1/2, 1/2 ],
[ 1/2, 1/2, -1/2 ],
// bottom face
[ -1/2, -1/2, -1/2 ],
[ 1/2, -1/2, -1/2 ],
[ 1/2, -1/2, 1/2 ],
[ -1/2, -1/2, 1/2 ],
// right face
[ 1/2, -1/2, -1/2 ],
[ 1/2, 1/2, -1/2 ],
[ 1/2, 1/2, 1/2 ],
[ 1/2, -1/2, 1/2 ],
// left face
[ -1/2, -1/2, -1/2 ],
[ -1/2,...