Implement 'refract' builtin.
diff --git a/builtin_function.cpp b/builtin_function.cpp
index c75805c..377fd509 100644
--- a/builtin_function.cpp
+++ b/builtin_function.cpp
@@ -1718,6 +1718,111 @@
    "))\n"
 };
 
+static const char *builtins_110_refract = {
+   "((function refract\n"
+   "   (signature float\n"
+   "     (parameters\n"
+   "       (declare (in) float i)\n"
+   "       (declare (in) float n)\n"
+   "       (declare (in) float eta))\n"
+   "     ((declare () float k)\n"
+   "      (assign (constant bool (1)) (var_ref k)\n"
+   "              (expression float - (constant float (1.0))\n"
+   "	        (expression float * (var_ref eta)\n"
+   "	          (expression float * (var_ref eta)\n"
+   "		    (expression float - (constant float (1.0))\n"
+   "		      (expression float * \n"
+   "		        (expression float dot (var_ref n) (var_ref i))\n"
+   "		        (expression float dot (var_ref n) (var_ref i))))))))\n"
+   "      (if (expression bool < (var_ref k) (constant float (0.0)))\n"
+   "          ((return (constant float (0.0))))\n"
+   "	  ((return (expression float -\n"
+   "	             (expression float * (var_ref eta) (var_ref i))\n"
+   "		     (expression float *\n"
+   "		       (expression float +\n"
+   "		         (expression float * (var_ref eta)\n"
+   "			   (expression float dot (var_ref n) (var_ref i)))\n"
+   "		         (expression float sqrt (var_ref k)))\n"
+   "		       (var_ref n))))))))\n"
+   "\n"
+   "   (signature vec2\n"
+   "     (parameters\n"
+   "       (declare (in) vec2 i)\n"
+   "       (declare (in) vec2 n)\n"
+   "       (declare (in) float eta))\n"
+   "     ((declare () float k)\n"
+   "      (assign (constant bool (1)) (var_ref k)\n"
+   "              (expression float - (constant float (1.0))\n"
+   "	        (expression float * (var_ref eta)\n"
+   "	          (expression float * (var_ref eta)\n"
+   "		    (expression float - (constant float (1.0))\n"
+   "		      (expression float * \n"
+   "		        (expression float dot (var_ref n) (var_ref i))\n"
+   "		        (expression float dot (var_ref n) (var_ref i))))))))\n"
+   "      (if (expression bool < (var_ref k) (constant float (0.0)))\n"
+   "          ((return (constant vec2 (0.0 0.0))))\n"
+   "	  ((return (expression vec2 -\n"
+   "	             (expression vec2 * (var_ref eta) (var_ref i))\n"
+   "		     (expression vec2 *\n"
+   "		       (expression float +\n"
+   "		         (expression float * (var_ref eta)\n"
+   "			   (expression float dot (var_ref n) (var_ref i)))\n"
+   "		         (expression float sqrt (var_ref k)))\n"
+   "		       (var_ref n))))))))\n"
+   "\n"
+   "   (signature vec3\n"
+   "     (parameters\n"
+   "       (declare (in) vec3 i)\n"
+   "       (declare (in) vec3 n)\n"
+   "       (declare (in) float eta))\n"
+   "     ((declare () float k)\n"
+   "      (assign (constant bool (1)) (var_ref k)\n"
+   "              (expression float - (constant float (1.0))\n"
+   "	        (expression float * (var_ref eta)\n"
+   "	          (expression float * (var_ref eta)\n"
+   "		    (expression float - (constant float (1.0))\n"
+   "		      (expression float * \n"
+   "		        (expression float dot (var_ref n) (var_ref i))\n"
+   "		        (expression float dot (var_ref n) (var_ref i))))))))\n"
+   "      (if (expression bool < (var_ref k) (constant float (0.0)))\n"
+   "          ((return (constant vec3 (0.0 0.0))))\n"
+   "	  ((return (expression vec3 -\n"
+   "	             (expression vec3 * (var_ref eta) (var_ref i))\n"
+   "		     (expression vec3 *\n"
+   "		       (expression float +\n"
+   "		         (expression float * (var_ref eta)\n"
+   "			   (expression float dot (var_ref n) (var_ref i)))\n"
+   "		         (expression float sqrt (var_ref k)))\n"
+   "		       (var_ref n))))))))\n"
+   "\n"
+   "   (signature vec4\n"
+   "     (parameters\n"
+   "       (declare (in) vec4 i)\n"
+   "       (declare (in) vec4 n)\n"
+   "       (declare (in) float eta))\n"
+   "     ((declare () float k)\n"
+   "      (assign (constant bool (1)) (var_ref k)\n"
+   "              (expression float - (constant float (1.0))\n"
+   "	        (expression float * (var_ref eta)\n"
+   "	          (expression float * (var_ref eta)\n"
+   "		    (expression float - (constant float (1.0))\n"
+   "		      (expression float * \n"
+   "		        (expression float dot (var_ref n) (var_ref i))\n"
+   "		        (expression float dot (var_ref n) (var_ref i))))))))\n"
+   "      (if (expression bool < (var_ref k) (constant float (0.0)))\n"
+   "          ((return (constant vec4 (0.0 0.0))))\n"
+   "	  ((return (expression vec4 -\n"
+   "	             (expression vec4 * (var_ref eta) (var_ref i))\n"
+   "		     (expression vec4 *\n"
+   "		       (expression float +\n"
+   "		         (expression float * (var_ref eta)\n"
+   "			   (expression float dot (var_ref n) (var_ref i)))\n"
+   "		         (expression float sqrt (var_ref k)))\n"
+   "		       (var_ref n))))))))\n"
+   "\n"
+   "))\n"
+};
+
 static const char *builtins_110_sign = {
    "((function sign\n"
    "   (signature float\n"
@@ -2379,6 +2484,7 @@
    builtins_110_pow,
    builtins_110_radians,
    builtins_110_reflect,
+   builtins_110_refract,
    builtins_110_sign,
    builtins_110_sin,
    builtins_110_smoothstep,