Merge branch 'master' into blender2.8
[blender.git] / source / blender / gpu / shaders / gpu_shader_material.glsl
index 67a099159c5035b1755d0729768aeb16dc128bd3..1f9ab45e556e952abf45538d2292275bc1c145d4 100644 (file)
@@ -1,11 +1,27 @@
+
+uniform mat4 ModelViewMatrix;
+#ifndef EEVEE_ENGINE
+uniform mat4 ProjectionMatrix;
+uniform mat4 ViewMatrixInverse;
+uniform mat4 ViewMatrix;
+#endif
+uniform mat4 ModelMatrix;
+uniform mat4 ModelMatrixInverse;
+uniform mat4 ModelViewMatrixInverse;
+uniform mat4 ProjectionMatrixInverse;
+uniform mat3 NormalMatrix;
+uniform vec4 CameraTexCoFactors;
+
+out vec4 fragColor;
+
 /* Converters */
 
 float convert_rgba_to_float(vec4 color)
 {
 #ifdef USE_NEW_SHADING
-       return color.r * 0.2126 + color.g * 0.7152 + color.b * 0.0722;
+       return dot(color.rgb, vec3(0.2126, 0.7152, 0.0722));
 #else
-       return (color.r + color.g + color.b) / 3.0;
+       return (color.r + color.g + color.b) * 0.333333;
 #endif
 }
 
@@ -53,7 +69,7 @@ void rgb_to_hsv(vec4 rgb, out vec4 outcol)
                h = 0.0;
        }
        else {
-               c = (vec3(cmax, cmax, cmax) - rgb.xyz) / cdelta;
+               c = (vec3(cmax) - rgb.xyz) / cdelta;
 
                if (rgb.x == cmax) h = c[2] - c[1];
                else if (rgb.y == cmax) h = 2.0 + c[0] -  c[2];
@@ -155,15 +171,18 @@ void color_to_blender_normal_new_shading(vec3 color, out vec3 normal)
        normal.y = -2.0 * ((color.g) - 0.5);
        normal.z = -2.0 * ((color.b) - 0.5);
 }
-
+#ifndef M_PI
 #define M_PI 3.14159265358979323846
-#define M_1_PI 0.31830988618379069
+#endif
+#ifndef M_1_PI
+#define M_1_PI 0.318309886183790671538
+#endif
 
 /*********** SHADER NODES ***************/
 
 void vcol_attribute(vec4 attvcol, out vec4 vcol)
 {
-       vcol = vec4(attvcol.x, attvcol.y, attvcol.z, 1.0);
+       vcol = vec4(attvcol.xyz, 1.0);
 }
 
 void uv_attribute(vec2 attuv, out vec3 uv)
