Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/gpu/shaders/gpu_shader_material.glsl')
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material.glsl819
1 files changed, 591 insertions, 228 deletions
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index d589c8765e6..667972fc429 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -1,11 +1,57 @@
+
+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;
+
+/* Old glsl mode compat. */
+
+#ifndef CLOSURE_DEFAULT
+
+struct Closure {
+ vec3 radiance;
+ float opacity;
+};
+
+#define CLOSURE_DEFAULT Closure(vec3(0.0), 1.0)
+
+Closure closure_mix(Closure cl1, Closure cl2, float fac)
+{
+ Closure cl;
+ cl.radiance = mix(cl1.radiance, cl2.radiance, fac);
+ cl.opacity = mix(cl1.opacity, cl2.opacity, fac);
+ return cl;
+}
+
+Closure closure_add(Closure cl1, Closure cl2)
+{
+ Closure cl;
+ cl.radiance = cl1.radiance + cl2.radiance;
+ cl.opacity = cl1.opacity + cl2.opacity;
+ return cl;
+}
+
+Closure nodetree_exec(void); /* Prototype */
+
+#endif /* CLOSURE_DEFAULT */
+
+
/* 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 +99,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 +201,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 +226,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 +468,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 +490,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 +532,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 +543,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 +865,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 +966,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 +982,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);
@@ -1277,11 +1327,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 +1396,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 +1414,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 +1431,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 +1459,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 +1527,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 +1554,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 +1643,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 +1664,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 +1716,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 +1773,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 +1840,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 +1874,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 +2066,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 +2223,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 +2265,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 +2301,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 +2320,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 +2379,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 +2394,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 +2469,15 @@ float hypot(float x, float y)
void generated_from_orco(vec3 orco, out vec3 generated)
{
- generated = orco * 0.5 + vec3(0.5);
+#ifdef VOLUMETRICS
+#ifdef MESH_SHADER
+ generated = volumeObjectLocalCoord;
+#else
+ generated = worldPosition;
+#endif
+#else
+ generated = orco;
+#endif
}
int floor_to_int(float x)
@@ -2434,7 +2490,6 @@ int quick_floor(float x)
return int(x) - ((x < 0) ? 1 : 0);
}
-#ifdef BIT_OPERATIONS
float integer_noise(int n)
{
int nn;
@@ -2498,7 +2553,6 @@ vec3 cellnoise_color(vec3 p)
return vec3(r, g, b);
}
-#endif // BIT_OPERATIONS
float floorfrac(float x, out int i)
{
@@ -2560,41 +2614,107 @@ 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
-/* bsdfs */
+struct glLight {
+ vec4 position;
+ vec4 diffuse;
+ vec4 specular;
+ vec4 halfVector;
+};
-void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out vec4 result)
-{
+layout(std140) uniform lightSource {
+ glLight glLightSource[NUM_LIGHTS];
+};
+
+#ifndef VOLUMETRICS
+/* bsdfs */
+void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out Closure result)
+{
+#ifdef EEVEE_ENGINE
+ vec3 vN = normalize(mat3(ViewMatrix) * N);
+ result = CLOSURE_DEFAULT;
+ result.ssr_normal = normal_encode(vN, viewCameraVec);
+ eevee_closure_diffuse(N, color.rgb, 1.0, result.radiance);
+ result.radiance *= color.rgb;
+#else
/* ambient light */
vec3 L = vec3(0.2);
/* 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;
}
- result = vec4(L * color.rgb, 1.0);
+ result = Closure(L * color.rgb, 1.0);
+#endif
}
-void node_bsdf_glossy(vec4 color, float roughness, vec3 N, out vec4 result)
+void node_bsdf_glossy(vec4 color, float roughness, vec3 N, float ssr_id, out Closure result)
{
+#ifdef EEVEE_ENGINE
+ vec3 out_spec, ssr_spec;
+ roughness = sqrt(roughness);
+ eevee_closure_glossy(N, vec3(1.0), int(ssr_id), roughness, 1.0, out_spec, ssr_spec);
+ vec3 vN = normalize(mat3(ViewMatrix) * N);
+ result = CLOSURE_DEFAULT;
+ result.radiance = out_spec * color.rgb;
+ result.ssr_data = vec4(ssr_spec * color.rgb, roughness);
+ result.ssr_normal = normal_encode(vN, viewCameraVec);
+ result.ssr_id = int(ssr_id);
+#else
/* ambient light */
vec3 L = vec3(0.2);
+ direction_transform_m4v3(N, ViewMatrix, N);
+
/* 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);
@@ -2602,30 +2722,52 @@ void node_bsdf_glossy(vec4 color, float roughness, vec3 N, out vec4 result)
L += light_specular * bsdf;
}
- result = vec4(L * color.rgb, 1.0);
+ result = Closure(L * color.rgb, 1.0);
+#endif
}
void node_bsdf_anisotropic(
vec4 color, float roughness, float anisotropy, float rotation, vec3 N, vec3 T,
- out vec4 result)
+ out Closure result)
{
node_bsdf_diffuse(color, 0.0, N, result);
}
-void node_bsdf_glass(vec4 color, float roughness, float ior, vec3 N, out vec4 result)
-{
+void node_bsdf_glass(vec4 color, float roughness, float ior, vec3 N, float ssr_id, out Closure result)
+{
+#ifdef EEVEE_ENGINE
+ vec3 out_spec, out_refr, ssr_spec;
+ roughness = sqrt(roughness);
+ vec3 refr_color = (refractionDepth > 0.0) ? color.rgb * color.rgb : color.rgb; /* Simulate 2 transmission event */
+ eevee_closure_glass(N, vec3(1.0), int(ssr_id), roughness, 1.0, ior, out_spec, out_refr, ssr_spec);
+ out_refr *= refr_color;
+ out_spec *= color.rgb;
+ float fresnel = F_eta(ior, dot(N, cameraVec));
+ vec3 vN = normalize(mat3(ViewMatrix) * N);
+ result = CLOSURE_DEFAULT;
+ result.radiance = mix(out_refr, out_spec, fresnel);
+ result.ssr_data = vec4(ssr_spec * color.rgb * fresnel, roughness);
+ result.ssr_normal = normal_encode(vN, viewCameraVec);
+ result.ssr_id = int(ssr_id);
+#else
node_bsdf_diffuse(color, 0.0, N, result);
+#endif
}
-void node_bsdf_toon(vec4 color, float size, float tsmooth, vec3 N, out vec4 result)
+void node_bsdf_toon(vec4 color, float size, float tsmooth, vec3 N, out Closure result)
{
node_bsdf_diffuse(color, 0.0, N, result);
}
+#ifndef EEVEE_ENGINE
void node_bsdf_principled(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)
+ float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, out Closure 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));
@@ -2633,28 +2775,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
- if(N.x != N.y || N.x != N.z) {
- Tangent = vec3(N.z-N.y, N.x-N.z, N.y-N.x); // (1,1,1) x N
- }
- else {
- Tangent = vec3(N.z-N.y, N.x+N.z, -N.y-N.x); // (-1,1,1) x N
- }
- }
-
- /* 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 +2783,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 +2799,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 +2820,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);
@@ -2738,83 +2855,234 @@ void node_bsdf_principled(vec4 base_color, float subsurface, vec3 subsurface_rad
L += diffuse_and_specular_bsdf + clearcoat_bsdf;
}
- result = vec4(L, 1.0);
+ result = Closure(L, 1.0);
}
+#endif
-void node_bsdf_translucent(vec4 color, vec3 N, out vec4 result)
+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, float ssr_id,
+ float sss_id, vec3 sss_scale, out Closure result)
{
- node_bsdf_diffuse(color, 0.0, N, result);
+#ifdef EEVEE_ENGINE
+ metallic = saturate(metallic);
+ transmission = saturate(transmission);
+
+ vec3 diffuse, f0, out_diff, out_spec, out_trans, out_refr, ssr_spec;
+ convert_metallic_to_specular_tinted(base_color.rgb, metallic, specular, specular_tint, diffuse, f0);
+
+ transmission *= 1.0 - metallic;
+ subsurface *= 1.0 - metallic;
+
+ clearcoat *= 0.25;
+ clearcoat *= 1.0 - transmission;
+
+#ifdef USE_SSS
+ diffuse = mix(diffuse, vec3(0.0), subsurface);
+#else
+ diffuse = mix(diffuse, subsurface_color.rgb, subsurface);
+#endif
+ f0 = mix(f0, vec3(1.0), transmission);
+
+ float sss_scalef = dot(sss_scale, vec3(1.0 / 3.0));
+ eevee_closure_principled(N, diffuse, f0, int(ssr_id), roughness,
+ CN, clearcoat, clearcoat_roughness, 1.0, sss_scalef, ior,
+ out_diff, out_trans, out_spec, out_refr, ssr_spec);
+
+ vec3 refr_color = base_color.rgb;
+ refr_color *= (refractionDepth > 0.0) ? refr_color : vec3(1.0); /* Simulate 2 transmission event */
+
+ float fresnel = F_eta(ior, dot(N, cameraVec));
+ vec3 refr_spec_color = base_color.rgb * fresnel;
+ /* This bit maybe innacurate. */
+ out_refr = out_refr * refr_color * (1.0 - fresnel) + out_spec * refr_spec_color;
+
+ ssr_spec = mix(ssr_spec, refr_spec_color, transmission);
+
+ vec3 vN = normalize(mat3(ViewMatrix) * N);
+ result = CLOSURE_DEFAULT;
+ result.radiance = out_spec + out_diff * diffuse;
+ result.radiance = mix(result.radiance, out_refr, transmission);
+ result.ssr_data = vec4(ssr_spec, roughness);
+ result.ssr_normal = normal_encode(vN, viewCameraVec);
+ result.ssr_id = int(ssr_id);
+#ifdef USE_SSS
+ result.sss_data.a = sss_scalef;
+ result.sss_data.rgb = out_diff + out_trans;
+#ifdef USE_SSS_ALBEDO
+ result.sss_albedo.rgb = mix(vec3(0.0), subsurface_color.rgb, subsurface);
+#else
+ result.sss_data.rgb *= mix(vec3(0.0), subsurface_color.rgb, subsurface);
+#endif
+ result.sss_data.rgb *= (1.0 - transmission);
+#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 Closure result)
+{
+ node_bsdf_diffuse(color, 0.0, -N, result);
}
-void node_bsdf_transparent(vec4 color, out vec4 result)
+void node_bsdf_transparent(vec4 color, out Closure result)
{
/* this isn't right */
- result.r = color.r;
- result.g = color.g;
- result.b = color.b;
- result.a = 0.0;
+ result = CLOSURE_DEFAULT;
+ result.radiance = vec3(0.0);
+ result.opacity = 0.0;
+#ifdef EEVEE_ENGINE
+ result.ssr_id = TRANSPARENT_CLOSURE_FLAG;
+#endif
}
-void node_bsdf_velvet(vec4 color, float sigma, vec3 N, out vec4 result)
+void node_bsdf_velvet(vec4 color, float sigma, vec3 N, out Closure result)
{
node_bsdf_diffuse(color, 0.0, N, result);
}
void node_subsurface_scattering(
- vec4 color, float scale, vec3 radius, float sharpen, float texture_blur, vec3 N,
- out vec4 result)
-{
+ vec4 color, float scale, vec3 radius, float sharpen, float texture_blur, vec3 N, float sss_id,
+ out Closure result)
+{
+#if defined(EEVEE_ENGINE) && defined(USE_SSS)
+ vec3 out_diff, out_trans;
+ vec3 vN = normalize(mat3(ViewMatrix) * N);
+ result = CLOSURE_DEFAULT;
+ result.ssr_data = vec4(0.0);
+ result.ssr_normal = normal_encode(vN, viewCameraVec);
+ result.ssr_id = -1;
+ result.sss_data.a = scale;
+ eevee_closure_subsurface(N, color.rgb, 1.0, scale, out_diff, out_trans);
+ result.sss_data.rgb = out_diff + out_trans;
+#ifdef USE_SSS_ALBEDO
+ /* Not perfect for texture_blur not exaclty equal to 0.0 or 1.0. */
+ result.sss_albedo.rgb = mix(color.rgb, vec3(1.0), texture_blur);
+ result.sss_data.rgb *= mix(vec3(1.0), color.rgb, texture_blur);
+#else
+ result.sss_data.rgb *= color.rgb;
+#endif
+#else
node_bsdf_diffuse(color, 0.0, N, result);
+#endif
}
-void node_bsdf_hair(vec4 color, float offset, float roughnessu, float roughnessv, vec3 tangent, out vec4 result)
+void node_bsdf_refraction(vec4 color, float roughness, float ior, vec3 N, out Closure result)
{
- result = color;
+#ifdef EEVEE_ENGINE
+ vec3 out_refr;
+ color.rgb *= (refractionDepth > 0.0) ? color.rgb : vec3(1.0); /* Simulate 2 absorption event. */
+ roughness = sqrt(roughness);
+ eevee_closure_refraction(N, roughness, ior, out_refr);
+ vec3 vN = normalize(mat3(ViewMatrix) * N);
+ result = CLOSURE_DEFAULT;
+ result.ssr_normal = normal_encode(vN, viewCameraVec);
+ result.radiance = out_refr * color.rgb;
+ result.ssr_id = REFRACT_CLOSURE_FLAG;
+#else
+ node_bsdf_diffuse(color, 0.0, N, result);
+#endif /* EEVEE_ENGINE */
}
-void node_bsdf_refraction(vec4 color, float roughness, float ior, vec3 N, out vec4 result)
+/* Unsupported for now */
+#ifndef EEVEE_ENGINE
+void node_bsdf_hair(vec4 color, float offset, float roughnessu, float roughnessv, vec3 tangent, out Closure result)
{
- node_bsdf_diffuse(color, 0.0, N, result);
+ result = Closure(color.rgb, color.a);
}
-void node_ambient_occlusion(vec4 color, out vec4 result)
+void node_ambient_occlusion(vec4 color, out Closure result)
{
- result = color;
+ result = Closure(color.rgb, color.a);
}
+#endif /* EEVEE_ENGINE */
+
+#endif /* VOLUMETRICS */
/* emission */
-void node_emission(vec4 color, float strength, vec3 N, out vec4 result)
+void node_emission(vec4 color, float strength, vec3 vN, out Closure result)
{
- result = color * strength;
+#ifndef VOLUMETRICS
+ color *= strength;
+#ifdef EEVEE_ENGINE
+ result = CLOSURE_DEFAULT;
+ result.radiance = color.rgb;
+ result.opacity = color.a;
+ result.ssr_normal = normal_encode(vN, viewCameraVec);
+#else
+ result = Closure(color.rgb, color.a);
+#endif
+#else
+ result = Closure(vec3(0.0), vec3(0.0), color.rgb * strength, 0.0);
+#endif
}
/* background */
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, out Closure result)
+{
+#ifndef VOLUMETRICS
+ color *= strength;
+#ifdef EEVEE_ENGINE
+ result = CLOSURE_DEFAULT;
+ result.radiance = color.rgb;
+ result.opacity = color.a;
+#else
+ result = Closure(color.rgb, color.a);
+#endif
+#else
+ result = CLOSURE_DEFAULT;
+#endif
+}
+
+/* volumes */
+
+void node_volume_scatter(vec4 color, float density, float anisotropy, out Closure result)
+{
+#ifdef VOLUMETRICS
+ result = Closure(vec3(0.0), color.rgb * density, vec3(0.0), anisotropy);
+#else
+ result = CLOSURE_DEFAULT;
+#endif
}
-void node_background(vec4 color, float strength, vec3 N, out vec4 result)
+void node_volume_absorption(vec4 color, float density, out Closure result)
{
- result = color * strength;
+#ifdef VOLUMETRICS
+ result = Closure((1.0 - color.rgb) * density, vec3(0.0), vec3(0.0), 0.0);
+#else
+ result = CLOSURE_DEFAULT;
+#endif
}
/* closures */
-void node_mix_shader(float fac, vec4 shader1, vec4 shader2, out vec4 shader)
+void node_mix_shader(float fac, Closure shader1, Closure shader2, out Closure shader)
{
- shader = mix(shader1, shader2, fac);
+ shader = closure_mix(shader1, shader2, fac);
}
-void node_add_shader(vec4 shader1, vec4 shader2, out vec4 shader)
+void node_add_shader(Closure shader1, Closure shader2, out Closure shader)
{
- shader = shader1 + shader2;
+ shader = closure_add(shader1, shader2);
}
/* fresnel */
@@ -2822,7 +3090,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 +3102,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);
@@ -2864,11 +3132,47 @@ void node_gamma(vec4 col, float gamma, out vec4 outcol)
/* geometry */
+void node_attribute_volume_density(sampler3D tex, out vec4 outcol, out vec3 outvec, out float outf)
+{
+#if defined(EEVEE_ENGINE) && defined(MESH_SHADER) && defined(VOLUMETRICS)
+ vec3 cos = volumeObjectLocalCoord;
+#else
+ vec3 cos = vec3(0.0);
+#endif
+ outvec = texture(tex, cos).aaa;
+ outcol = vec4(outvec, 1.0);
+ outf = dot(vec3(1.0 / 3.0), outvec);
+}
+
+void node_attribute_volume_color(sampler3D tex, out vec4 outcol, out vec3 outvec, out float outf)
+{
+#if defined(EEVEE_ENGINE) && defined(MESH_SHADER) && defined(VOLUMETRICS)
+ vec3 cos = volumeObjectLocalCoord;
+#else
+ vec3 cos = vec3(0.0);
+#endif
+ outvec = texture(tex, cos).rgb;
+ outcol = vec4(outvec, 1.0);
+ outf = dot(vec3(1.0 / 3.0), outvec);
+}
+
+void node_attribute_volume_flame(sampler3D tex, out vec4 outcol, out vec3 outvec, out float outf)
+{
+#if defined(EEVEE_ENGINE) && defined(MESH_SHADER) && defined(VOLUMETRICS)
+ vec3 cos = volumeObjectLocalCoord;
+#else
+ vec3 cos = vec3(0.0);
+#endif
+ outvec = texture(tex, cos).rrr;
+ outcol = vec4(outvec, 1.0);
+ outf = dot(vec3(1.0 / 3.0), outvec);
+}
+
void node_attribute(vec3 attr, out vec4 outcol, out vec3 outvec, out float outf)
{
outcol = vec4(attr, 1.0);
outvec = attr;
- outf = (attr.x + attr.y + attr.z) / 3.0;
+ outf = dot(vec3(1.0 / 3.0), attr);
}
void node_uvmap(vec3 attr_uv, out vec3 outvec)
@@ -2876,19 +3180,51 @@ 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 = vec3(0.0, (orco_in.z - 0.5) * -0.5, (orco_in.y - 0.5) * 0.5);
+}
+
+void tangent_orco_y(vec3 orco_in, out vec3 orco_out)
+{
+ orco_out = vec3((orco_in.z - 0.5) * -0.5, 0.0, (orco_in.x - 0.5) * 0.5);
+}
+
+void tangent_orco_z(vec3 orco_in, out vec3 orco_out)
+{
+ orco_out = vec3((orco_in.y - 0.5) * -0.5, (orco_in.x - 0.5) * 0.5, 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)
{
+#ifdef EEVEE_ENGINE
+ position = worldPosition;
+#else
position = (toworld * vec4(I, 1.0)).xyz;
+#endif
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 +3238,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;
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 +3258,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 +3277,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)
@@ -3012,7 +3357,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,
@@ -3048,7 +3392,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,
@@ -3059,7 +3402,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,
@@ -3073,10 +3415,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)
@@ -3091,7 +3429,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)
@@ -3107,7 +3453,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)
@@ -3117,7 +3463,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;
}
@@ -3191,21 +3537,21 @@ void node_tex_image_box(vec3 texco,
if(signed_N.x < 0.0) {
uv.x = 1.0 - uv.x;
}
- color += weight.x * texture2D(ima, uv);
+ color += weight.x * texture(ima, uv);
}
if (weight.y > 0.0) {
vec2 uv = texco.xz;
if(signed_N.y > 0.0) {
uv.x = 1.0 - uv.x;
}
- color += weight.y * texture2D(ima, uv);
+ color += weight.y * texture(ima, uv);
}
if (weight.z > 0.0) {
vec2 uv = texco.yx;
if(signed_N.z > 0.0) {
uv.x = 1.0 - uv.x;
}
- color += weight.z * texture2D(ima, uv);
+ color += weight.z * texture(ima, uv);
}
alpha = color.a;
@@ -3278,7 +3624,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);
@@ -3353,10 +3698,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);
@@ -3366,7 +3710,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);
@@ -3381,11 +3725,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) {
@@ -3401,15 +3743,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
@@ -3425,9 +3760,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;
@@ -3453,9 +3787,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;
@@ -3481,13 +3814,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;
@@ -3516,13 +3848,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;
@@ -3553,14 +3884,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));
@@ -3582,19 +3912,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,
@@ -3607,7 +3936,6 @@ void node_tex_musgrave(vec3 co,
out vec4 color,
out float fac)
{
-#ifdef BIT_OPERATIONS
fac = svm_musgrave(int(type),
dimension,
lacunarity,
@@ -3616,9 +3944,6 @@ void node_tex_musgrave(vec3 co,
1.0,
gain,
co * scale);
-#else
- fac = 1.0;
-#endif
color = vec4(fac, fac, fac, 1.0);
}
@@ -3630,7 +3955,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];
@@ -3695,13 +4019,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;
@@ -3723,22 +4042,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 */
@@ -3758,13 +4071,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;
@@ -3863,37 +4184,79 @@ void node_vector_displacement_world(vec4 vector, float midlevel, float scale, ou
/* output */
-void node_output_material(vec4 surface, vec4 volume, vec3 displacement, out vec4 result)
+void node_output_material(Closure surface, Closure volume, vec3 displacement, out Closure result)
{
+#ifdef VOLUMETRICS
+ result = volume;
+#else
result = surface;
+#endif
}
-void node_output_world(vec4 surface, vec4 volume, out vec4 result)
+uniform float backgroundAlpha;
+
+void node_output_world(Closure surface, Closure volume, out Closure result)
{
- result = surface;
+#ifndef VOLUMETRICS
+#ifdef EEVEE_ENGINE
+ result.radiance = surface.radiance;
+ result.opacity = backgroundAlpha;
+#else
+ result = Closure(surface.radiance, backgroundAlpha);
+#endif
+#else
+ result = volume;
+#endif /* VOLUMETRICS */
+}
+
+#ifndef VOLUMETRICS
+/* 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_specular(
+ vec4 diffuse, vec4 specular, float roughness, vec4 emissive, float transp, vec3 normal,
+ float clearcoat, float clearcoat_roughness, vec3 clearcoat_normal,
+ float occlusion, float ssr_id, out Closure result)
+{
+ vec3 out_diff, out_spec, ssr_spec;
+ eevee_closure_default(normal, diffuse.rgb, specular.rgb, int(ssr_id), roughness, occlusion,
+ out_diff, out_spec, ssr_spec);
+
+ vec3 vN = normalize(mat3(ViewMatrix) * normal);
+ result = CLOSURE_DEFAULT;
+ result.radiance = out_diff * diffuse.rgb + out_spec + emissive.rgb;
+ result.opacity = 1.0 - transp;
+ result.ssr_data = vec4(ssr_spec, roughness);
+ result.ssr_normal = normal_encode(vN, viewCameraVec);
+ result.ssr_id = int(ssr_id);
}
+#endif /* EEVEE_ENGINE */
+#endif /* VOLUMETRICS */
+
/* ********************** 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;
}