Phong Shading

by soulwire

HTML

<script src="https://rawgithub.com/toji/gl-matrix/v2.2.0/dist/gl-matrix.js"></script>
<!doctype html>
<html>
<head>
    <title></title>
    <style> html, body { margin: 0; } </style>
</head>
<body>
    <canvas id="canvas"></canvas>
    <script src="lib/gl-matrix.js"></script>
    <script id="vs" type="x-vert-shader">

    attribute vec3 aVertexPosition;
    attribute vec3 aVertexNormal;

    uniform mat4 uPerspectiveMatrix;
    uniform mat4 uModelViewMatrix;
    uniform mat4 uNormalMatrix;

    varying vec3 vNormal;
    varying vec3 vEye;

    void main() {
        
        vec4 vertex = uModelViewMatrix * vec4( aVertexPosition, 1.0 );
        vNormal = vec3( uNormalMatrix * vec4( aVertexNormal, 1.0 ) );
        vEye = -vec3( vertex.xyz );

        gl_Position = uPerspectiveMatrix * vertex;
    }

    </script>

    <script id="fs" type="x-frag-shader">

    precision mediump float;

    uniform vec3 uLightDirection;
    uniform vec4 uLightSpecular;
    uniform vec4 uLightDiffuse;
    uniform vec4 uLightAmbient;

    uniform vec4 uMaterialSpecular;
    uniform vec4 uMaterialDiffuse;
    uniform vec4 uMaterialAmbient;
    uniform float uShininess;

    varying vec3 vNormal;
    varying vec3 vEye;

    void main() {

        vec3 L = normalize( uLightDirection );
        vec3 N = normalize( vNormal );

        // Compute Lambertian coefficient
        float LC = dot( N, -L );

        // Compute final components
        vec4 ambient = uLightAmbient * uMaterialAmbient;
        vec4 diffuse = vec4( 0, 0, 0, 1 );
        vec4 specular = vec4( 0, 0, 0, 1 );

        // If infront (TODO: explain what positive dot product tells us)
        if ( LC > 0.0 ) {

            diffuse = uLightDiffuse * uMaterialDiffuse * LC;
            vec3 E = normalize( vEye );
            vec3 R = reflect( L, N );
            float S = pow( max( dot( R, E ), 0.0 ), uShininess );
            specular = uLightSpecular * uMaterialSpecular * S;
        }

        specular = vec4(0);
       ...