@@ -177,7 +196,7 @@ void geom(
         out vec3 normal, out vec4 vcol, out float vcol_alpha, out float frontback)
 {
        local = co;
-       view = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(local) : vec3(0.0, 0.0, -1.0);
+       view = (ProjectionMatrix[3][3] == 0.0) ? normalize(local) : vec3(0.0, 0.0, -1.0);
        global = (viewinvmat * vec4(local, 1.0)).xyz;
        orco = attorco;
        uv_attribute(attuv, uv);
@@ -419,13 +438,13 @@ void squeeze(float val, float width, float center, out float outval)
 void vec_math_add(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
 {
        outvec = v1 + v2;
-       outval = (abs(outvec[0]) + abs(outvec[1]) + abs(outvec[2])) / 3.0;
+       outval = (abs(outvec[0]) + abs(outvec[1]) + abs(outvec[2])) * 0.333333;
 }
 
 void vec_math_sub(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
 {
        outvec = v1 - v2;
-       outval = (abs(outvec[0]) + abs(outvec[1]) + abs(outvec[2])) / 3.0;
+       outval = (abs(outvec[0]) + abs(outvec[1]) + abs(outvec[2])) * 0.333333;
 }
 
 void vec_math_average(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
@@ -441,7 +460,7 @@ void vec_math_mix(float strength, vec3 v1, vec3 v2, out vec3 outvec)
 
 void vec_math_dot(vec3 v1, vec3 v2, out vec3 outvec, out float outval)
 {
-       outvec = vec3(0, 0, 0);
+       outvec = vec3(0);
        outval = dot(v1, v2);
 }
 
@@ -483,9 +502,9 @@ void normal_new_shading(vec3 dir, vec3 nor, out vec3 outnor, out float outdot)
 
 void curves_vec(float fac, vec3 vec, sampler2D curvemap, out vec3 outvec)
 {
-       outvec.x = texture2D(curvemap, vec2((vec.x + 1.0) * 0.5, 0.0)).x;
-       outvec.y = texture2D(curvemap, vec2((vec.y + 1.0) * 0.5, 0.0)).y;
-       outvec.z = texture2D(curvemap, vec2((vec.z + 1.0) * 0.5, 0.0)).z;
+       outvec.x = texture(curvemap, vec2((vec.x + 1.0) * 0.5, 0.0)).x;
+       outvec.y = texture(curvemap, vec2((vec.y + 1.0) * 0.5, 0.0)).y;
+       outvec.z = texture(curvemap, vec2((vec.z + 1.0) * 0.5, 0.0)).z;
 
        if (fac != 1.0)
                outvec = (outvec * fac) + (vec * (1.0 - fac));
@@ -494,9 +513,9 @@ void curves_vec(float fac, vec3 vec, sampler2D curvemap, out vec3 outvec)
 
 void curves_rgb(float fac, vec4 col, sampler2D curvemap, out vec4 outcol)
 {
-       outcol.r = texture2D(curvemap, vec2(texture2D(curvemap, vec2(col.r, 0.0)).a, 0.0)).r;
-       outcol.g = texture2D(curvemap, vec2(texture2D(curvemap, vec2(col.g, 0.0)).a, 0.0)).g;
-       outcol.b = texture2D(curvemap, vec2(texture2D(curvemap, vec2(col.b, 0.0)).a, 0.0)).b;
+       outcol.r = texture(curvemap, vec2(texture(curvemap, vec2(col.r, 0.0)).a, 0.0)).r;
+       outcol.g = texture(curvemap, vec2(texture(curvemap, vec2(col.g, 0.0)).a, 0.0)).g;
+       outcol.b = texture(curvemap, vec2(texture(curvemap, vec2(col.b, 0.0)).a, 0.0)).b;
 
        if (fac != 1.0)
                outcol = (outcol * fac) + (col * (1.0 - fac));
@@ -816,22 +835,23 @@ void mix_linear(float fac, vec4 col1, vec4 col2, out vec4 outcol)
 
 void valtorgb(float fac, sampler2D colormap, out vec4 outcol, out float outalpha)
 {
-       outcol = texture2D(colormap, vec2(fac, 0.0));
+       outcol = texture(colormap, vec2(fac, 0.0));
        outalpha = outcol.a;
 }
 
 void rgbtobw(vec4 color, out float outval)
 {
 #ifdef USE_NEW_SHADING
-       outval = color.r * 0.2126 + color.g * 0.7152 + color.b * 0.0722;
+       vec3 factors = vec3(0.2126, 0.7152, 0.0722);
 #else
-       outval = color.r * 0.35 + color.g * 0.45 + color.b * 0.2; /* keep these factors in sync with texture.h:RGBTOBW */
+       vec3 factors = vec3(0.35, 0.45, 0.2); /* keep these factors in sync with texture.h:RGBTOBW */
 #endif
+       outval = dot(color.rgb, factors);
 }
 
 void invert(float fac, vec4 col, out vec4 outcol)
 {
-       outcol.xyz = mix(col.xyz, vec3(1.0, 1.0, 1.0) - col.xyz, fac);
+       outcol.xyz = mix(col.xyz, vec3(1.0) - col.xyz, fac);
        outcol.w = col.w;
 }
 
@@ -916,12 +936,12 @@ void texture_flip_blend(vec3 vec, out vec3 outvec)
 
 void texture_blend_lin(vec3 vec, out float outval)
 {
-       outval = (1.0 + vec.x) / 2.0;
+       outval = (1.0 + vec.x) * 0.5;
 }
 
 void texture_blend_quad(vec3 vec, out float outval)
 {
-       outval = max((1.0 + vec.x) / 2.0, 0.0);
+       outval = max((1.0 + vec.x) * 0.5, 0.0);
        outval *= outval;
 }
 
@@ -932,12 +952,12 @@ void texture_wood_sin(vec3 vec, out float value, out vec4 color, out vec3 normal
 
        value = wi;
        color = vec4(wi, wi, wi, 1.0);
-       normal = vec3(0.0, 0.0, 0.0);
+       normal = vec3(0.0);
 }
 
 void texture_image(vec3 vec, sampler2D ima, out float value, out vec4 color, out vec3 normal)
 {
-       color = texture2D(ima, (vec.xy + vec2(1.0, 1.0)) * 0.5);
+       color = texture(ima, (vec.xy + vec2(1.0)) * 0.5);
        value = color.a;
 
        normal.x = 2.0 * (color.r - 0.5);
@@ -955,7 +975,7 @@ void texco_orco(vec3 attorco, out vec3 orco)
 void texco_uv(vec2 attuv, out vec3 uv)
 {
        /* disabled for now, works together with leaving out mtex_2d_mapping
-          uv = vec3(attuv*2.0 - vec2(1.0, 1.0), 0.0); */
+          uv = vec3(attuv * 2.0 - vec2(1.0), 0.0); */
        uv = vec3(attuv, 0.0);
 }
 
@@ -1277,11 +1297,7 @@ void mtex_har_divide(float har, out float outhar)
 
 void mtex_har_multiply_clamp(float har, out float outhar)
 {
-       har *= 128.0;
-
-       if (har < 1.0) outhar = 1.0;
-       else if (har > 511.0) outhar = 511.0;
-       else outhar = har;
+       outhar = clamp(har * 128.0, 1.0, 511.0);
 }
 
 void mtex_alpha_from_col(vec4 col, out float alpha)
@@ -1350,14 +1366,14 @@ vec3 mtex_2d_mapping(vec3 vec)
 
 void mtex_cube_map(vec3 co, samplerCube ima, out float value, out vec4 color)
 {
-       color = textureCube(ima, co);
+       color = texture(ima, co);
        value = 1.0;
 }
 
 void mtex_cube_map_refl_from_refldir(
         samplerCube ima, vec3 reflecteddirection, out float value, out vec4 color)
 {
-        color = textureCube(ima, reflecteddirection);
+        color = texture(ima, reflecteddirection);
         value = color.a;
 }
 
@@ -1368,13 +1384,13 @@ void mtex_cube_map_refl(
        vec3 viewdirection = vec3(viewmatrixinverse * vec4(vp, 0.0));
        vec3 normaldirection = normalize(vec3(vec4(vn, 0.0) * viewmatrix));
        vec3 reflecteddirection = reflect(viewdirection, normaldirection);
-       color = textureCube(ima, reflecteddirection);
+       color = texture(ima, reflecteddirection);
        value = 1.0;
 }
 
 void mtex_image(vec3 texco, sampler2D ima, out float value, out vec4 color)
 {
-       color = texture2D(ima, texco.xy);
+       color = texture(ima, texco.xy);
        value = 1.0;
 }
 
@@ -1385,7 +1401,7 @@ void mtex_normal(vec3 texco, sampler2D ima, out vec3 normal)
        // It needs to be done because in Blender
        // the normal used points inward.
        // Should this ever change this negate must be removed.
-       vec4 color = texture2D(ima, texco.xy);
+       vec4 color = texture(ima, texco.xy);
        normal = 2.0 * (vec3(-color.r, color.g, color.b) - vec3(-0.5, 0.5, 0.5));
 }
 
@@ -1413,8 +1429,8 @@ void mtex_bump_init_objspace(
         out float fPrevMagnitude_out, out vec3 vNacc_out,
         out vec3 vR1, out vec3 vR2, out float fDet)
 {
-       mat3 obj2view = to_mat3(gl_ModelViewMatrix);
-       mat3 view2obj = to_mat3(gl_ModelViewMatrixInverse);
+       mat3 obj2view = to_mat3(ModelViewMatrix);
+       mat3 view2obj = to_mat3(ModelViewMatrixInverse);
 
        vec3 vSigmaS = view2obj * dFdx(surf_pos);
        vec3 vSigmaT = view2obj * dFdy(surf_pos);
@@ -1481,9 +1497,9 @@ void mtex_bump_tap3(
        vec2 STul = texco.xy + dFdy(texco.xy);
 
        float Hll, Hlr, Hul;
-       rgbtobw(texture2D(ima, STll), Hll);
-       rgbtobw(texture2D(ima, STlr), Hlr);
-       rgbtobw(texture2D(ima, STul), Hul);
+       rgbtobw(texture(ima, STll), Hll);
+       rgbtobw(texture(ima, STlr), Hlr);
+       rgbtobw(texture(ima, STul), Hul);
 
        dBs = hScale * (Hlr - Hll);
        dBt = hScale * (Hul - Hll);
@@ -1508,10 +1524,10 @@ void mtex_bump_bicubic(
        vec2 STd = texco.xy - 0.5 * TexDy;
        vec2 STu = texco.xy + 0.5 * TexDy;
 
-       rgbtobw(texture2D(ima, STl), Hl);
-       rgbtobw(texture2D(ima, STr), Hr);
-       rgbtobw(texture2D(ima, STd), Hd);
-       rgbtobw(texture2D(ima, STu), Hu);
+       rgbtobw(texture(ima, STl), Hl);
+       rgbtobw(texture(ima, STr), Hr);
+       rgbtobw(texture(ima, STd), Hd);
+       rgbtobw(texture(ima, STu), Hu);
 
        vec2 dHdxy = vec2(Hr - Hl, Hu - Hd);
        float fBlend = clamp(1.0 - textureQueryLOD(ima, texco.xy).x, 0.0, 1.0);
@@ -1597,11 +1613,11 @@ void mtex_bump_tap5(
        vec2 STu = texco.xy + 0.5 * TexDy;
 
        float Hc, Hl, Hr, Hd, Hu;
-       rgbtobw(texture2D(ima, STc), Hc);
-       rgbtobw(texture2D(ima, STl), Hl);
-       rgbtobw(texture2D(ima, STr), Hr);
-       rgbtobw(texture2D(ima, STd), Hd);
-       rgbtobw(texture2D(ima, STu), Hu);
+       rgbtobw(texture(ima, STc), Hc);
+       rgbtobw(texture(ima, STl), Hl);
+       rgbtobw(texture(ima, STr), Hr);
+       rgbtobw(texture(ima, STd), Hd);
+       rgbtobw(texture(ima, STu), Hu);
 
        dBs = hScale * (Hr - Hl);
        dBt = hScale * (Hu - Hd);
@@ -1618,7 +1634,7 @@ void mtex_bump_deriv(
        // this variant using a derivative map is described here
        // http://mmikkelsen3d.blogspot.com/2011/07/derivative-maps.html
        vec2 dim = vec2(ima_x, ima_y);
-       vec2 dBduv = hScale * dim * (2.0 * texture2D(ima, texco.xy).xy - 1.0);
+       vec2 dBduv = hScale * dim * (2.0 * texture(ima, texco.xy).xy - 1.0);
 
        dBs = dBduv.x * TexDx.x + s * dBduv.y * TexDx.y;
        dBt = dBduv.x * TexDy.x + s * dBduv.y * TexDy.y;
@@ -1670,7 +1686,7 @@ void mtex_nspace_world(mat4 viewmat, vec3 texnormal, out vec3 outnormal)
 
 void mtex_nspace_object(vec3 texnormal, out vec3 outnormal)
 {
-       outnormal = normalize(gl_NormalMatrix * texnormal);
+       outnormal = normalize(NormalMatrix * texnormal);
 }
 
 void mtex_blend_normal(float norfac, vec3 normal, vec3 newnormal, out vec3 outnormal)
@@ -1727,7 +1743,7 @@ void lamp_falloff_invcoefficients(float coeff_const, float coeff_lin, float coef
 
 void lamp_falloff_curve(float lampdist, sampler2D curvemap, float dist, out float visifac)
 {
-       visifac = texture2D(curvemap, vec2(dist / lampdist, 0.0)).x;
+       visifac = texture(curvemap, vec2(dist / lampdist, 0.0)).x;
 }
 
 void lamp_visibility_sphere(float lampdist, float dist, float visifac, out float outvisifac)
@@ -1794,7 +1810,7 @@ void lamp_visibility_clamp(float visifac, out float outvisifac)
 void world_paper_view(vec3 vec, out vec3 outvec)
 {
        vec3 nvec = normalize(vec);
-       outvec = (gl_ProjectionMatrix[3][3] == 0.0) ? vec3(nvec.x, 0.0, nvec.y) : vec3(0.0, 0.0, -1.0);
+       outvec = (ProjectionMatrix[3][3] == 0.0) ? vec3(nvec.x, 0.0, nvec.y) : vec3(0.0, 0.0, -1.0);
 }
 
 void world_zen_mapping(vec3 view, float zenup, float zendown, out float zenfac)
@@ -1828,7 +1844,7 @@ void world_blend(vec3 vec, out float blend)
 void shade_view(vec3 co, out vec3 view)
 {
        /* handle perspective/orthographic */
-       view = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(co) : vec3(0.0, 0.0, -1.0);
+       view = (ProjectionMatrix[3][3] == 0.0) ? normalize(co) : vec3(0.0, 0.0, -1.0);
 }
 
 void shade_tangent_v(vec3 lv, vec3 tang, out vec3 vn)
@@ -2020,7 +2036,7 @@ void shade_add_to_diffuse(float i, vec3 lampcol, vec3 col, out vec3 outcol)
        if (i > 0.0)
                outcol = i * lampcol * col;
        else
-               outcol = vec3(0.0, 0.0, 0.0);
+               outcol = vec3(0.0);
 }
 
 void shade_hemi_spec(vec3 vn, vec3 lv, vec3 view, float spec, float hard, float visifac, out float t)
@@ -2177,12 +2193,12 @@ void shade_madd(vec4 col, vec4 col1, vec4 col2, out vec4 outcol)
 
 void shade_add_clamped(vec4 col1, vec4 col2, out vec4 outcol)
 {
-       outcol = col1 + max(col2, vec4(0.0, 0.0, 0.0, 0.0));
+       outcol = col1 + max(col2, vec4(0.0));
 }
 
 void shade_madd_clamped(vec4 col, vec4 col1, vec4 col2, out vec4 outcol)
 {
-       outcol = col + max(col1 * col2, vec4(0.0, 0.0, 0.0, 0.0));
+       outcol = col + max(col1 * col2, vec4(0.0));
 }
 
 void env_apply(vec4 col, vec3 hor, vec3 zen, vec4 f, mat4 vm, vec3 vn, out vec4 outcol)
@@ -2219,7 +2235,7 @@ void shade_obcolor(vec4 col, vec4 obcol, out vec4 outcol)
 
 void ramp_rgbtobw(vec3 color, out float outval)
 {
-       outval = color.r * 0.3 + color.g * 0.58 + color.b * 0.12;
+       outval = dot(color, vec3(0.3, 0.58, 0.12));
 }
 
 void shade_only_shadow(float i, float shadfac, float energy, vec3 shadcol, out vec3 outshadrgb)
@@ -2255,10 +2271,12 @@ void test_shadowbuf(
                //float bias = (1.5 - inp*inp)*shadowbias;
                co.z -= shadowbias * co.w;
 
-               if (co.w > 0.0 && co.x > 0.0 && co.x / co.w < 1.0 && co.y > 0.0 && co.y / co.w < 1.0)
-                       result = shadow2DProj(shadowmap, co).x;
-               else
+               if (co.w > 0.0 && co.x > 0.0 && co.x / co.w < 1.0 && co.y > 0.0 && co.y / co.w < 1.0) {
+                       result = textureProj(shadowmap, co);
+               }
+               else {
                        result = 1.0;
+               }
        }
 }
 
@@ -2272,7 +2290,7 @@ void test_shadowbuf_vsm(
        else {
                vec4 co = shadowpersmat * vec4(rco, 1.0);
                if (co.w > 0.0 && co.x > 0.0 && co.x / co.w < 1.0 && co.y > 0.0 && co.y / co.w < 1.0) {
-                       vec2 moments = texture2DProj(shadowmap, co).rg;
+                       vec2 moments = textureProj(shadowmap, co).rg;
                        float dist = co.z / co.w;
                        float p = 0.0;
 
@@ -2331,7 +2349,7 @@ void shade_light_texture(vec3 rco, sampler2D cookie, mat4 shadowpersmat, out vec
 
        vec4 co = shadowpersmat * vec4(rco, 1.0);
 
-       result = texture2DProj(cookie, co);
+       result = textureProj(cookie, co);
 }
 
 void shade_exposure_correct(vec3 col, float linfac, float logfac, out vec3 outcol)
@@ -2346,7 +2364,7 @@ void shade_mist_factor(
        if (enable == 1.0) {
                float fac, zcor;
 
-               zcor = (gl_ProjectionMatrix[3][3] == 0.0) ? length(co) : -co[2];
+               zcor = (ProjectionMatrix[3][3] == 0.0) ? length(co) : -co[2];
 
                fac = clamp((zcor - miststa) / mistdist, 0.0, 1.0);
                if (misttype == 0.0) fac *= fac;
@@ -2421,7 +2439,7 @@ float hypot(float x, float y)
 
 void generated_from_orco(vec3 orco, out vec3 generated)
 {
-       generated = orco * 0.5 + vec3(0.5);
+       generated = orco;
 }
 
 int floor_to_int(float x)
@@ -2434,7 +2452,6 @@ int quick_floor(float x)
        return int(x) - ((x < 0) ? 1 : 0);
 }
 
-#ifdef BIT_OPERATIONS
 float integer_noise(int n)
 {
        int nn;
@@ -2499,7 +2516,6 @@ vec3 cellnoise_color(vec3 p)
 
        return vec3(r, g, b);
 }
-#endif  // BIT_OPERATIONS
 
 float floorfrac(float x, out int i)
 {
@@ -2557,11 +2573,56 @@ vec3 rotate_vector(vec3 p, vec3 n, float theta) {
               );
 }
 
+void prepare_tangent(
+        float anisotropic, float anisotropic_rotation, float roughness, vec3 N, vec3 T,
+        out vec3 X, out vec3 Y, out float ax, out float ay)
+{
+       /* rotate tangent */
+       if (anisotropic_rotation != 0.0) {
+               T = rotate_vector(T, N, anisotropic_rotation * 2.0 * M_PI);
+       }
+
+       Y = normalize(cross(T, N));
+
+       float aspect = sqrt(1.0 - anisotropic * 0.9);
+       float a = sqr(roughness);
+       ax = max(0.001, a / aspect);
+       ay = max(0.001, a * aspect);
+}
+
+void convert_metallic_to_specular(vec3 basecol, float metallic, float specular_fac, out vec3 diffuse, out vec3 f0)
+{
+       vec3 dielectric = vec3(0.034) * specular_fac * 2.0;
+       diffuse = mix(basecol, vec3(0.0), metallic);
+       f0 = mix(dielectric, basecol, metallic);
+}
+
+void convert_metallic_to_specular_tinted(
+        vec3 basecol, float metallic, float specular_fac, float specular_tint,
+        out vec3 diffuse, out vec3 f0)
+{
+       vec3 dielectric = vec3(0.034) * specular_fac * 2.0;
+       float lum = dot(basecol, vec3(0.3, 0.6, 0.1)); /* luminance approx. */
+       vec3 tint = lum > 0 ? basecol / lum : vec3(1.0); /* normalize lum. to isolate hue+sat */
+       f0 = mix(dielectric * mix(vec3(1.0), tint, specular_tint), basecol, metallic);
+       diffuse = mix(basecol, vec3(0.0), metallic);
+}
 
 /*********** NEW SHADER NODES ***************/
 
 #define NUM_LIGHTS 3
 
+struct glLight {
+       vec4 position;
+       vec4 diffuse;
+       vec4 specular;
+       vec4 halfVector;
+};
+
+layout(std140) uniform lightSource {
+       glLight glLightSource[NUM_LIGHTS];
+};
+
 /* bsdfs */
 
 void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out vec4 result)
@@ -2571,8 +2632,8 @@ void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out vec4 result)
 
        /* directional lights */
        for (int i = 0; i < NUM_LIGHTS; i++) {
-               vec3 light_position = gl_LightSource[i].position.xyz;
-               vec3 light_diffuse = gl_LightSource[i].diffuse.rgb;
+               vec3 light_position = glLightSource[i].position.xyz;
+               vec3 light_diffuse = glLightSource[i].diffuse.rgb;
 
                float bsdf = max(dot(N, light_position), 0.0);
                L += light_diffuse * bsdf;
@@ -2588,10 +2649,10 @@ void node_bsdf_glossy(vec4 color, float roughness, vec3 N, out vec4 result)
 
        /* directional lights */
        for (int i = 0; i < NUM_LIGHTS; i++) {
-               vec3 light_position = gl_LightSource[i].position.xyz;
-               vec3 H = gl_LightSource[i].halfVector.xyz;
-               vec3 light_diffuse = gl_LightSource[i].diffuse.rgb;
-               vec3 light_specular = gl_LightSource[i].specular.rgb;
+               vec3 light_position = glLightSource[i].position.xyz;
+               vec3 H = glLightSource[i].halfVector.xyz;
+               vec3 light_diffuse = glLightSource[i].diffuse.rgb;
+               vec3 light_specular = glLightSource[i].specular.rgb;
 
                /* we mix in some diffuse so low roughness still shows up */
                float bsdf = 0.5 * pow(max(dot(N, H), 0.0), 1.0 / roughness);
@@ -2623,6 +2684,10 @@ void node_bsdf_principled(vec4 base_color, float subsurface, vec3 subsurface_rad
        float specular_tint, float roughness, float anisotropic, float anisotropic_rotation, float sheen, float sheen_tint, float clearcoat,
        float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, out vec4 result)
 {
+       vec3 X, Y;
+       float ax, ay;
+       prepare_tangent(anisotropic, anisotropic_rotation, roughness, N, T, X, Y, ax, ay);
+
        /* ambient light */
        // TODO: set ambient light to an appropriate value
        vec3 L = mix(0.1, 0.03, metallic) * mix(base_color.rgb, subsurface_color.rgb, subsurface * (1.0 - metallic));
@@ -2630,31 +2695,7 @@ void node_bsdf_principled(vec4 base_color, float subsurface, vec3 subsurface_rad
        float eta = (2.0 / (1.0 - sqrt(0.08 * specular))) - 1.0;
 
        /* set the viewing vector */
-       vec3 V = (gl_ProjectionMatrix[3][3] == 0.0) ? -normalize(I) : vec3(0.0, 0.0, 1.0);
-
-       /* get the tangent */
-       vec3 Tangent = T;
-       if (T == vec3(0.0)) {
-               // if no tangent is set, use a default tangent
-               Tangent = vec3(1.0, 0.0, 0.0);
-               if (N.x != 0.0 || N.y != 0.0) {
-                       vec3 N_xz = normalize(vec3(N.x, 0.0, N.z));
-
-                       vec3 axis = normalize(cross(vec3(0.0, 0.0, 1.0), N_xz));
-                       float angle = acos(dot(vec3(0.0, 0.0, 1.0), N_xz));
-
-                       Tangent = normalize(rotate_vector(vec3(1.0, 0.0, 0.0), axis, angle));
-               }
-       }
-
-       /* rotate tangent */
-       if (anisotropic_rotation != 0.0) {
-               Tangent = rotate_vector(Tangent, N, anisotropic_rotation * 2.0 * M_PI);
-       }
-
-       /* calculate the tangent and bitangent */
-       vec3 Y = normalize(cross(N, Tangent));
-       vec3 X = cross(Y, N);
+       vec3 V = (ProjectionMatrix[3][3] == 0.0) ? -normalize(I) : vec3(0.0, 0.0, 1.0);
 
        /* fresnel normalization parameters */
        float F0 = fresnel_dielectric_0(eta);
@@ -2662,13 +2703,13 @@ void node_bsdf_principled(vec4 base_color, float subsurface, vec3 subsurface_rad
 
        /* directional lights */
        for (int i = 0; i < NUM_LIGHTS; i++) {
-               vec3 light_position_world = gl_LightSource[i].position.xyz;
+               vec3 light_position_world = glLightSource[i].position.xyz;
                vec3 light_position = normalize(light_position_world);
 
                vec3 H = normalize(light_position + V);
 
-               vec3 light_diffuse = gl_LightSource[i].diffuse.rgb;
-               vec3 light_specular = gl_LightSource[i].specular.rgb;
+               vec3 light_diffuse = glLightSource[i].diffuse.rgb;
+               vec3 light_specular = glLightSource[i].specular.rgb;
 
                float NdotL = dot(N, light_position);
                float NdotV = dot(N, V);
@@ -2678,7 +2719,7 @@ void node_bsdf_principled(vec4 base_color, float subsurface, vec3 subsurface_rad
                if (NdotL >= 0.0 && NdotV >= 0.0) {
                        float NdotH = dot(N, H);
 
-                       float Cdlum = 0.3 * base_color.r + 0.6 * base_color.g + 0.1 * base_color.b; // luminance approx.
+                       float Cdlum = dot(base_color.rgb, vec3(0.3, 0.6, 0.1)); // luminance approx.
 
                        vec3 Ctint = Cdlum > 0 ? base_color.rgb / Cdlum : vec3(1.0); // normalize lum. to isolate hue+sat
                        vec3 Cspec0 = mix(specular * 0.08 * mix(vec3(1.0), Ctint, specular_tint), base_color.rgb, metallic);
@@ -2699,10 +2740,6 @@ void node_bsdf_principled(vec4 base_color, float subsurface, vec3 subsurface_rad
                        float ss = 1.25 * (Fss * (1.0 / (NdotL + NdotV) - 0.5) + 0.5);
 
                        // specular
-                       float aspect = sqrt(1.0 - anisotropic * 0.9);
-                       float a = sqr(roughness);
-                       float ax = max(0.001, a / aspect);
-                       float ay = max(0.001, a * aspect);
                        float Ds = GTR2_aniso(NdotH, dot(H, X), dot(H, Y), ax, ay); //GTR2(NdotH, a);
                        float FH = (fresnel_dielectric_cos(LdotH, eta) - F0) * F0_norm;
                        vec3 Fs = mix(Cspec0, vec3(1.0), FH);
@@ -2741,6 +2778,65 @@ void node_bsdf_principled(vec4 base_color, float subsurface, vec3 subsurface_rad
        result = vec4(L, 1.0);
 }
 
+void node_bsdf_principled_simple(vec4 base_color, float subsurface, vec3 subsurface_radius, vec4 subsurface_color, float metallic, float specular,
+       float specular_tint, float roughness, float anisotropic, float anisotropic_rotation, float sheen, float sheen_tint, float clearcoat,
+       float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, out vec4 result)
+{
+#ifdef EEVEE_ENGINE
+       vec3 diffuse, f0;
+       convert_metallic_to_specular_tinted(base_color.rgb, metallic, specular, specular_tint, diffuse, f0);
+
+       result = vec4(eevee_surface_lit(N, diffuse, f0, roughness, 1.0), 1.0);
+#else
+       node_bsdf_principled(base_color, subsurface, subsurface_radius, subsurface_color, metallic, specular,
+               specular_tint, roughness, anisotropic, anisotropic_rotation, sheen, sheen_tint, clearcoat,
+               clearcoat_roughness, ior, transmission, transmission_roughness, N, CN, T, I, result);
+#endif
+}
+
+void node_bsdf_principled_clearcoat(vec4 base_color, float subsurface, vec3 subsurface_radius, vec4 subsurface_color, float metallic, float specular,
+       float specular_tint, float roughness, float anisotropic, float anisotropic_rotation, float sheen, float sheen_tint, float clearcoat,
+       float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, out vec4 result)
+{
+#ifdef EEVEE_ENGINE
+       vec3 diffuse, f0;
+       convert_metallic_to_specular_tinted(base_color.rgb, metallic, specular, specular_tint, diffuse, f0);
+
+       clearcoat *= 0.25;
+#if 0 /* Wait until temporal AA (aka. denoising) */
+
+       vec3 X, Y;
+       float ax, ay;
+       prepare_tangent(anisotropic, anisotropic_rotation, roughness, N, T, X, Y, ax, ay);
+
+       /* Distribute N in anisotropy direction. */
+       vec4 surface_color = vec4(0.0);
+       for (float i = 0.0; i < 5.0; ++i) {
+               vec4 rand = texture(utilTex, vec3((gl_FragCoord.xy + i) / LUT_SIZE, 2.0));
+
+               float tmp = sqrt( rand.x / (1.0 - rand.x) );
+               float x = (ax > ay ? ax : 0.0) * tmp * rand.z;
+               float y = (ay > ax ? ay : 0.0) * tmp * rand.w;
+               vec3 Ht = normalize(vec3(x, y, 1.0));
+               N = tangent_to_world(Ht, N, Y, X);
+
+               if (dot(N, cameraVec) > 0) {
+                       surface_color.rgb += eevee_surface_clearcoat_lit(N, diffuse, f0, sqrt(min(ax, ay)), CN, clearcoat, clearcoat_roughness, 1.0);
+                       surface_color.a += 1.0;
+               }
+       }
+       result = vec4(surface_color.rgb / surface_color.a, 1.0);
+#else
+       result = vec4(eevee_surface_clearcoat_lit(N, diffuse, f0, roughness, CN, clearcoat, clearcoat_roughness, 1.0), 1.0);
+#endif
+
+#else
+       node_bsdf_principled(base_color, subsurface, subsurface_radius, subsurface_color, metallic, specular,
+               specular_tint, roughness, anisotropic, anisotropic_rotation, sheen, sheen_tint, clearcoat,
+               clearcoat_roughness, ior, transmission, transmission_roughness, N, CN, T, I, result);
+#endif
+}
+
 void node_bsdf_translucent(vec4 color, vec3 N, out vec4 result)
 {
        node_bsdf_diffuse(color, 0.0, N, result);
@@ -2793,14 +2889,18 @@ void node_emission(vec4 color, float strength, vec3 N, out vec4 result)
 
 void background_transform_to_world(vec3 viewvec, out vec3 worldvec)
 {
-       vec4 v = (gl_ProjectionMatrix[3][3] == 0.0) ? vec4(viewvec, 1.0) : vec4(0.0, 0.0, 1.0, 1.0);
-       vec4 co_homogenous = (gl_ProjectionMatrixInverse * v);
+       vec4 v = (ProjectionMatrix[3][3] == 0.0) ? vec4(viewvec, 1.0) : vec4(0.0, 0.0, 1.0, 1.0);
+       vec4 co_homogenous = (ProjectionMatrixInverse * v);
 
        vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0);
-       worldvec = (gl_ModelViewMatrixInverse * co).xyz;
+#if defined(WORLD_BACKGROUND) || defined(PROBE_CAPTURE)
+       worldvec = (ViewMatrixInverse * co).xyz;
+#else
+       worldvec = (ModelViewMatrixInverse * co).xyz;
+#endif
 }
 
-void node_background(vec4 color, float strength, vec3 N, out vec4 result)
+void node_background(vec4 color, float strength, out vec4 result)
 {
        result = color * strength;
 }
@@ -2822,7 +2922,7 @@ void node_add_shader(vec4 shader1, vec4 shader2, out vec4 shader)
 void node_fresnel(float ior, vec3 N, vec3 I, out float result)
 {
        /* handle perspective/orthographic */
-       vec3 I_view = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
+       vec3 I_view = (ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
 
        float eta = max(ior, 0.00001);
        result = fresnel_dielectric(I_view, N, (gl_FrontFacing) ? eta : 1.0 / eta);
@@ -2834,7 +2934,7 @@ void node_layer_weight(float blend, vec3 N, vec3 I, out float fresnel, out float
 {
        /* fresnel */
        float eta = max(1.0 - blend, 0.00001);
-       vec3 I_view = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
+       vec3 I_view = (ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
 
        fresnel = fresnel_dielectric(I_view, N, (gl_FrontFacing) ? 1.0 / eta : eta);
 
@@ -2876,19 +2976,47 @@ void node_uvmap(vec3 attr_uv, out vec3 outvec)
        outvec = attr_uv;
 }
 
+void tangent_orco_x(vec3 orco_in, out vec3 orco_out)
+{
+       orco_out = orco_in.xzy * vec3(0.0, -0.25, 0.25);
+}
+
+void tangent_orco_y(vec3 orco_in, out vec3 orco_out)
+{
+       orco_out = orco_in.zyx * vec3(-0.25, 0.0, 0.25);
+}
+
+void tangent_orco_z(vec3 orco_in, out vec3 orco_out)
+{
+       orco_out = orco_in.yxz * vec3(-0.25, 0.25, 0.0);
+}
+
+void node_tangentmap(vec4 attr_tangent, mat4 toworld, out vec3 tangent)
+{
+       tangent = (toworld * vec4(attr_tangent.xyz, 0.0)).xyz;
+}
+
+void node_tangent(vec3 N, vec3 orco, mat4 objmat, mat4 toworld, out vec3 T)
+{
+       N = (toworld * vec4(N, 0.0)).xyz;
+       T = (objmat * vec4(orco, 0.0)).xyz;
+       T = cross(N, normalize(cross(T, N)));
+}
+
 void node_geometry(
-        vec3 I, vec3 N, mat4 toworld,
+        vec3 I, vec3 N, vec3 orco, mat4 objmat, mat4 toworld,
         out vec3 position, out vec3 normal, out vec3 tangent,
         out vec3 true_normal, out vec3 incoming, out vec3 parametric,
         out float backfacing, out float pointiness)
 {
        position = (toworld * vec4(I, 1.0)).xyz;
        normal = (toworld * vec4(N, 0.0)).xyz;
-       tangent = vec3(0.0);
+       tangent_orco_z(orco, orco);
+       node_tangent(N, orco, objmat, toworld, tangent);
        true_normal = normal;
 
        /* handle perspective/orthographic */
-       vec3 I_view = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
+       vec3 I_view = (ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
        incoming = -(toworld * vec4(I_view, 0.0)).xyz;
 
        parametric = vec3(0.0);
@@ -2902,12 +3030,12 @@ void node_tex_coord(
         out vec3 generated, out vec3 normal, out vec3 uv, out vec3 object,
         out vec3 camera, out vec3 window, out vec3 reflection)
 {
-       generated = attr_orco * 0.5 + vec3(0.5);
+       generated = attr_orco * 0.5 + 0.5;
        normal = normalize((obinvmat * (viewinvmat * vec4(N, 0.0))).xyz);
        uv = attr_uv;
        object = (obinvmat * (viewinvmat * vec4(I, 1.0))).xyz;
        camera = vec3(I.xy, -I.z);
-       vec4 projvec = gl_ProjectionMatrix * vec4(I, 1.0);
+       vec4 projvec = ProjectionMatrix * vec4(I, 1.0);
        window = vec3(mtex_2d_mapping(projvec.xyz / projvec.w).xy * camerafac.xy + camerafac.zw, 0.0);
 
        vec3 shade_I;
@@ -2922,13 +3050,18 @@ void node_tex_coord_background(
         out vec3 generated, out vec3 normal, out vec3 uv, out vec3 object,
         out vec3 camera, out vec3 window, out vec3 reflection)
 {
-       vec4 v = (gl_ProjectionMatrix[3][3] == 0.0) ? vec4(I, 1.0) : vec4(0.0, 0.0, 1.0, 1.0);
-       vec4 co_homogenous = (gl_ProjectionMatrixInverse * v);
+       vec4 v = (ProjectionMatrix[3][3] == 0.0) ? vec4(I, 1.0) : vec4(0.0, 0.0, 1.0, 1.0);
+       vec4 co_homogenous = (ProjectionMatrixInverse * v);
 
        vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0);
 
        co = normalize(co);
-       vec3 coords = (gl_ModelViewMatrixInverse * co).xyz;
+
+#if defined(WORLD_BACKGROUND) || defined(PROBE_CAPTURE)
+       vec3 coords = (ViewMatrixInverse * co).xyz;
+#else
+       vec3 coords = (ModelViewMatrixInverse * co).xyz;
+#endif
 
        generated = coords;
        normal = -coords;
@@ -2936,13 +3069,17 @@ void node_tex_coord_background(
        object = coords;
 
        camera = vec3(co.xy, -co.z);
-       window = (gl_ProjectionMatrix[3][3] == 0.0) ?
+       window = (ProjectionMatrix[3][3] == 0.0) ?
                 vec3(mtex_2d_mapping(I).xy * camerafac.xy + camerafac.zw, 0.0) :
                 vec3(vec2(0.5) * camerafac.xy + camerafac.zw, 0.0);
 
        reflection = -coords;
 }
 
+#if defined(WORLD_BACKGROUND) || (defined(PROBE_CAPTURE) && !defined(MESH_SHADER))
+#define node_tex_coord node_tex_coord_background
+#endif
+
 /* textures */
 
 float calc_gradient(vec3 p, int gradient_type)
@@ -3009,7 +3146,6 @@ void node_tex_checker(vec3 co, vec4 color1, vec4 color2, float scale, out vec4 c
        fac = check ? 1.0 : 0.0;
 }
 
-#ifdef BIT_OPERATIONS
 vec2 calc_brick_texture(vec3 p, float mortar_size, float mortar_smooth, float bias,
                         float brick_width, float row_height,
                         float offset_amount, int offset_frequency,
@@ -3045,7 +3181,6 @@ vec2 calc_brick_texture(vec3 p, float mortar_size, float mortar_smooth, float bi
                return vec2(tint, smoothstep(0.0, mortar_smooth, min_dist));
        }
 }
-#endif
 
 void node_tex_brick(vec3 co,
                     vec4 color1, vec4 color2,
@@ -3056,7 +3191,6 @@ void node_tex_brick(vec3 co,
                     float squash_amount, float squash_frequency,
                     out vec4 color, out float fac)
 {
-#ifdef BIT_OPERATIONS
        vec2 f2 = calc_brick_texture(co * scale,
                                     mortar_size, mortar_smooth, bias,
                                     brick_width, row_height,
@@ -3070,10 +3204,6 @@ void node_tex_brick(vec3 co,
        }
        color = mix(color1, mortar, f);
        fac = f;
-#else
-       color = vec4(1.0);
-       fac = 1.0;
-#endif
 }
 
 void node_tex_clouds(vec3 co, float size, out vec4 color, out float fac)
@@ -3088,7 +3218,15 @@ void node_tex_environment_equirectangular(vec3 co, sampler2D ima, out vec4 color
        float u = -atan(nco.y, nco.x) / (2.0 * M_PI) + 0.5;
        float v = atan(nco.z, hypot(nco.x, nco.y)) / M_PI + 0.5;
 
-       color = texture2D(ima, vec2(u, v));
+       /* Fix pole bleeding */
+       float half_width = 0.5 / float(textureSize(ima, 0).x);
+       v = clamp(v, half_width, 1.0 - half_width);
+
+       /* Fix u = 0 seam */
+       /* This is caused by texture filtering, since uv don't have smooth derivatives
+        * at u = 0 or 2PI, hardware filtering is using the smallest mipmap for certain
+        * texels. So we force the highest mipmap and don't do anisotropic filtering. */
+       color = textureLod(ima, vec2(u, v), 0.0);
 }
 
 void node_tex_environment_mirror_ball(vec3 co, sampler2D ima, out vec4 color)
@@ -3104,7 +3242,7 @@ void node_tex_environment_mirror_ball(vec3 co, sampler2D ima, out vec4 color)
        float u = 0.5 * (nco.x + 1.0);
        float v = 0.5 * (nco.z + 1.0);
 
-       color = texture2D(ima, vec2(u, v));
+       color = texture(ima, vec2(u, v));
 }
 
 void node_tex_environment_empty(vec3 co, out vec4 color)
@@ -3114,7 +3252,7 @@ void node_tex_environment_empty(vec3 co, out vec4 color)
 
 void node_tex_image(vec3 co, sampler2D ima, out vec4 color, out float alpha)
 {
-       color = texture2D(ima, co.xy);
+       color = texture(ima, co.xy);
        alpha = color.a;
 }
 
@@ -3182,13 +3320,13 @@ void node_tex_image_box(vec3 texco,
        }
        color = vec4(0);
        if (weight.x > 0.0) {
-               color += weight.x * texture2D(ima, texco.yz);
+               color += weight.x * texture(ima, texco.yz);
        }
        if (weight.y > 0.0) {
-               color += weight.y * texture2D(ima, texco.xz);
+               color += weight.y * texture(ima, texco.xz);
        }
        if (weight.z > 0.0) {
-               color += weight.z * texture2D(ima, texco.yx);
+               color += weight.z * texture(ima, texco.yx);
        }
 
        alpha = color.a;
@@ -3261,7 +3399,6 @@ void node_tex_magic(vec3 co, float scale, float distortion, float depth, out vec
        fac = (color.x + color.y + color.z) / 3.0;
 }
 
-#ifdef BIT_OPERATIONS
 float noise_fade(float t)
 {
        return t * t * t * (t * (t * 6.0 - 15.0) + 10.0);
@@ -3324,10 +3461,9 @@ float noise_turbulence(vec3 p, float octaves, int hard)
        float fscale = 1.0;
        float amp = 1.0;
        float sum = 0.0;
-       int i, n;
        octaves = clamp(octaves, 0.0, 16.0);
-       n = int(octaves);
-       for (i = 0; i <= n; i++) {
+       int n = int(octaves);
+       for (int i = 0; i <= n; i++) {
                float t = noise(fscale * p);
                if (hard != 0) {
                        t = abs(2.0 * t - 1.0);
@@ -3337,7 +3473,7 @@ float noise_turbulence(vec3 p, float octaves, int hard)
                fscale *= 2.0;
        }
        float rmd = octaves - floor(octaves);
-       if  (rmd != 0.0) {
+       if (rmd != 0.0) {
                float t = noise(fscale * p);
                if (hard != 0) {
                        t = abs(2.0 * t - 1.0);
@@ -3352,11 +3488,9 @@ float noise_turbulence(vec3 p, float octaves, int hard)
                return sum;
        }
 }
-#endif  // BIT_OPERATIONS
 
 void node_tex_noise(vec3 co, float scale, float detail, float distortion, out vec4 color, out float fac)
 {
-#ifdef BIT_OPERATIONS
        vec3 p = co * scale;
        int hard = 0;
        if (distortion != 0.0) {
@@ -3372,15 +3506,8 @@ void node_tex_noise(vec3 co, float scale, float detail, float distortion, out ve
                     noise_turbulence(vec3(p.y, p.x, p.z), detail, hard),
                     noise_turbulence(vec3(p.y, p.z, p.x), detail, hard),
                     1);
-#else  // BIT_OPERATIONS
-       color = vec4(1.0);
-       fac = 1.0;
-#endif  // BIT_OPERATIONS
 }
 
-
-#ifdef BIT_OPERATIONS
-
 /* Musgrave fBm
  *
  * H: fractal increment parameter
@@ -3396,9 +3523,8 @@ float noise_musgrave_fBm(vec3 p, float H, float lacunarity, float octaves)
        float value = 0.0;
        float pwr = 1.0;
        float pwHL = pow(lacunarity, -H);
-       int i;
 
-       for (i = 0; i < int(octaves); i++) {
+       for (int i = 0; i < int(octaves); i++) {
                value += snoise(p) * pwr;
                pwr *= pwHL;
                p *= lacunarity;
@@ -3424,9 +3550,8 @@ float noise_musgrave_multi_fractal(vec3 p, float H, float lacunarity, float octa
        float value = 1.0;
        float pwr = 1.0;
        float pwHL = pow(lacunarity, -H);
-       int i;
 
-       for (i = 0; i < int(octaves); i++) {
+       for (int i = 0; i < int(octaves); i++) {
                value *= (pwr * snoise(p) + 1.0);
                pwr *= pwHL;
                p *= lacunarity;
@@ -3452,13 +3577,12 @@ float noise_musgrave_hetero_terrain(vec3 p, float H, float lacunarity, float oct
        float value, increment, rmd;
        float pwHL = pow(lacunarity, -H);
        float pwr = pwHL;
-       int i;
 
        /* first unscaled octave of function; later octaves are scaled */
        value = offset + snoise(p);
        p *= lacunarity;
 
-       for (i = 1; i < int(octaves); i++) {
+       for (int i = 1; i < int(octaves); i++) {
                increment = (snoise(p) + offset) * pwr * value;
                value += increment;
                pwr *= pwHL;
@@ -3487,13 +3611,12 @@ float noise_musgrave_hybrid_multi_fractal(vec3 p, float H, float lacunarity, flo
        float result, signal, weight, rmd;
        float pwHL = pow(lacunarity, -H);
        float pwr = pwHL;
-       int i;
 
        result = snoise(p) + offset;
        weight = gain * result;
        p *= lacunarity;
 
-       for (i = 1; (weight > 0.001f) && (i < int(octaves)); i++) {
+       for (int i = 1; (weight > 0.001f) && (i < int(octaves)); i++) {
                if (weight > 1.0)
                        weight = 1.0;
 
@@ -3524,14 +3647,13 @@ float noise_musgrave_ridged_multi_fractal(vec3 p, float H, float lacunarity, flo
        float result, signal, weight;
        float pwHL = pow(lacunarity, -H);
        float pwr = pwHL;
-       int i;
 
        signal = offset - abs(snoise(p));
        signal *= signal;
        result = signal;
        weight = 1.0;
 
-       for (i = 1; i < int(octaves); i++) {
+       for (int i = 1; i < int(octaves); i++) {
                p *= lacunarity;
                weight = clamp(signal * gain, 0.0, 1.0);
                signal = offset - abs(snoise(p));
@@ -3553,19 +3675,18 @@ float svm_musgrave(int type,
                    float gain,
                    vec3 p)
 {
-       if (type == 0 /*NODE_MUSGRAVE_MULTIFRACTAL*/)
+       if (type == 0 /* NODE_MUSGRAVE_MULTIFRACTAL */)
                return intensity * noise_musgrave_multi_fractal(p, dimension, lacunarity, octaves);
-       else if (type == 1 /*NODE_MUSGRAVE_FBM*/)
+       else if (type == 1 /* NODE_MUSGRAVE_FBM */)
                return intensity * noise_musgrave_fBm(p, dimension, lacunarity, octaves);
-       else if (type == 2 /*NODE_MUSGRAVE_HYBRID_MULTIFRACTAL*/)
+       else if (type == 2 /* NODE_MUSGRAVE_HYBRID_MULTIFRACTAL */)
                return intensity * noise_musgrave_hybrid_multi_fractal(p, dimension, lacunarity, octaves, offset, gain);
-       else if (type == 3 /*NODE_MUSGRAVE_RIDGED_MULTIFRACTAL*/)
+       else if (type == 3 /* NODE_MUSGRAVE_RIDGED_MULTIFRACTAL */)
                return intensity * noise_musgrave_ridged_multi_fractal(p, dimension, lacunarity, octaves, offset, gain);
-       else if (type == 4 /*NODE_MUSGRAVE_HETERO_TERRAIN*/)
+       else if (type == 4 /* NODE_MUSGRAVE_HETERO_TERRAIN */)
                return intensity * noise_musgrave_hetero_terrain(p, dimension, lacunarity, octaves, offset);
        return 0.0;
 }
-#endif  // #ifdef BIT_OPERATIONS
 
 void node_tex_musgrave(vec3 co,
                        float scale,
@@ -3578,7 +3699,6 @@ void node_tex_musgrave(vec3 co,
                        out vec4 color,
                        out float fac)
 {
-#ifdef BIT_OPERATIONS
        fac = svm_musgrave(int(type),
                           dimension,
                           lacunarity,
@@ -3587,9 +3707,6 @@ void node_tex_musgrave(vec3 co,
                           1.0,
                           gain,
                           co * scale);
-#else
-       fac = 1.0;
-#endif
 
        color = vec4(fac, fac, fac, 1.0);
 }
@@ -3601,7 +3718,6 @@ void node_tex_sky(vec3 co, out vec4 color)
 
 void node_tex_voronoi(vec3 co, float scale, float coloring, out vec4 color, out float fac)
 {
-#ifdef BIT_OPERATIONS
        vec3 p = co * scale;
        int xx, yy, zz, xi, yi, zi;
        float da[4];
@@ -3666,13 +3782,8 @@ void node_tex_voronoi(vec3 co, float scale, float coloring, out vec4 color, out
                color = vec4(cellnoise_color(pa[0]), 1);
                fac = (color.x + color.y + color.z) * (1.0 / 3.0);
        }
-#else  // BIT_OPERATIONS
-       color = vec4(1.0);
-       fac = 1.0;
-#endif  // BIT_OPERATIONS
 }
 
-#ifdef BIT_OPERATIONS
 float calc_wave(vec3 p, float distortion, float detail, float detail_scale, int wave_type, int wave_profile)
 {
        float n;
@@ -3694,22 +3805,16 @@ float calc_wave(vec3 p, float distortion, float detail, float detail_scale, int
                return (n < 0.0) ? n + 1.0 : n;
        }
 }
-#endif  // BIT_OPERATIONS
 
 void node_tex_wave(
         vec3 co, float scale, float distortion, float detail, float detail_scale, float wave_type, float wave_profile,
         out vec4 color, out float fac)
 {
-#ifdef BIT_OPERATIONS
        float f;
        f = calc_wave(co * scale, distortion, detail, detail_scale, int(wave_type), int(wave_profile));
 
        color = vec4(f, f, f, 1.0);
        fac = f;
-#else  // BIT_OPERATIONS
-       color = vec4(1.0);
-       fac = 1;
-#endif  // BIT_OPERATIONS
 }
 
 /* light path */
@@ -3729,13 +3834,21 @@ void node_light_path(
        out float transparent_depth,
        out float transmission_depth)
 {
+#ifndef PROBE_CAPTURE
        is_camera_ray = 1.0;
-       is_shadow_ray = 0.0;
-       is_diffuse_ray = 0.0;
        is_glossy_ray = 0.0;
-       is_singular_ray = 0.0;
+       is_diffuse_ray = 0.0;
        is_reflection_ray = 0.0;
        is_transmission_ray = 0.0;
+#else
+       is_camera_ray = 0.0;
+       is_glossy_ray = 1.0;
+       is_diffuse_ray = 1.0;
+       is_reflection_ray = 1.0;
+       is_transmission_ray = 1.0;
+#endif
+       is_shadow_ray = 0.0;
+       is_singular_ray = 0.0;
        ray_length = 1.0;
        ray_depth = 1.0;
        diffuse_depth = 1.0;
@@ -3800,32 +3913,65 @@ void node_output_material(vec4 surface, vec4 volume, float displacement, out vec
        result = surface;
 }
 
+uniform float backgroundAlpha;
+
 void node_output_world(vec4 surface, vec4 volume, out vec4 result)
 {
-       result = surface;
+       result = vec4(surface.rgb, backgroundAlpha);
+}
+
+/* TODO : clean this ifdef mess */
+/* EEVEE output */
+#ifdef EEVEE_ENGINE
+void world_normals_get(out vec3 N)
+{
+       N = gl_FrontFacing ? worldNormal : -worldNormal;
+}
+
+void node_eevee_metallic(
+        vec4 basecol, float metallic, float specular, float roughness, vec4 emissive, float transp, vec3 normal,
+        float clearcoat, float clearcoat_roughness, vec3 clearcoat_normal,
+        float occlusion, out vec4 result)
+{
+       vec3 diffuse, f0;
+       convert_metallic_to_specular(basecol.rgb, metallic, specular, diffuse, f0);
+
+       result = vec4(eevee_surface_lit(normal, diffuse, f0, roughness, occlusion) + emissive.rgb, 1.0 - transp);
+}
+
+void node_eevee_specular(
+        vec4 diffuse, vec4 specular, float roughness, vec4 emissive, float transp, vec3 normal,
+        float clearcoat, float clearcoat_roughness, vec3 clearcoat_normal,
+        float occlusion, out vec4 result)
+{
+       result = vec4(eevee_surface_lit(normal, diffuse.rgb, specular.rgb, roughness, occlusion) + emissive.rgb, 1.0 - transp);
+}
+
+void node_output_eevee_material(vec4 surface, out vec4 result)
+{
+       result = vec4(surface.rgb, length(viewPosition));
 }
 
+#endif
+
 /* ********************** matcap style render ******************** */
 
 void material_preview_matcap(vec4 color, sampler2D ima, vec4 N, vec4 mask, out vec4 result)
 {
        vec3 normal;
-       vec2 tex;
        
 #ifndef USE_OPENSUBDIV
        /* remap to 0.0 - 1.0 range. This is done because OpenGL 2.0 clamps colors
         * between shader stages and we want the full range of the normal */
-       normal = vec3(2.0, 2.0, 2.0) * vec3(N.x, N.y, N.z) - vec3(1.0, 1.0, 1.0);
-       if (normal.z < 0.0) {
-               normal.z = 0.0;
-       }
+       normal = 2.0 * N.xyz - vec3(1.0);
+       normal.z = max(normal.z, 0.0);
        normal = normalize(normal);
 #else
        normal = inpt.v.normal;
-       mask = vec4(1.0, 1.0, 1.0, 1.0);
+       mask = vec4(1.0);
 #endif
 
-       tex.x = 0.5 + 0.49 * normal.x;
-       tex.y = 0.5 + 0.49 * normal.y;
-       result = texture2D(ima, tex) * mask;
+       vec2 tex = 0.49 * normal.xy + vec2(0.5);
+
+       result = texture(ima, tex) * mask;
 }