override protected void _fragmentShader()
        {
            var textureRGB   = (IRegister)assign(TEMP[0], "textureRGB");
            var lightNormal  = (IField)assign(TEMP[1].xyz, "lightNormal");
            var keyValue     = (IComponent)assign(TEMP[2].x, "keyValue");
            var attenuation  = (IComponent)assign(TEMP[2].y, "attenuation");
            var pixelToLight = (IField)assign(TEMP[3].xyz, "pixelToLight");
            var finalLight   = (IRegister)assign(TEMP[4], "finalLight");
            var finalColor   = (IRegister)assign(TEMP[5], "finalColor");

            var lightColor   = (IField)CONST[0].rgb;
            var lightStrenth = (IComponent)CONST[0].w;
            var ambient      = (IField)CONST[1].rgb;
            var zero         = (IComponent)CONST[2].x;
            var third        = (IComponent)CONST[2].y;
            var one          = (IComponent)CONST[2].z;
            var half         = (IComponent)CONST[2].w;

            // Use UV coordinates passed from vertex shader to sample the texture
            sampleTexture(textureRGB, vertexUV, SAMPLER[0], new[] { TextureFlag.TYPE_2D, TextureFlag.MODE_CLAMP, TextureFlag.FILTER_LINEAR });

            //  Calculate the key value - hilight on surfaces that directly face the light source
            normalize(lightNormal, lightPos.xyz);
            dotProduct3(keyValue, vertexNormal, lightNormal);
            add(keyValue, keyValue, third);
            multiply(keyValue, keyValue, lightStrenth);
            max(keyValue, keyValue, zero);

            //  Attenuated diffuse light - the closer to the light a surface is, the stronger this value
            subtract(pixelToLight, vertexPos.xyz, lightPos.xyz);
            dotProduct3(attenuation, pixelToLight, pixelToLight);
            squareRoot(attenuation, attenuation);
            subtract(attenuation, attenuation, lightStrenth);
            subtract(attenuation, attenuation, lightStrenth);
            subtract(attenuation, attenuation, lightStrenth);
            max(attenuation, attenuation, zero);
            reciprocal(attenuation, attenuation);
            multiply(attenuation, attenuation, attenuation);

            // Blend the key and attenuation values with the light color
            add(finalLight, keyValue, attenuation);
            multiply(finalLight, finalLight, lightColor);
            add(finalLight, finalLight, ambient);

            // Finally, blend with the texture sample and output (Try using any of the following blends)
            Blend.hardLight(finalColor, textureRGB, finalLight, one, half, TEMP[1], TEMP[2], TEMP[3]);
            //Blend.softLight(finalColor, finalLight, textureRGB);
            //Blend.pinLight(finalColor, textureRGB, finalLight, one, half, TEMP[1], TEMP[2], TEMP[3]);
            //Blend.glow(finalColor, finalLight, textureRGB, one, TEMP[1]);
            //Blend.grainMerge(finalColor, textureRGB, finalLight, half);
            //Blend.linearLight(finalColor, textureRGB, finalLight, one);
            move(OUTPUT, finalColor.rgb);
        }