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.glsl2396
1 files changed, 538 insertions, 1858 deletions
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index ce9e82b34f8..3affacf5203 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -1,12 +1,18 @@
+
+uniform mat4 ModelMatrix;
+uniform mat4 ModelViewMatrix;
+uniform mat4 ModelViewMatrixInverse;
+uniform mat3 NormalMatrix;
+
+#ifndef ATTRIB
+uniform mat4 ModelMatrixInverse;
+#endif
+
/* 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;
-#else
- return (color.r + color.g + color.b) / 3.0;
-#endif
+ return dot(color.rgb, vec3(0.2126, 0.7152, 0.0722));
}
float exp_blender(float f)
@@ -53,7 +59,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,56 +161,15 @@ 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);
-}
-
-void uv_attribute(vec2 attuv, out vec3 uv)
-{
- uv = vec3(attuv * 2.0 - vec2(1.0, 1.0), 0.0);
-}
-
-void geom(
- vec3 co, vec3 nor, mat4 viewinvmat, vec3 attorco, vec2 attuv, vec4 attvcol,
- out vec3 global, out vec3 local, out vec3 view, out vec3 orco, out vec3 uv,
- 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);
- global = (viewinvmat * vec4(local, 1.0)).xyz;
- orco = attorco;
- uv_attribute(attuv, uv);
- normal = -normalize(nor); /* blender render normal is negated */
- vcol_attribute(attvcol, vcol);
- srgb_to_linearrgb(vcol, vcol);
- vcol_alpha = attvcol.a;
- frontback = (gl_FrontFacing) ? 1.0 : 0.0;
-}
-
-void particle_info(
- vec4 sprops, vec4 loc, vec3 vel, vec3 avel,
- out float index, out float random, out float age,
- out float life_time, out vec3 location,
- out float size, out vec3 velocity, out vec3 angular_velocity)
-{
- index = sprops.x;
- random = loc.w;
- age = sprops.y;
- life_time = sprops.z;
- size = sprops.w;
-
- location = loc.xyz;
- velocity = vel;
- angular_velocity = avel;
-}
-
void vect_normalize(vec3 vin, out vec3 vout)
{
vout = normalize(vin);
@@ -272,17 +237,6 @@ void camera(vec3 co, out vec3 outview, out float outdepth, out float outdist)
outview = normalize(co);
}
-void lamp(
- vec4 col, float energy, vec3 lv, float dist, vec3 shadow, float visifac,
- out vec4 outcol, out vec3 outlv, out float outdist, out vec4 outshadow, out float outvisifac)
-{
- outcol = col * energy;
- outlv = lv;
- outdist = dist;
- outshadow = vec4(shadow, 1.0);
- outvisifac = visifac;
-}
-
void math_add(float val1, float val2, out float outval)
{
outval = val1 + val2;
@@ -426,13 +380,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)
@@ -448,7 +402,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);
}
@@ -490,9 +444,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));
@@ -501,9 +455,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));
@@ -823,22 +777,19 @@ 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;
-#else
- outval = color.r * 0.35 + color.g * 0.45 + color.b * 0.2; /* keep these factors in sync with texture.h:RGBTOBW */
-#endif
+ vec3 factors = vec3(0.2126, 0.7152, 0.0722);
+ 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,56 +867,6 @@ void output_node(vec4 rgb, float alpha, out vec4 outrgb)
/*********** TEXTURES ***************/
-void texture_flip_blend(vec3 vec, out vec3 outvec)
-{
- outvec = vec.yxz;
-}
-
-void texture_blend_lin(vec3 vec, out float outval)
-{
- outval = (1.0 + vec.x) / 2.0;
-}
-
-void texture_blend_quad(vec3 vec, out float outval)
-{
- outval = max((1.0 + vec.x) / 2.0, 0.0);
- outval *= outval;
-}
-
-void texture_wood_sin(vec3 vec, out float value, out vec4 color, out vec3 normal)
-{
- float a = sqrt(vec.x * vec.x + vec.y * vec.y + vec.z * vec.z) * 20.0;
- float wi = 0.5 + 0.5 * sin(a);
-
- value = wi;
- color = vec4(wi, wi, wi, 1.0);
- normal = vec3(0.0, 0.0, 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);
- value = color.a;
-
- normal.x = 2.0 * (color.r - 0.5);
- normal.y = 2.0 * (0.5 - color.g);
- normal.z = 2.0 * (color.b - 0.5);
-}
-
-/************* MTEX *****************/
-
-void texco_orco(vec3 attorco, out vec3 orco)
-{
- orco = attorco;
-}
-
-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, 0.0);
-}
-
void texco_norm(vec3 normal, out vec3 outnormal)
{
/* corresponds to shi->orn, which is negated so cancels
@@ -973,436 +874,11 @@ void texco_norm(vec3 normal, out vec3 outnormal)
outnormal = normalize(normal);
}
-void texco_tangent(vec4 tangent, out vec3 outtangent)
-{
- outtangent = normalize(tangent.xyz);
-}
-
-void texco_global(mat4 viewinvmat, vec3 co, out vec3 global)
-{
- global = (viewinvmat * vec4(co, 1.0)).xyz;
-}
-
-void texco_object(mat4 viewinvmat, mat4 obinvmat, vec3 co, out vec3 object)
-{
- object = (obinvmat * (viewinvmat * vec4(co, 1.0))).xyz;
-}
-
-void texco_refl(vec3 vn, vec3 view, out vec3 ref)
-{
- ref = view - 2.0 * dot(vn, view) * vn;
-}
-
-void shade_norm(vec3 normal, out vec3 outnormal)
-{
- /* blender render normal is negated */
- outnormal = -normalize(normal);
-}
-
-void mtex_mirror(vec3 tcol, vec4 refcol, float tin, float colmirfac, out vec4 outrefcol)
-{
- outrefcol = mix(refcol, vec4(1.0, tcol), tin * colmirfac);
-}
-
-void mtex_rgb_blend(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
-{
- float facm;
-
- fact *= facg;
- facm = 1.0 - fact;
-
- incol = fact * texcol + facm * outcol;
-}
-
-void mtex_rgb_mul(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
-{
- float facm;
-
- fact *= facg;
- facm = 1.0 - fact;
-
- incol = (facm + fact * texcol) * outcol;
-}
-
-void mtex_rgb_screen(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
-{
- float facm;
-
- fact *= facg;
- facm = 1.0 - fact;
-
- incol = vec3(1.0) - (vec3(facm) + fact * (vec3(1.0) - texcol)) * (vec3(1.0) - outcol);
-}
-
-void mtex_rgb_overlay(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
-{
- float facm;
-
- fact *= facg;
- facm = 1.0 - fact;
-
- if (outcol.r < 0.5)
- incol.r = outcol.r * (facm + 2.0 * fact * texcol.r);
- else
- incol.r = 1.0 - (facm + 2.0 * fact * (1.0 - texcol.r)) * (1.0 - outcol.r);
-
- if (outcol.g < 0.5)
- incol.g = outcol.g * (facm + 2.0 * fact * texcol.g);
- else
- incol.g = 1.0 - (facm + 2.0 * fact * (1.0 - texcol.g)) * (1.0 - outcol.g);
-
- if (outcol.b < 0.5)
- incol.b = outcol.b * (facm + 2.0 * fact * texcol.b);
- else
- incol.b = 1.0 - (facm + 2.0 * fact * (1.0 - texcol.b)) * (1.0 - outcol.b);
-}
-
-void mtex_rgb_sub(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
-{
- incol = -fact * facg * texcol + outcol;
-}
-
-void mtex_rgb_add(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
-{
- incol = fact * facg * texcol + outcol;
-}
-
-void mtex_rgb_div(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
-{
- float facm;
-
- fact *= facg;
- facm = 1.0 - fact;
-
- if (texcol.r != 0.0) incol.r = facm * outcol.r + fact * outcol.r / texcol.r;
- if (texcol.g != 0.0) incol.g = facm * outcol.g + fact * outcol.g / texcol.g;
- if (texcol.b != 0.0) incol.b = facm * outcol.b + fact * outcol.b / texcol.b;
-}
-
-void mtex_rgb_diff(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
-{
- float facm;
-
- fact *= facg;
- facm = 1.0 - fact;
-
- incol = facm * outcol + fact * abs(texcol - outcol);
-}
-
-void mtex_rgb_dark(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
-{
- float facm, col;
-
- fact *= facg;
- facm = 1.0 - fact;
-
- incol.r = min(outcol.r, texcol.r) * fact + outcol.r * facm;
- incol.g = min(outcol.g, texcol.g) * fact + outcol.g * facm;
- incol.b = min(outcol.b, texcol.b) * fact + outcol.b * facm;
-}
-
-void mtex_rgb_light(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
-{
- float facm, col;
-
- fact *= facg;
-
- col = fact * texcol.r;
- if (col > outcol.r) incol.r = col; else incol.r = outcol.r;
- col = fact * texcol.g;
- if (col > outcol.g) incol.g = col; else incol.g = outcol.g;
- col = fact * texcol.b;
- if (col > outcol.b) incol.b = col; else incol.b = outcol.b;
-}
-
-void mtex_rgb_hue(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
-{
- vec4 col;
-
- mix_hue(fact * facg, vec4(outcol, 1.0), vec4(texcol, 1.0), col);
- incol.rgb = col.rgb;
-}
-
-void mtex_rgb_sat(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
-{
- vec4 col;
-
- mix_sat(fact * facg, vec4(outcol, 1.0), vec4(texcol, 1.0), col);
- incol.rgb = col.rgb;
-}
-
-void mtex_rgb_val(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
-{
- vec4 col;
-
- mix_val(fact * facg, vec4(outcol, 1.0), vec4(texcol, 1.0), col);
- incol.rgb = col.rgb;
-}
-
-void mtex_rgb_color(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
-{
- vec4 col;
-
- mix_color(fact * facg, vec4(outcol, 1.0), vec4(texcol, 1.0), col);
- incol.rgb = col.rgb;
-}
-
-void mtex_rgb_soft(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
-{
- vec4 col;
-
- mix_soft(fact * facg, vec4(outcol, 1.0), vec4(texcol, 1.0), col);
- incol.rgb = col.rgb;
-}
-
-void mtex_rgb_linear(vec3 outcol, vec3 texcol, float fact, float facg, out vec3 incol)
-{
- fact *= facg;
-
- if (texcol.r > 0.5)
- incol.r = outcol.r + fact * (2.0 * (texcol.r - 0.5));
- else
- incol.r = outcol.r + fact * (2.0 * (texcol.r) - 1.0);
-
- if (texcol.g > 0.5)
- incol.g = outcol.g + fact * (2.0 * (texcol.g - 0.5));
- else
- incol.g = outcol.g + fact * (2.0 * (texcol.g) - 1.0);
-
- if (texcol.b > 0.5)
- incol.b = outcol.b + fact * (2.0 * (texcol.b - 0.5));
- else
- incol.b = outcol.b + fact * (2.0 * (texcol.b) - 1.0);
-}
-
-void mtex_value_vars(inout float fact, float facg, out float facm)
-{
- fact *= abs(facg);
- facm = 1.0 - fact;
-
- if (facg < 0.0) {
- float tmp = fact;
- fact = facm;
- facm = tmp;
- }
-}
-
-void mtex_value_blend(float outcol, float texcol, float fact, float facg, out float incol)
-{
- float facm;
- mtex_value_vars(fact, facg, facm);
-
- incol = fact * texcol + facm * outcol;
-}
-
-void mtex_value_mul(float outcol, float texcol, float fact, float facg, out float incol)
-{
- float facm;
- mtex_value_vars(fact, facg, facm);
-
- facm = 1.0 - facg;
- incol = (facm + fact * texcol) * outcol;
-}
-
-void mtex_value_screen(float outcol, float texcol, float fact, float facg, out float incol)
-{
- float facm;
- mtex_value_vars(fact, facg, facm);
-
- facm = 1.0 - facg;
- incol = 1.0 - (facm + fact * (1.0 - texcol)) * (1.0 - outcol);
-}
-
-void mtex_value_sub(float outcol, float texcol, float fact, float facg, out float incol)
-{
- float facm;
- mtex_value_vars(fact, facg, facm);
-
- fact = -fact;
- incol = fact * texcol + outcol;
-}
-
-void mtex_value_add(float outcol, float texcol, float fact, float facg, out float incol)
-{
- float facm;
- mtex_value_vars(fact, facg, facm);
-
- fact = fact;
- incol = fact * texcol + outcol;
-}
-
-void mtex_value_div(float outcol, float texcol, float fact, float facg, out float incol)
-{
- float facm;
- mtex_value_vars(fact, facg, facm);
-
- if (texcol != 0.0)
- incol = facm * outcol + fact * outcol / texcol;
- else
- incol = 0.0;
-}
-
-void mtex_value_diff(float outcol, float texcol, float fact, float facg, out float incol)
-{
- float facm;
- mtex_value_vars(fact, facg, facm);
-
- incol = facm * outcol + fact * abs(texcol - outcol);
-}
-
-void mtex_value_dark(float outcol, float texcol, float fact, float facg, out float incol)
-{
- float facm;
- mtex_value_vars(fact, facg, facm);
-
- incol = facm * outcol + fact * min(outcol, texcol);
-}
-
-void mtex_value_light(float outcol, float texcol, float fact, float facg, out float incol)
-{
- float facm;
- mtex_value_vars(fact, facg, facm);
-
- float col = fact * texcol;
- if (col > outcol) incol = col; else incol = outcol;
-}
-
-void mtex_value_clamp_positive(float fac, out float outfac)
-{
- outfac = max(fac, 0.0);
-}
-
-void mtex_value_clamp(float fac, out float outfac)
-{
- outfac = clamp(fac, 0.0, 1.0);
-}
-
-void mtex_har_divide(float har, out float outhar)
-{
- outhar = har / 128.0;
-}
-
-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;
-}
-
-void mtex_alpha_from_col(vec4 col, out float alpha)
-{
- alpha = col.a;
-}
-
-void mtex_alpha_to_col(vec4 col, float alpha, out vec4 outcol)
-{
- outcol = vec4(col.rgb, alpha);
-}
-
-void mtex_alpha_multiply_value(vec4 col, float value, out vec4 outcol)
-{
- outcol = vec4(col.rgb, col.a * value);
-}
-
-void mtex_rgbtoint(vec4 rgb, out float intensity)
-{
- intensity = dot(vec3(0.35, 0.45, 0.2), rgb.rgb);
-}
-
-void mtex_value_invert(float invalue, out float outvalue)
-{
- outvalue = 1.0 - invalue;
-}
-
-void mtex_rgb_invert(vec4 inrgb, out vec4 outrgb)
-{
- outrgb = vec4(vec3(1.0) - inrgb.rgb, inrgb.a);
-}
-
-void mtex_value_stencil(float stencil, float intensity, out float outstencil, out float outintensity)
-{
- float fact = intensity;
- outintensity = intensity * stencil;
- outstencil = stencil * fact;
-}
-
-void mtex_rgb_stencil(float stencil, vec4 rgb, out float outstencil, out vec4 outrgb)
-{
- float fact = rgb.a;
- outrgb = vec4(rgb.rgb, rgb.a * stencil);
- outstencil = stencil * fact;
-}
-
-void mtex_mapping_ofs(vec3 texco, vec3 ofs, out vec3 outtexco)
-{
- outtexco = texco + ofs;
-}
-
-void mtex_mapping_size(vec3 texco, vec3 size, out vec3 outtexco)
-{
- outtexco = size * texco;
-}
-
-void mtex_2d_mapping(vec3 vec, out vec3 outvec)
-{
- outvec = vec3(vec.xy * 0.5 + vec2(0.5), vec.z);
-}
-
vec3 mtex_2d_mapping(vec3 vec)
{
return vec3(vec.xy * 0.5 + vec2(0.5), vec.z);
}
-void mtex_cube_map(vec3 co, samplerCube ima, out float value, out vec4 color)
-{
- color = textureCube(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);
- value = color.a;
-}
-
-void mtex_cube_map_refl(
- samplerCube ima, vec3 vp, vec3 vn, mat4 viewmatrixinverse, mat4 viewmatrix,
- out float value, out vec4 color)
-{
- 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);
- value = 1.0;
-}
-
-void mtex_image(vec3 texco, sampler2D ima, out float value, out vec4 color)
-{
- color = texture2D(ima, texco.xy);
- value = 1.0;
-}
-
-void mtex_normal(vec3 texco, sampler2D ima, out vec3 normal)
-{
- // The invert of the red channel is to make
- // the normal map compliant with the outside world.
- // 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);
- normal = 2.0 * (vec3(-color.r, color.g, color.b) - vec3(-0.5, 0.5, 0.5));
-}
-
-void mtex_bump_normals_init(vec3 vN, out vec3 vNorg, out vec3 vNacc, out float fPrevMagnitude)
-{
- vNorg = vN;
- vNacc = vN;
- fPrevMagnitude = 1.0;
-}
-
/** helper method to extract the upper left 3x3 matrix from a 4x4 matrix */
mat3 to_mat3(mat4 m4)
{
@@ -1413,976 +889,6 @@ mat3 to_mat3(mat4 m4)
return m3;
}
-void mtex_bump_init_objspace(
- vec3 surf_pos, vec3 surf_norm,
- mat4 mView, mat4 mViewInv, mat4 mObj, mat4 mObjInv,
- float fPrevMagnitude_in, vec3 vNacc_in,
- 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);
-
- vec3 vSigmaS = view2obj * dFdx(surf_pos);
- vec3 vSigmaT = view2obj * dFdy(surf_pos);
- vec3 vN = normalize(surf_norm * obj2view);
-
- vR1 = cross(vSigmaT, vN);
- vR2 = cross(vN, vSigmaS);
- fDet = dot(vSigmaS, vR1);
-
- /* pretransform vNacc (in mtex_bump_apply) using the inverse transposed */
- vR1 = vR1 * view2obj;
- vR2 = vR2 * view2obj;
- vN = vN * view2obj;
-
- float fMagnitude = abs(fDet) * length(vN);
- vNacc_out = vNacc_in * (fMagnitude / fPrevMagnitude_in);
- fPrevMagnitude_out = fMagnitude;
-}
-
-void mtex_bump_init_texturespace(
- vec3 surf_pos, vec3 surf_norm,
- float fPrevMagnitude_in, vec3 vNacc_in,
- out float fPrevMagnitude_out, out vec3 vNacc_out,
- out vec3 vR1, out vec3 vR2, out float fDet)
-{
- vec3 vSigmaS = dFdx(surf_pos);
- vec3 vSigmaT = dFdy(surf_pos);
- vec3 vN = surf_norm; /* normalized interpolated vertex normal */
-
- vR1 = normalize(cross(vSigmaT, vN));
- vR2 = normalize(cross(vN, vSigmaS));
- fDet = sign(dot(vSigmaS, vR1));
-
- float fMagnitude = abs(fDet);
- vNacc_out = vNacc_in * (fMagnitude / fPrevMagnitude_in);
- fPrevMagnitude_out = fMagnitude;
-}
-
-void mtex_bump_init_viewspace(
- vec3 surf_pos, vec3 surf_norm,
- float fPrevMagnitude_in, vec3 vNacc_in,
- out float fPrevMagnitude_out, out vec3 vNacc_out,
- out vec3 vR1, out vec3 vR2, out float fDet)
-{
- vec3 vSigmaS = dFdx(surf_pos);
- vec3 vSigmaT = dFdy(surf_pos);
- vec3 vN = surf_norm; /* normalized interpolated vertex normal */
-
- vR1 = cross(vSigmaT, vN);
- vR2 = cross(vN, vSigmaS);
- fDet = dot(vSigmaS, vR1);
-
- float fMagnitude = abs(fDet);
- vNacc_out = vNacc_in * (fMagnitude / fPrevMagnitude_in);
- fPrevMagnitude_out = fMagnitude;
-}
-
-void mtex_bump_tap3(
- vec3 texco, sampler2D ima, float hScale,
- out float dBs, out float dBt)
-{
- vec2 STll = texco.xy;
- vec2 STlr = texco.xy + dFdx(texco.xy);
- 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);
-
- dBs = hScale * (Hlr - Hll);
- dBt = hScale * (Hul - Hll);
-}
-
-#ifdef BUMP_BICUBIC
-
-void mtex_bump_bicubic(
- vec3 texco, sampler2D ima, float hScale,
- out float dBs, out float dBt )
-{
- float Hl;
- float Hr;
- float Hd;
- float Hu;
-
- vec2 TexDx = dFdx(texco.xy);
- vec2 TexDy = dFdy(texco.xy);
-
- vec2 STl = texco.xy - 0.5 * TexDx;
- vec2 STr = texco.xy + 0.5 * TexDx;
- 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);
-
- vec2 dHdxy = vec2(Hr - Hl, Hu - Hd);
- float fBlend = clamp(1.0 - textureQueryLOD(ima, texco.xy).x, 0.0, 1.0);
- if (fBlend != 0.0) {
- // the derivative of the bicubic sampling of level 0
- ivec2 vDim;
- vDim = textureSize(ima, 0);
-
- // taking the fract part of the texture coordinate is a hardcoded wrap mode.
- // this is acceptable as textures use wrap mode exclusively in 3D view elsewhere in blender.
- // this is done so that we can still get a valid texel with uvs outside the 0,1 range
- // by texelFetch below, as coordinates are clamped when using this function.
- vec2 fTexLoc = vDim * fract(texco.xy) - vec2(0.5, 0.5);
- ivec2 iTexLoc = ivec2(floor(fTexLoc));
- vec2 t = clamp(fTexLoc - iTexLoc, 0.0, 1.0); // sat just to be pedantic
-
-/*******************************************************************************************
- * This block will replace the one below when one channel textures are properly supported. *
- *******************************************************************************************
- vec4 vSamplesUL = textureGather(ima, (iTexLoc+ivec2(-1,-1) + vec2(0.5,0.5))/vDim);
- vec4 vSamplesUR = textureGather(ima, (iTexLoc+ivec2(1,-1) + vec2(0.5,0.5))/vDim);
- vec4 vSamplesLL = textureGather(ima, (iTexLoc+ivec2(-1,1) + vec2(0.5,0.5))/vDim);
- vec4 vSamplesLR = textureGather(ima, (iTexLoc+ivec2(1,1) + vec2(0.5,0.5))/vDim);
-
- mat4 H = mat4(vSamplesUL.w, vSamplesUL.x, vSamplesLL.w, vSamplesLL.x,
- vSamplesUL.z, vSamplesUL.y, vSamplesLL.z, vSamplesLL.y,
- vSamplesUR.w, vSamplesUR.x, vSamplesLR.w, vSamplesLR.x,
- vSamplesUR.z, vSamplesUR.y, vSamplesLR.z, vSamplesLR.y);
- */
- ivec2 iTexLocMod = iTexLoc + ivec2(-1, -1);
-
- mat4 H;
-
- for (int i = 0; i < 4; i++) {
- for (int j = 0; j < 4; j++) {
- ivec2 iTexTmp = iTexLocMod + ivec2(i, j);
-
- // wrap texture coordinates manually for texelFetch to work on uvs oitside the 0,1 range.
- // this is guaranteed to work since we take the fractional part of the uv above.
- iTexTmp.x = (iTexTmp.x < 0) ? iTexTmp.x + vDim.x : ((iTexTmp.x >= vDim.x) ? iTexTmp.x - vDim.x : iTexTmp.x);
- iTexTmp.y = (iTexTmp.y < 0) ? iTexTmp.y + vDim.y : ((iTexTmp.y >= vDim.y) ? iTexTmp.y - vDim.y : iTexTmp.y);
-
- rgbtobw(texelFetch(ima, iTexTmp, 0), H[i][j]);
- }
- }
-
- float x = t.x, y = t.y;
- float x2 = x * x, x3 = x2 * x, y2 = y * y, y3 = y2 * y;
-
- vec4 X = vec4(-0.5 * (x3 + x) + x2, 1.5 * x3 - 2.5 * x2 + 1, -1.5 * x3 + 2 * x2 + 0.5 * x, 0.5 * (x3 - x2));
- vec4 Y = vec4(-0.5 * (y3 + y) + y2, 1.5 * y3 - 2.5 * y2 + 1, -1.5 * y3 + 2 * y2 + 0.5 * y, 0.5 * (y3 - y2));
- vec4 dX = vec4(-1.5 * x2 + 2 * x - 0.5, 4.5 * x2 - 5 * x, -4.5 * x2 + 4 * x + 0.5, 1.5 * x2 - x);
- vec4 dY = vec4(-1.5 * y2 + 2 * y - 0.5, 4.5 * y2 - 5 * y, -4.5 * y2 + 4 * y + 0.5, 1.5 * y2 - y);
-
- // complete derivative in normalized coordinates (mul by vDim)
- vec2 dHdST = vDim * vec2(dot(Y, H * dX), dot(dY, H * X));
-
- // transform derivative to screen-space
- vec2 dHdxy_bicubic = vec2(dHdST.x * TexDx.x + dHdST.y * TexDx.y,
- dHdST.x * TexDy.x + dHdST.y * TexDy.y);
-
- // blend between the two
- dHdxy = dHdxy * (1 - fBlend) + dHdxy_bicubic * fBlend;
- }
-
- dBs = hScale * dHdxy.x;
- dBt = hScale * dHdxy.y;
-}
-
-#endif
-
-void mtex_bump_tap5(
- vec3 texco, sampler2D ima, float hScale,
- out float dBs, out float dBt)
-{
- vec2 TexDx = dFdx(texco.xy);
- vec2 TexDy = dFdy(texco.xy);
-
- vec2 STc = texco.xy;
- vec2 STl = texco.xy - 0.5 * TexDx;
- vec2 STr = texco.xy + 0.5 * TexDx;
- vec2 STd = texco.xy - 0.5 * TexDy;
- 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);
-
- dBs = hScale * (Hr - Hl);
- dBt = hScale * (Hu - Hd);
-}
-
-void mtex_bump_deriv(
- vec3 texco, sampler2D ima, float ima_x, float ima_y, float hScale,
- out float dBs, out float dBt)
-{
- float s = 1.0; // negate this if flipped texture coordinate
- vec2 TexDx = dFdx(texco.xy);
- vec2 TexDy = dFdy(texco.xy);
-
- // 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);
-
- dBs = dBduv.x * TexDx.x + s * dBduv.y * TexDx.y;
- dBt = dBduv.x * TexDy.x + s * dBduv.y * TexDy.y;
-}
-
-void mtex_bump_apply(
- float fDet, float dBs, float dBt, vec3 vR1, vec3 vR2, vec3 vNacc_in,
- out vec3 vNacc_out, out vec3 perturbed_norm)
-{
- vec3 vSurfGrad = sign(fDet) * (dBs * vR1 + dBt * vR2);
-
- vNacc_out = vNacc_in - vSurfGrad;
- perturbed_norm = normalize(vNacc_out);
-}
-
-void mtex_bump_apply_texspace(
- float fDet, float dBs, float dBt, vec3 vR1, vec3 vR2,
- sampler2D ima, vec3 texco, float ima_x, float ima_y, vec3 vNacc_in,
- out vec3 vNacc_out, out vec3 perturbed_norm)
-{
- vec2 TexDx = dFdx(texco.xy);
- vec2 TexDy = dFdy(texco.xy);
-
- vec3 vSurfGrad = sign(fDet) * (
- dBs / length(vec2(ima_x * TexDx.x, ima_y * TexDx.y)) * vR1 +
- dBt / length(vec2(ima_x * TexDy.x, ima_y * TexDy.y)) * vR2);
-
- vNacc_out = vNacc_in - vSurfGrad;
- perturbed_norm = normalize(vNacc_out);
-}
-
-void mtex_negate_texnormal(vec3 normal, out vec3 outnormal)
-{
- outnormal = vec3(-normal.x, -normal.y, normal.z);
-}
-
-void mtex_nspace_tangent(vec4 tangent, vec3 normal, vec3 texnormal, out vec3 outnormal)
-{
- vec3 B = tangent.w * cross(normal, tangent.xyz);
-
- outnormal = texnormal.x * tangent.xyz + texnormal.y * B + texnormal.z * normal;
- outnormal = normalize(outnormal);
-}
-
-void mtex_nspace_world(mat4 viewmat, vec3 texnormal, out vec3 outnormal)
-{
- outnormal = normalize((viewmat * vec4(texnormal, 0.0)).xyz);
-}
-
-void mtex_nspace_object(vec3 texnormal, out vec3 outnormal)
-{
- outnormal = normalize(gl_NormalMatrix * texnormal);
-}
-
-void mtex_blend_normal(float norfac, vec3 normal, vec3 newnormal, out vec3 outnormal)
-{
- outnormal = (1.0 - norfac) * normal + norfac * newnormal;
- outnormal = normalize(outnormal);
-}
-
-/******* MATERIAL *********/
-
-void lamp_visibility_sun_hemi(vec3 lampvec, out vec3 lv, out float dist, out float visifac)
-{
- lv = lampvec;
- dist = 1.0;
- visifac = 1.0;
-}
-
-void lamp_visibility_other(vec3 co, vec3 lampco, out vec3 lv, out float dist, out float visifac)
-{
- lv = co - lampco;
- dist = length(lv);
- lv = normalize(lv);
- visifac = 1.0;
-}
-
-void lamp_falloff_invlinear(float lampdist, float dist, out float visifac)
-{
- visifac = lampdist / (lampdist + dist);
-}
-
-void lamp_falloff_invsquare(float lampdist, float dist, out float visifac)
-{
- visifac = lampdist / (lampdist + dist * dist);
-}
-
-void lamp_falloff_sliders(float lampdist, float ld1, float ld2, float dist, out float visifac)
-{
- float lampdistkw = lampdist * lampdist;
-
- visifac = lampdist / (lampdist + ld1 * dist);
- visifac *= lampdistkw / (lampdistkw + ld2 * dist * dist);
-}
-
-void lamp_falloff_invcoefficients(float coeff_const, float coeff_lin, float coeff_quad, float dist, out float visifac)
-{
- vec3 coeff = vec3(coeff_const, coeff_lin, coeff_quad);
- vec3 d_coeff = vec3(1.0, dist, dist * dist);
- float visifac_r = dot(coeff, d_coeff);
- if (visifac_r > 0.0)
- visifac = 1.0 / visifac_r;
- else
- visifac = 0.0;
-}
-
-void lamp_falloff_curve(float lampdist, sampler2D curvemap, float dist, out float visifac)
-{
- visifac = texture2D(curvemap, vec2(dist / lampdist, 0.0)).x;
-}
-
-void lamp_visibility_sphere(float lampdist, float dist, float visifac, out float outvisifac)
-{
- float t = lampdist - dist;
-
- outvisifac = visifac * max(t, 0.0) / lampdist;
-}
-
-void lamp_visibility_spot_square(vec3 lampvec, mat4 lampimat, vec2 scale, vec3 lv, out float inpr)
-{
- if (dot(lv, lampvec) > 0.0) {
- vec3 lvrot = (lampimat * vec4(lv, 0.0)).xyz;
- /* without clever non-uniform scale, we could do: */
- // float x = max(abs(lvrot.x / lvrot.z), abs(lvrot.y / lvrot.z));
- float x = max(abs((lvrot.x / scale.x) / lvrot.z), abs((lvrot.y / scale.y) / lvrot.z));
-
- inpr = 1.0 / sqrt(1.0 + x * x);
- }
- else
- inpr = 0.0;
-}
-
-void lamp_visibility_spot_circle(vec3 lampvec, mat4 lampimat, vec2 scale, vec3 lv, out float inpr)
-{
- /* without clever non-uniform scale, we could do: */
- // inpr = dot(lv, lampvec);
- if (dot(lv, lampvec) > 0.0) {
- vec3 lvrot = (lampimat * vec4(lv, 0.0)).xyz;
- float x = abs(lvrot.x / lvrot.z);
- float y = abs(lvrot.y / lvrot.z);
-
- float ellipse = abs((x * x) / (scale.x * scale.x) + (y * y) / (scale.y * scale.y));
-
- inpr = 1.0 / sqrt(1.0 + ellipse);
- }
- else
- inpr = 0.0;
-}
-
-void lamp_visibility_spot(float spotsi, float spotbl, float inpr, float visifac, out float outvisifac)
-{
- float t = spotsi;
-
- if (inpr <= t) {
- outvisifac = 0.0;
- }
- else {
- t = inpr - t;
-
- /* soft area */
- if (spotbl != 0.0)
- inpr *= smoothstep(0.0, 1.0, t / spotbl);
-
- outvisifac = visifac * inpr;
- }
-}
-
-void lamp_visibility_clamp(float visifac, out float outvisifac)
-{
- outvisifac = (visifac < 0.001) ? 0.0 : visifac;
-}
-
-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);
-}
-
-void world_zen_mapping(vec3 view, float zenup, float zendown, out float zenfac)
-{
- if (view.z >= 0.0)
- zenfac = zenup;
- else
- zenfac = zendown;
-}
-
-void world_blend_paper_real(vec3 vec, out float blend)
-{
- blend = abs(vec.y);
-}
-
-void world_blend_paper(vec3 vec, out float blend)
-{
- blend = (vec.y + 1.0) * 0.5;
-}
-
-void world_blend_real(vec3 vec, out float blend)
-{
- blend = abs(normalize(vec).z);
-}
-
-void world_blend(vec3 vec, out float blend)
-{
- blend = (normalize(vec).z + 1) * 0.5;
-}
-
-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);
-}
-
-void shade_tangent_v(vec3 lv, vec3 tang, out vec3 vn)
-{
- vec3 c = cross(lv, tang);
- vec3 vnor = cross(c, tang);
-
- vn = -normalize(vnor);
-}
-
-void shade_inp(vec3 vn, vec3 lv, out float inp)
-{
- inp = dot(vn, lv);
-}
-
-void shade_is_no_diffuse(out float is)
-{
- is = 0.0;
-}
-
-void shade_is_hemi(float inp, out float is)
-{
- is = 0.5 * inp + 0.5;
-}
-
-float area_lamp_energy(mat4 area, vec3 co, vec3 vn)
-{
- vec3 vec[4], c[4];
- float rad[4], fac;
-
- vec[0] = normalize(co - area[0].xyz);
- vec[1] = normalize(co - area[1].xyz);
- vec[2] = normalize(co - area[2].xyz);
- vec[3] = normalize(co - area[3].xyz);
-
- c[0] = normalize(cross(vec[0], vec[1]));
- c[1] = normalize(cross(vec[1], vec[2]));
- c[2] = normalize(cross(vec[2], vec[3]));
- c[3] = normalize(cross(vec[3], vec[0]));
-
- rad[0] = acos(dot(vec[0], vec[1]));
- rad[1] = acos(dot(vec[1], vec[2]));
- rad[2] = acos(dot(vec[2], vec[3]));
- rad[3] = acos(dot(vec[3], vec[0]));
-
- fac = rad[0] * dot(vn, c[0]);
- fac += rad[1] * dot(vn, c[1]);
- fac += rad[2] * dot(vn, c[2]);
- fac += rad[3] * dot(vn, c[3]);
-
- return max(fac, 0.0);
-}
-
-void shade_inp_area(
- vec3 position, vec3 lampco, vec3 lampvec, vec3 vn, mat4 area, float areasize, float k,
- out float inp)
-{
- vec3 co = position;
- vec3 vec = co - lampco;
-
- if (dot(vec, lampvec) < 0.0) {
- inp = 0.0;
- }
- else {
- float intens = area_lamp_energy(area, co, vn);
-
- inp = pow(intens * areasize, k);
- }
-}
-
-void shade_diffuse_oren_nayer(float nl, vec3 n, vec3 l, vec3 v, float rough, out float is)
-{
- vec3 h = normalize(v + l);
- float nh = max(dot(n, h), 0.0);
- float nv = max(dot(n, v), 0.0);
- float realnl = dot(n, l);
-
- if (realnl < 0.0) {
- is = 0.0;
- }
- else if (nl < 0.0) {
- is = 0.0;
- }
- else {
- float vh = max(dot(v, h), 0.0);
- float Lit_A = acos(realnl);
- float View_A = acos(nv);
-
- vec3 Lit_B = normalize(l - realnl * n);
- vec3 View_B = normalize(v - nv * n);
-
- float t = max(dot(Lit_B, View_B), 0.0);
-
- float a, b;
-
- if (Lit_A > View_A) {
- a = Lit_A;
- b = View_A;
- }
- else {
- a = View_A;
- b = Lit_A;
- }
-
- float A = 1.0 - (0.5 * ((rough * rough) / ((rough * rough) + 0.33)));
- float B = 0.45 * ((rough * rough) / ((rough * rough) + 0.09));
-
- b *= 0.95;
- is = nl * (A + (B * t * sin(a) * tan(b)));
- }
-}
-
-void shade_diffuse_toon(vec3 n, vec3 l, vec3 v, float size, float tsmooth, out float is)
-{
- float rslt = dot(n, l);
- float ang = acos(rslt);
-
- if (ang < size) is = 1.0;
- else if (ang > (size + tsmooth) || tsmooth == 0.0) is = 0.0;
- else is = 1.0 - ((ang - size) / tsmooth);
-}
-
-void shade_diffuse_minnaert(float nl, vec3 n, vec3 v, float darkness, out float is)
-{
- if (nl <= 0.0) {
- is = 0.0;
- }
- else {
- float nv = max(dot(n, v), 0.0);
-
- if (darkness <= 1.0)
- is = nl * pow(max(nv * nl, 0.1), darkness - 1.0);
- else
- is = nl * pow(1.0001 - nv, darkness - 1.0);
- }
-}
-
-float fresnel_fac(vec3 view, vec3 vn, float grad, float fac)
-{
- float t1, t2;
- float ffac;
-
- if (fac == 0.0) {
- ffac = 1.0;
- }
- else {
- t1 = dot(view, vn);
- if (t1 > 0.0) t2 = 1.0 + t1;
- else t2 = 1.0 - t1;
-
- t2 = grad + (1.0 - grad) * pow(t2, fac);
-
- if (t2 < 0.0) ffac = 0.0;
- else if (t2 > 1.0) ffac = 1.0;
- else ffac = t2;
- }
-
- return ffac;
-}
-
-void shade_diffuse_fresnel(vec3 vn, vec3 lv, vec3 view, float fac_i, float fac, out float is)
-{
- is = fresnel_fac(lv, vn, fac_i, fac);
-}
-
-void shade_cubic(float is, out float outis)
-{
- if (is > 0.0 && is < 1.0)
- outis = smoothstep(0.0, 1.0, is);
- else
- outis = is;
-}
-
-void shade_visifac(float i, float visifac, float refl, out float outi)
-{
- /*if (i > 0.0)*/
- outi = max(i * visifac * refl, 0.0);
- /*else
- outi = i;*/
-}
-
-void shade_tangent_v_spec(vec3 tang, out vec3 vn)
-{
- vn = tang;
-}
-
-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);
-}
-
-void shade_hemi_spec(vec3 vn, vec3 lv, vec3 view, float spec, float hard, float visifac, out float t)
-{
- lv += view;
- lv = normalize(lv);
-
- t = dot(vn, lv);
- t = 0.5 * t + 0.5;
-
- t = visifac * spec * pow(t, hard);
-}
-
-void shade_phong_spec(vec3 n, vec3 l, vec3 v, float hard, out float specfac)
-{
- vec3 h = normalize(l + v);
- float rslt = max(dot(h, n), 0.0);
-
- specfac = pow(rslt, hard);
-}
-
-void shade_cooktorr_spec(vec3 n, vec3 l, vec3 v, float hard, out float specfac)
-{
- vec3 h = normalize(v + l);
- float nh = dot(n, h);
-
- if (nh < 0.0) {
- specfac = 0.0;
- }
- else {
- float nv = max(dot(n, v), 0.0);
- float i = pow(nh, hard);
-
- i = i / (0.1 + nv);
- specfac = i;
- }
-}
-
-void shade_blinn_spec(vec3 n, vec3 l, vec3 v, float refrac, float spec_power, out float specfac)
-{
- if (refrac < 1.0) {
- specfac = 0.0;
- }
- else if (spec_power == 0.0) {
- specfac = 0.0;
- }
- else {
- if (spec_power < 100.0)
- spec_power = sqrt(1.0 / spec_power);
- else
- spec_power = 10.0 / spec_power;
-
- vec3 h = normalize(v + l);
- float nh = dot(n, h);
- if (nh < 0.0) {
- specfac = 0.0;
- }
- else {
- float nv = max(dot(n, v), 0.01);
- float nl = dot(n, l);
- if (nl <= 0.01) {
- specfac = 0.0;
- }
- else {
- float vh = max(dot(v, h), 0.01);
-
- float a = 1.0;
- float b = (2.0 * nh * nv) / vh;
- float c = (2.0 * nh * nl) / vh;
-
- float g = 0.0;
-
- if (a < b && a < c) g = a;
- else if (b < a && b < c) g = b;
- else if (c < a && c < b) g = c;
-
- float p = sqrt(((refrac * refrac) + (vh * vh) - 1.0));
- float f = ((((p - vh) * (p - vh)) / ((p + vh) * (p + vh))) *
- (1.0 + ((((vh * (p + vh)) - 1.0) * ((vh * (p + vh)) - 1.0)) /
- (((vh * (p - vh)) + 1.0) * ((vh * (p - vh)) + 1.0)))));
- float ang = acos(nh);
-
- specfac = max(f * g * exp_blender((-(ang * ang) / (2.0 * spec_power * spec_power))), 0.0);
- }
- }
- }
-}
-
-void shade_wardiso_spec(vec3 n, vec3 l, vec3 v, float rms, out float specfac)
-{
- vec3 h = normalize(l + v);
- float nh = max(dot(n, h), 0.001);
- float nv = max(dot(n, v), 0.001);
- float nl = max(dot(n, l), 0.001);
- float angle = tan(acos(nh));
- float alpha = max(rms, 0.001);
-
- specfac = nl * (1.0 / (4.0 * M_PI * alpha * alpha)) * (exp_blender(-(angle * angle) / (alpha * alpha)) / (sqrt(nv * nl)));
-}
-
-void shade_toon_spec(vec3 n, vec3 l, vec3 v, float size, float tsmooth, out float specfac)
-{
- vec3 h = normalize(l + v);
- float rslt = dot(h, n);
- float ang = acos(rslt);
-
- if (ang < size) rslt = 1.0;
- else if (ang >= (size + tsmooth) || tsmooth == 0.0) rslt = 0.0;
- else rslt = 1.0 - ((ang - size) / tsmooth);
-
- specfac = rslt;
-}
-
-void shade_spec_area_inp(float specfac, float inp, out float outspecfac)
-{
- outspecfac = specfac * inp;
-}
-
-void shade_spec_t(float shadfac, float spec, float visifac, float specfac, out float t)
-{
- t = shadfac * spec * visifac * specfac;
-}
-
-void shade_add_spec(float t, vec3 lampcol, vec3 speccol, out vec3 outcol)
-{
- outcol = t * lampcol * speccol;
-}
-
-void shade_add_mirror(vec3 mir, vec4 refcol, vec3 combined, out vec3 result)
-{
- result = mir * refcol.gba + (vec3(1.0) - mir * refcol.rrr) * combined;
-}
-
-void alpha_spec_correction(vec3 spec, float spectra, float alpha, out float outalpha)
-{
- if (spectra > 0.0) {
- float t = clamp(max(max(spec.r, spec.g), spec.b) * spectra, 0.0, 1.0);
- outalpha = (1.0 - t) * alpha + t;
- }
- else {
- outalpha = alpha;
- }
-}
-
-void shade_add(vec4 col1, vec4 col2, out vec4 outcol)
-{
- outcol = col1 + col2;
-}
-
-void shade_madd(vec4 col, vec4 col1, vec4 col2, out vec4 outcol)
-{
- outcol = col + col1 * col2;
-}
-
-void shade_add_clamped(vec4 col1, vec4 col2, out vec4 outcol)
-{
- outcol = col1 + max(col2, vec4(0.0, 0.0, 0.0, 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));
-}
-
-void env_apply(vec4 col, vec3 hor, vec3 zen, vec4 f, mat4 vm, vec3 vn, out vec4 outcol)
-{
- vec3 vv = normalize(vm[2].xyz);
- float skyfac = 0.5 * (1.0 + dot(vn, -vv));
- outcol = col + f * vec4(mix(hor, zen, skyfac), 0);
-}
-
-void shade_maddf(vec4 col, float f, vec4 col1, out vec4 outcol)
-{
- outcol = col + f * col1;
-}
-
-void shade_mul(vec4 col1, vec4 col2, out vec4 outcol)
-{
- outcol = col1 * col2;
-}
-
-void shade_mul_value(float fac, vec4 col, out vec4 outcol)
-{
- outcol = col * fac;
-}
-
-void shade_mul_value_v3(float fac, vec3 col, out vec3 outcol)
-{
- outcol = col * fac;
-}
-
-void shade_obcolor(vec4 col, vec4 obcol, out vec4 outcol)
-{
- outcol = vec4(col.rgb * obcol.rgb, col.a);
-}
-
-void ramp_rgbtobw(vec3 color, out float outval)
-{
- outval = color.r * 0.3 + color.g * 0.58 + color.b * 0.12;
-}
-
-void shade_only_shadow(float i, float shadfac, float energy, vec3 shadcol, out vec3 outshadrgb)
-{
- outshadrgb = i * energy * (1.0 - shadfac) * (vec3(1.0) - shadcol);
-}
-
-void shade_only_shadow_diffuse(vec3 shadrgb, vec3 rgb, vec4 diff, out vec4 outdiff)
-{
- outdiff = diff - vec4(rgb * shadrgb, 0.0);
-}
-
-void shade_only_shadow_specular(vec3 shadrgb, vec3 specrgb, vec4 spec, out vec4 outspec)
-{
- outspec = spec - vec4(specrgb * shadrgb, 0.0);
-}
-
-void shade_clamp_positive(vec4 col, out vec4 outcol)
-{
- outcol = max(col, vec4(0.0));
-}
-
-void test_shadowbuf(
- vec3 rco, sampler2DShadow shadowmap, mat4 shadowpersmat, float shadowbias, float inp,
- out float result)
-{
- if (inp <= 0.0) {
- result = 0.0;
- }
- else {
- vec4 co = shadowpersmat * vec4(rco, 1.0);
-
- //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
- result = 1.0;
- }
-}
-
-void test_shadowbuf_vsm(
- vec3 rco, sampler2D shadowmap, mat4 shadowpersmat, float shadowbias, float bleedbias, float inp,
- out float result)
-{
- if (inp <= 0.0) {
- result = 0.0;
- }
- 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;
- float dist = co.z / co.w;
- float p = 0.0;
-
- if (dist <= moments.x)
- p = 1.0;
-
- float variance = moments.y - (moments.x * moments.x);
- variance = max(variance, shadowbias / 10.0);
-
- float d = moments.x - dist;
- float p_max = variance / (variance + d * d);
-
- // Now reduce light-bleeding by removing the [0, x] tail and linearly rescaling (x, 1]
- p_max = clamp((p_max - bleedbias) / (1.0 - bleedbias), 0.0, 1.0);
-
- result = max(p, p_max);
- }
- else {
- result = 1.0;
- }
- }
-}
-
-void shadows_only(
- vec3 rco, sampler2DShadow shadowmap, mat4 shadowpersmat,
- float shadowbias, vec3 shadowcolor, float inp,
- out vec3 result)
-{
- result = vec3(1.0);
-
- if (inp > 0.0) {
- float shadfac;
-
- test_shadowbuf(rco, shadowmap, shadowpersmat, shadowbias, inp, shadfac);
- result -= (1.0 - shadfac) * (vec3(1.0) - shadowcolor);
- }
-}
-
-void shadows_only_vsm(
- vec3 rco, sampler2D shadowmap, mat4 shadowpersmat,
- float shadowbias, float bleedbias, vec3 shadowcolor, float inp,
- out vec3 result)
-{
- result = vec3(1.0);
-
- if (inp > 0.0) {
- float shadfac;
-
- test_shadowbuf_vsm(rco, shadowmap, shadowpersmat, shadowbias, bleedbias, inp, shadfac);
- result -= (1.0 - shadfac) * (vec3(1.0) - shadowcolor);
- }
-}
-
-void shade_light_texture(vec3 rco, sampler2D cookie, mat4 shadowpersmat, out vec4 result)
-{
-
- vec4 co = shadowpersmat * vec4(rco, 1.0);
-
- result = texture2DProj(cookie, co);
-}
-
-void shade_exposure_correct(vec3 col, float linfac, float logfac, out vec3 outcol)
-{
- outcol = linfac * (1.0 - exp(col * logfac));
-}
-
-void shade_mist_factor(
- vec3 co, float enable, float miststa, float mistdist, float misttype, float misi,
- out float outfac)
-{
- if (enable == 1.0) {
- float fac, zcor;
-
- zcor = (gl_ProjectionMatrix[3][3] == 0.0) ? length(co) : -co[2];
-
- fac = clamp((zcor - miststa) / mistdist, 0.0, 1.0);
- if (misttype == 0.0) fac *= fac;
- else if (misttype == 1.0) ;
- else fac = sqrt(fac);
-
- outfac = 1.0 - (1.0 - fac) * (1.0 - misi);
- }
- else {
- outfac = 0.0;
- }
-}
-
-void shade_world_mix(vec3 hor, vec4 col, out vec4 outcol)
-{
- float fac = clamp(col.a, 0.0, 1.0);
- outcol = vec4(mix(hor, col.rgb, fac), col.a);
-}
-
-void shade_alpha_opaque(vec4 col, out vec4 outcol)
-{
- outcol = vec4(col.rgb, 1.0);
-}
-
-void shade_alpha_obcolor(vec4 col, vec4 obcol, out vec4 outcol)
-{
- outcol = vec4(col.rgb, col.a * obcol.a);
-}
-
/*********** NEW SHADER UTILITIES **************/
float fresnel_dielectric_0(float eta)
@@ -2428,7 +934,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)
@@ -2441,7 +955,6 @@ int quick_floor(float x)
return int(x) - ((x < 0) ? 1 : 0);
}
-#ifdef BIT_OPERATIONS
float integer_noise(int n)
{
int nn;
@@ -2505,7 +1018,6 @@ vec3 cellnoise_color(vec3 p)
return vec3(r, g, b);
}
-#endif // BIT_OPERATIONS
float floorfrac(float x, out int i)
{
@@ -2513,317 +1025,346 @@ float floorfrac(float x, out int i)
return x - i;
}
+/* bsdfs */
-/* Principled BSDF operations */
-
-float sqr(float a)
+void convert_metallic_to_specular_tinted(
+ vec3 basecol, float metallic, float specular_fac, float specular_tint,
+ out vec3 diffuse, out vec3 f0)
{
- return a*a;
+ 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);
}
-float schlick_fresnel(float u)
+#ifndef VOLUMETRICS
+void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out Closure result)
{
- float m = clamp(1.0 - u, 0.0, 1.0);
- float m2 = m * m;
- return m2 * m2 * m; // pow(m,5)
+ 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;
}
-float GTR1(float NdotH, float a)
+void node_bsdf_glossy(vec4 color, float roughness, vec3 N, float ssr_id, out Closure result)
{
- if (a >= 1.0) {
- return M_1_PI;
- }
-
- a = max(a, 0.001);
- float a2 = a*a;
- float t = 1.0 + (a2 - 1.0) * NdotH*NdotH;
- return (a2 - 1.0) / (M_PI * log(a2) * t);
+ vec3 out_spec, ssr_spec;
+ 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);
}
-float GTR2(float NdotH, float a)
+void node_bsdf_anisotropic(
+ vec4 color, float roughness, float anisotropy, float rotation, vec3 N, vec3 T,
+ out Closure result)
{
- float a2 = a*a;
- float t = 1.0 + (a2 - 1.0) * NdotH*NdotH;
- return a2 / (M_PI * t*t);
+ node_bsdf_diffuse(color, 0.0, N, result);
}
-float GTR2_aniso(float NdotH, float HdotX, float HdotY, float ax, float ay)
+void node_bsdf_glass(vec4 color, float roughness, float ior, vec3 N, float ssr_id, out Closure result)
{
- return 1.0 / (M_PI * ax*ay * sqr(sqr(HdotX / ax) + sqr(HdotY / ay) + NdotH*NdotH));
+ vec3 out_spec, out_refr, ssr_spec;
+ 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);
}
-float smithG_GGX(float NdotV, float alphaG)
+void node_bsdf_toon(vec4 color, float size, float tsmooth, vec3 N, out Closure result)
{
- float a = alphaG*alphaG;
- float b = NdotV*NdotV;
- return 1.0 / (NdotV + sqrt(a + b - a * b));
+ node_bsdf_diffuse(color, 0.0, N, result);
}
-vec3 rotate_vector(vec3 p, vec3 n, float theta) {
- return (
- p * cos(theta) + cross(n, p) *
- sin(theta) + n * dot(p, n) *
- (1.0 - cos(theta))
- );
-}
+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)
+{
+ 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);
-/*********** NEW SHADER NODES ***************/
+ transmission *= 1.0 - metallic;
+ subsurface *= 1.0 - metallic;
-#define NUM_LIGHTS 3
+ clearcoat *= 0.25;
+ clearcoat *= 1.0 - transmission;
-/* bsdfs */
+#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
+}
-void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out vec4 result)
+void node_bsdf_translucent(vec4 color, vec3 N, out Closure result)
{
- /* 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;
-
- float bsdf = max(dot(N, light_position), 0.0);
- L += light_diffuse * bsdf;
- }
-
- result = vec4(L * color.rgb, 1.0);
+ node_bsdf_diffuse(color, 0.0, -N, result);
}
-void node_bsdf_glossy(vec4 color, float roughness, vec3 N, out vec4 result)
+void node_bsdf_transparent(vec4 color, out Closure result)
{
- /* 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 H = gl_LightSource[i].halfVector.xyz;
- vec3 light_diffuse = gl_LightSource[i].diffuse.rgb;
- vec3 light_specular = gl_LightSource[i].specular.rgb;
-
- /* we mix in some diffuse so low roughness still shows up */
- float r2 = roughness * roughness;
- float bsdf = 0.5 * pow(max(dot(N, H), 0.0), 1.0 / r2);
- bsdf += 0.5 * max(dot(N, light_position), 0.0);
- L += light_specular * bsdf;
- }
-
- result = vec4(L * color.rgb, 1.0);
+ /* this isn't right */
+ result = CLOSURE_DEFAULT;
+ result.radiance = vec3(0.0);
+ result.opacity = 0.0;
+ result.ssr_id = TRANSPARENT_CLOSURE_FLAG;
}
-void node_bsdf_anisotropic(
- vec4 color, float roughness, float anisotropy, float rotation, vec3 N, vec3 T,
- 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_bsdf_glass(vec4 color, float roughness, float ior, vec3 N, out vec4 result)
-{
+void node_subsurface_scattering(
+ vec4 color, float scale, vec3 radius, float sharpen, float texture_blur, vec3 N, float sss_id,
+ out Closure result)
+{
+#if 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_toon(vec4 color, float size, float tsmooth, vec3 N, out vec4 result)
+void node_bsdf_refraction(vec4 color, float roughness, float ior, vec3 N, out Closure result)
{
- node_bsdf_diffuse(color, 0.0, N, result);
+ vec3 out_refr;
+ color.rgb *= (refractionDepth > 0.0) ? color.rgb : vec3(1.0); /* Simulate 2 absorption event. */
+ 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;
}
-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)
+void node_ambient_occlusion(vec4 color, float distance, vec3 normal, out vec4 result_color, out float result_ao)
{
- /* 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));
-
- 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);
-
- /* fresnel normalization parameters */
- float F0 = fresnel_dielectric_0(eta);
- float F0_norm = 1.0 / (1.0 - F0);
-
- /* directional lights */
- for (int i = 0; i < NUM_LIGHTS; i++) {
- vec3 light_position_world = gl_LightSource[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;
-
- float NdotL = dot(N, light_position);
- float NdotV = dot(N, V);
- float LdotH = dot(light_position, H);
-
- vec3 diffuse_and_specular_bsdf = vec3(0.0);
- 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.
-
- 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);
- vec3 Csheen = mix(vec3(1.0), Ctint, sheen_tint);
-
- // Diffuse fresnel - go from 1 at normal incidence to .5 at grazing
- // and mix in diffuse retro-reflection based on roughness
-
- float FL = schlick_fresnel(NdotL), FV = schlick_fresnel(NdotV);
- float Fd90 = 0.5 + 2.0 * LdotH*LdotH * roughness;
- float Fd = mix(1.0, Fd90, FL) * mix(1.0, Fd90, FV);
-
- // Based on Hanrahan-Krueger brdf approximation of isotropic bssrdf
- // 1.25 scale is used to (roughly) preserve albedo
- // Fss90 used to "flatten" retroreflection based on roughness
- float Fss90 = LdotH*LdotH * roughness;
- float Fss = mix(1.0, Fss90, FL) * mix(1.0, Fss90, FV);
- 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);
- float roughg = sqr(roughness * 0.5 + 0.5);
- float Gs = smithG_GGX(NdotL, roughg) * smithG_GGX(NdotV, roughg);
-
- // sheen
- vec3 Fsheen = schlick_fresnel(LdotH) * sheen * Csheen;
-
- vec3 diffuse_bsdf = (mix(Fd * base_color.rgb, ss * subsurface_color.rgb, subsurface) + Fsheen) * light_diffuse;
- vec3 specular_bsdf = Gs * Fs * Ds * light_specular;
- diffuse_and_specular_bsdf = diffuse_bsdf * (1.0 - metallic) + specular_bsdf;
- }
- diffuse_and_specular_bsdf *= max(NdotL, 0.0);
+ vec3 bent_normal;
+ vec4 rand = texelFetch(utilTex, ivec3(ivec2(gl_FragCoord.xy) % LUT_SIZE, 2.0), 0);
+ result_ao = occlusion_compute(normalize(normal), viewPosition, 1.0, rand, bent_normal);
+ result_color = result_ao * color;
+}
- float CNdotL = dot(CN, light_position);
- float CNdotV = dot(CN, V);
+#endif /* VOLUMETRICS */
- vec3 clearcoat_bsdf = vec3(0.0);
- if (CNdotL >= 0.0 && CNdotV >= 0.0 && clearcoat > 0.0) {
- float CNdotH = dot(CN, H);
- //float FH = schlick_fresnel(LdotH);
+/* emission */
- // clearcoat (ior = 1.5 -> F0 = 0.04)
- float Dr = GTR1(CNdotH, sqr(clearcoat_roughness));
- float Fr = fresnel_dielectric_cos(LdotH, 1.5); //mix(0.04, 1.0, FH);
- float Gr = smithG_GGX(CNdotL, 0.25) * smithG_GGX(CNdotV, 0.25);
+void node_emission(vec4 color, float strength, vec3 vN, out Closure result)
+{
+#ifndef VOLUMETRICS
+ color *= strength;
+ result = CLOSURE_DEFAULT;
+ result.radiance = color.rgb;
+ result.opacity = color.a;
+ result.ssr_normal = normal_encode(vN, viewCameraVec);
+#else
+ result = Closure(vec3(0.0), vec3(0.0), color.rgb * strength, 0.0);
+#endif
+}
- clearcoat_bsdf = clearcoat * Gr * Fr * Dr * vec3(0.25) * light_specular;
- }
- clearcoat_bsdf *= max(CNdotL, 0.0);
+/* background */
- L += diffuse_and_specular_bsdf + clearcoat_bsdf;
- }
+void background_transform_to_world(vec3 viewvec, out vec3 worldvec)
+{
+ 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);
- result = vec4(L, 1.0);
+ vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0);
+#if defined(WORLD_BACKGROUND) || defined(PROBE_CAPTURE)
+ worldvec = (ViewMatrixInverse * co).xyz;
+#else
+ worldvec = (ModelViewMatrixInverse * co).xyz;
+#endif
}
-void node_bsdf_translucent(vec4 color, vec3 N, out vec4 result)
+void node_background(vec4 color, float strength, out Closure result)
{
- node_bsdf_diffuse(color, 0.0, N, result);
+#ifndef VOLUMETRICS
+ color *= strength;
+ result = CLOSURE_DEFAULT;
+ result.radiance = color.rgb;
+ result.opacity = color.a;
+#else
+ result = CLOSURE_DEFAULT;
+#endif
}
-void node_bsdf_transparent(vec4 color, out vec4 result)
-{
- /* this isn't right */
- result.r = color.r;
- result.g = color.g;
- result.b = color.b;
- result.a = 0.0;
-}
+/* volumes */
-void node_bsdf_velvet(vec4 color, float sigma, vec3 N, out vec4 result)
+void node_volume_scatter(vec4 color, float density, float anisotropy, out Closure result)
{
- node_bsdf_diffuse(color, 0.0, N, result);
+#ifdef VOLUMETRICS
+ result = Closure(vec3(0.0), color.rgb * density, vec3(0.0), anisotropy);
+#else
+ result = CLOSURE_DEFAULT;
+#endif
}
-void node_subsurface_scattering(
- vec4 color, float scale, vec3 radius, float sharpen, float texture_blur, vec3 N,
- out vec4 result)
+void node_volume_absorption(vec4 color, float density, out Closure result)
{
- node_bsdf_diffuse(color, 0.0, N, result);
+#ifdef VOLUMETRICS
+ result = Closure((1.0 - color.rgb) * density, vec3(0.0), vec3(0.0), 0.0);
+#else
+ result = CLOSURE_DEFAULT;
+#endif
}
-void node_bsdf_hair(vec4 color, float offset, float roughnessu, float roughnessv, vec3 tangent, out vec4 result)
+void node_blackbody(float temperature, sampler2D spectrummap, out vec4 color)
{
- result = color;
+ if(temperature >= 12000.0) {
+ color = vec4(0.826270103, 0.994478524, 1.56626022, 1.0);
+ }
+ else if(temperature < 965.0) {
+ color = vec4(4.70366907, 0.0, 0.0, 1.0);
+ }
+ else {
+ float t = (temperature - 965.0) / (12000.0 - 965.0);
+ color = vec4(texture(spectrummap, vec2(t, 0.0)).rgb, 1.0);
+ }
}
-void node_bsdf_refraction(vec4 color, float roughness, float ior, vec3 N, out vec4 result)
+void node_volume_principled(
+ vec4 color,
+ float density,
+ float anisotropy,
+ vec4 absorption_color,
+ float emission_strength,
+ vec4 emission_color,
+ float blackbody_intensity,
+ vec4 blackbody_tint,
+ float temperature,
+ float density_attribute,
+ vec4 color_attribute,
+ float temperature_attribute,
+ sampler2D spectrummap,
+ out Closure result)
{
- node_bsdf_diffuse(color, 0.0, N, result);
-}
+#ifdef VOLUMETRICS
+ vec3 absorption_coeff = vec3(0.0);
+ vec3 scatter_coeff = vec3(0.0);
+ vec3 emission_coeff = vec3(0.0);
-void node_ambient_occlusion(vec4 color, float distance, vec3 normal, out vec4 result_color, out float result_ao)
-{
- result_color = color;
- result_ao = 1.0;
-}
+ /* Compute density. */
+ density = max(density, 0.0);
-/* emission */
+ if(density > 1e-5) {
+ density = max(density * density_attribute, 0.0);
+ }
-void node_emission(vec4 color, float strength, vec3 N, out vec4 result)
-{
- result = color * strength;
-}
+ if(density > 1e-5) {
+ /* Compute scattering and absorption coefficients. */
+ vec3 scatter_color = color.rgb * color_attribute.rgb;
-/* background */
+ scatter_coeff = scatter_color * density;
+ absorption_color.rgb = sqrt(max(absorption_color.rgb, 0.0));
+ absorption_coeff = max(1.0 - scatter_color, 0.0) * max(1.0 - absorption_color.rgb, 0.0) * density;
+ }
-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);
+ /* Compute emission. */
+ emission_strength = max(emission_strength, 0.0);
- vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0);
- worldvec = (gl_ModelViewMatrixInverse * co).xyz;
-}
+ if(emission_strength > 1e-5) {
+ emission_coeff += emission_strength * emission_color.rgb;
+ }
-void node_background(vec4 color, float strength, vec3 N, out vec4 result)
-{
- result = color * strength;
+ if(blackbody_intensity > 1e-3) {
+ /* Add temperature from attribute. */
+ float T = max(temperature * max(temperature_attribute, 0.0), 0.0);
+
+ /* Stefan-Boltzman law. */
+ float T4 = (T * T) * (T * T);
+ float sigma = 5.670373e-8 * 1e-6 / M_PI;
+ float intensity = sigma * mix(1.0, T4, blackbody_intensity);
+
+ if(intensity > 1e-5) {
+ vec4 bb;
+ node_blackbody(T, spectrummap, bb);
+ emission_coeff += bb.rgb * blackbody_tint.rgb * intensity;
+ }
+ }
+
+ result = Closure(absorption_coeff, scatter_coeff, emission_coeff, anisotropy);
+#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 */
@@ -2831,7 +1372,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);
@@ -2843,7 +1384,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);
@@ -2873,11 +1414,67 @@ 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(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(MESH_SHADER) && defined(VOLUMETRICS)
+ vec3 cos = volumeObjectLocalCoord;
+#else
+ vec3 cos = vec3(0.0);
+#endif
+
+ vec4 value = texture(tex, cos).rgba;
+ /* Density is premultiplied for interpolation, divide it out here. */
+ if (value.a > 1e-8)
+ value.rgb /= value.a;
+
+ outvec = value.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(MESH_SHADER) && defined(VOLUMETRICS)
+ vec3 cos = volumeObjectLocalCoord;
+#else
+ vec3 cos = vec3(0.0);
+#endif
+ outf = texture(tex, cos).r;
+ outvec = vec3(outf, outf, outf);
+ outcol = vec4(outf, outf, outf, 1.0);
+}
+
+void node_attribute_volume_temperature(sampler3D tex, vec2 temperature, out vec4 outcol, out vec3 outvec, out float outf)
+{
+#if defined(MESH_SHADER) && defined(VOLUMETRICS)
+ vec3 cos = volumeObjectLocalCoord;
+#else
+ vec3 cos = vec3(0.0);
+#endif
+ float flame = texture(tex, cos).r;
+
+ outf = (flame > 0.01) ? temperature.x + flame * (temperature.y - temperature.x): 0.0;
+ outvec = vec3(outf, outf, outf);
+ outcol = vec4(outf, outf, outf, 1.0);
+}
+
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)
@@ -2885,19 +1482,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 = 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)
{
- position = (toworld * vec4(I, 1.0)).xyz;
+ position = worldPosition;
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);
@@ -2911,16 +1536,15 @@ 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;
- shade_view(I, shade_I);
+ vec3 shade_I = (ProjectionMatrix[3][3] == 0.0) ? normalize(I) : vec3(0.0, 0.0, -1.0);
vec3 view_reflection = reflect(shade_I, normalize(N));
reflection = (viewinvmat * vec4(view_reflection, 0.0)).xyz;
}
@@ -2931,13 +1555,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;
@@ -2945,13 +1574,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)
@@ -3021,7 +1654,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,
@@ -3057,7 +1689,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,
@@ -3068,7 +1699,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,
@@ -3082,10 +1712,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)
@@ -3100,7 +1726,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)
@@ -3116,7 +1750,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)
@@ -3126,7 +1760,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;
}
@@ -3200,21 +1834,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;
@@ -3287,7 +1921,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);
@@ -3362,10 +1995,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);
@@ -3375,7 +2007,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);
@@ -3390,11 +2022,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) {
@@ -3410,15 +2040,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
@@ -3434,9 +2057,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;
@@ -3462,9 +2084,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;
@@ -3490,13 +2111,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;
@@ -3525,13 +2145,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;
@@ -3562,14 +2181,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));
@@ -3591,19 +2209,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,
@@ -3616,7 +2233,6 @@ void node_tex_musgrave(vec3 co,
out vec4 color,
out float fac)
{
-#ifdef BIT_OPERATIONS
fac = svm_musgrave(int(type),
dimension,
lacunarity,
@@ -3625,9 +2241,6 @@ void node_tex_musgrave(vec3 co,
1.0,
gain,
co * scale);
-#else
- fac = 1.0;
-#endif
color = vec4(fac, fac, fac, 1.0);
}
@@ -3639,7 +2252,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];
@@ -3704,13 +2316,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;
@@ -3732,22 +2339,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 */
@@ -3767,13 +2368,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;
@@ -3836,6 +2445,23 @@ void node_bevel(float radius, vec3 N, out vec3 result)
result = N;
}
+void node_hair_info(out float is_strand, out float intercept, out float thickness, out vec3 tangent, out float random)
+{
+#ifdef HAIR_SHADER
+ is_strand = 1.0;
+ intercept = hairTime;
+ thickness = hairThickness;
+ tangent = normalize(hairTangent);
+ random = wang_hash_noise(uint(hairStrandID)); /* TODO: could be precomputed per strand instead. */
+#else
+ is_strand = 0.0;
+ intercept = 0.0;
+ thickness = 0.0;
+ tangent = vec3(1.0);
+ random = 0.0;
+#endif
+}
+
void node_displacement_object(float height, float midlevel, float scale, vec3 N, mat4 obmat, out vec3 result)
{
N = (vec4(N, 0.0) * obmat).xyz;
@@ -3872,37 +2498,91 @@ 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
+ result.radiance = surface.radiance;
+ result.opacity = backgroundAlpha;
+#else
+ result = volume;
+#endif /* VOLUMETRICS */
}
-/* ********************** matcap style render ******************** */
-
-void material_preview_matcap(vec4 color, sampler2D ima, vec4 N, vec4 mask, out vec4 result)
+#ifndef VOLUMETRICS
+/* TODO : clean this ifdef mess */
+/* EEVEE output */
+void world_normals_get(out vec3 N)
{
- 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;
+#ifdef HAIR_SHADER
+ vec3 B = normalize(cross(worldNormal, hairTangent));
+ float cos_theta;
+ if (hairThicknessRes == 1) {
+ vec4 rand = texelFetch(utilTex, ivec3(ivec2(gl_FragCoord.xy) % LUT_SIZE, 2.0), 0);
+ /* Random cosine normal distribution on the hair surface. */
+ cos_theta = rand.x * 2.0 - 1.0;
+ }
+ else {
+ /* Shade as a cylinder. */
+ cos_theta = hairThickTime / hairThickness;
}
- normal = normalize(normal);
+ float sin_theta = sqrt(max(0.0, 1.0f - cos_theta*cos_theta));;
+ N = normalize(worldNormal * sin_theta + B * cos_theta);
#else
- normal = inpt.v.normal;
- mask = vec4(1.0, 1.0, 1.0, 1.0);
+ N = gl_FrontFacing ? worldNormal : -worldNormal;
#endif
+}
- tex.x = 0.5 + 0.49 * normal.x;
- tex.y = 0.5 + 0.49 * normal.y;
- result = texture2D(ima, tex) * mask;
+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);
}
+
+void node_shader_to_rgba(Closure cl, out vec4 outcol, out float outalpha)
+{
+ vec4 spec_accum = vec4(0.0);
+ if (ssrToggle && cl.ssr_id == outputSsrId) {
+ vec3 V = cameraVec;
+ vec3 vN = normal_decode(cl.ssr_normal, viewCameraVec);
+ vec3 N = transform_direction(ViewMatrixInverse, vN);
+ float roughness = cl.ssr_data.a;
+ float roughnessSquared = max(1e-3, roughness * roughness);
+ fallback_cubemap(N, V, worldPosition, viewPosition, roughness, roughnessSquared, spec_accum);
+ }
+
+ outalpha = cl.opacity;
+ outcol = vec4((spec_accum.rgb * cl.ssr_data.rgb) + cl.radiance, 1.0);
+
+# ifdef USE_SSS
+# ifdef USE_SSS_ALBEDO
+ outcol.rgb += cl.sss_data.rgb * cl.sss_albedo;
+# else
+ outcol.rgb += cl.sss_data.rgb;
+# endif
+# endif
+}
+
+#endif /* VOLUMETRICS */