diff options
Diffstat (limited to 'source/blender/gpu/shaders/gpu_shader_material.glsl')
-rw-r--r-- | source/blender/gpu/shaders/gpu_shader_material.glsl | 417 |
1 files changed, 253 insertions, 164 deletions
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index f6b39d77dc7..7595a3cf6b7 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -1,11 +1,27 @@ + +uniform mat4 ModelViewMatrix; +#ifndef EEVEE_ENGINE +uniform mat4 ProjectionMatrix; +uniform mat4 ViewMatrixInverse; +#endif +uniform mat4 ViewMatrix; +uniform mat4 ModelMatrix; +uniform mat4 ModelMatrixInverse; +uniform mat4 ModelViewMatrixInverse; +uniform mat4 ProjectionMatrixInverse; +uniform mat3 NormalMatrix; +uniform vec4 CameraTexCoFactors; + +out vec4 fragColor; + /* Converters */ float convert_rgba_to_float(vec4 color) { #ifdef USE_NEW_SHADING - return color.r * 0.2126 + color.g * 0.7152 + color.b * 0.0722; + return dot(color.rgb, vec3(0.2126, 0.7152, 0.0722)); #else - return (color.r + color.g + color.b) / 3.0; + return (color.r + color.g + color.b) * 0.333333; #endif } @@ -53,7 +69,7 @@ void rgb_to_hsv(vec4 rgb, out vec4 outcol) h = 0.0; } else { - c = (vec3(cmax, cmax, cmax) - rgb.xyz) / cdelta; + c = (vec3(cmax) - rgb.xyz) / cdelta; if (rgb.x == cmax) h = c[2] - c[1]; else if (rgb.y == cmax) h = 2.0 + c[0] - c[2]; @@ -155,15 +171,18 @@ void color_to_blender_normal_new_shading(vec3 color, out vec3 normal) normal.y = -2.0 * ((color.g) - 0.5); normal.z = -2.0 * ((color.b) - 0.5); } - +#ifndef M_PI #define M_PI 3.14159265358979323846 -#define M_1_PI 0.31830988618379069 +#endif +#ifndef M_1_PI +#define M_1_PI 0.318309886183790671538 +#endif /*********** SHADER NODES ***************/ void vcol_attribute(vec4 attvcol, out vec4 vcol) { - vcol = vec4(attvcol.x, attvcol.y, attvcol.z, 1.0); + vcol = vec4(attvcol.xyz, 1.0); } void uv_attribute(vec2 attuv, out vec3 uv) @@ -177,7 +196,7 @@ void geom( out vec3 normal, out vec4 vcol, out float vcol_alpha, out float frontback) { local = co; - view = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(local) : vec3(0.0, 0.0, -1.0); + view = (ProjectionMatrix[3][3] == 0.0) ? normalize(local) : vec3(0.0, 0.0, -1.0); global = (viewinvmat * vec4(local, 1.0)).xyz; orco = attorco; uv_attribute(attuv, uv); @@ -419,13 +438,13 @@ void squeeze(float val, float width, float center, out float outval) void vec_math_add(vec3 v1, vec3 v2, out vec3 outvec, out float outval) { outvec = v1 + v2; - outval = (abs(outvec[0]) + abs(outvec[1]) + abs(outvec[2])) / 3.0; + outval = (abs(outvec[0]) + abs(outvec[1]) + abs(outvec[2])) * 0.333333; } void vec_math_sub(vec3 v1, vec3 v2, out vec3 outvec, out float outval) { outvec = v1 - v2; - outval = (abs(outvec[0]) + abs(outvec[1]) + abs(outvec[2])) / 3.0; + outval = (abs(outvec[0]) + abs(outvec[1]) + abs(outvec[2])) * 0.333333; } void vec_math_average(vec3 v1, vec3 v2, out vec3 outvec, out float outval) @@ -441,7 +460,7 @@ void vec_math_mix(float strength, vec3 v1, vec3 v2, out vec3 outvec) void vec_math_dot(vec3 v1, vec3 v2, out vec3 outvec, out float outval) { - outvec = vec3(0, 0, 0); + outvec = vec3(0); outval = dot(v1, v2); } @@ -483,9 +502,9 @@ void normal_new_shading(vec3 dir, vec3 nor, out vec3 outnor, out float outdot) void curves_vec(float fac, vec3 vec, sampler2D curvemap, out vec3 outvec) { - outvec.x = texture2D(curvemap, vec2((vec.x + 1.0) * 0.5, 0.0)).x; - outvec.y = texture2D(curvemap, vec2((vec.y + 1.0) * 0.5, 0.0)).y; - outvec.z = texture2D(curvemap, vec2((vec.z + 1.0) * 0.5, 0.0)).z; + outvec.x = texture(curvemap, vec2((vec.x + 1.0) * 0.5, 0.0)).x; + outvec.y = texture(curvemap, vec2((vec.y + 1.0) * 0.5, 0.0)).y; + outvec.z = texture(curvemap, vec2((vec.z + 1.0) * 0.5, 0.0)).z; if (fac != 1.0) outvec = (outvec * fac) + (vec * (1.0 - fac)); @@ -494,9 +513,9 @@ void curves_vec(float fac, vec3 vec, sampler2D curvemap, out vec3 outvec) void curves_rgb(float fac, vec4 col, sampler2D curvemap, out vec4 outcol) { - outcol.r = texture2D(curvemap, vec2(texture2D(curvemap, vec2(col.r, 0.0)).a, 0.0)).r; - outcol.g = texture2D(curvemap, vec2(texture2D(curvemap, vec2(col.g, 0.0)).a, 0.0)).g; - outcol.b = texture2D(curvemap, vec2(texture2D(curvemap, vec2(col.b, 0.0)).a, 0.0)).b; + outcol.r = texture(curvemap, vec2(texture(curvemap, vec2(col.r, 0.0)).a, 0.0)).r; + outcol.g = texture(curvemap, vec2(texture(curvemap, vec2(col.g, 0.0)).a, 0.0)).g; + outcol.b = texture(curvemap, vec2(texture(curvemap, vec2(col.b, 0.0)).a, 0.0)).b; if (fac != 1.0) outcol = (outcol * fac) + (col * (1.0 - fac)); @@ -816,22 +835,23 @@ void mix_linear(float fac, vec4 col1, vec4 col2, out vec4 outcol) void valtorgb(float fac, sampler2D colormap, out vec4 outcol, out float outalpha) { - outcol = texture2D(colormap, vec2(fac, 0.0)); + outcol = texture(colormap, vec2(fac, 0.0)); outalpha = outcol.a; } void rgbtobw(vec4 color, out float outval) { #ifdef USE_NEW_SHADING - outval = color.r * 0.2126 + color.g * 0.7152 + color.b * 0.0722; + vec3 factors = vec3(0.2126, 0.7152, 0.0722); #else - outval = color.r * 0.35 + color.g * 0.45 + color.b * 0.2; /* keep these factors in sync with texture.h:RGBTOBW */ + vec3 factors = vec3(0.35, 0.45, 0.2); /* keep these factors in sync with texture.h:RGBTOBW */ #endif + outval = dot(color.rgb, factors); } void invert(float fac, vec4 col, out vec4 outcol) { - outcol.xyz = mix(col.xyz, vec3(1.0, 1.0, 1.0) - col.xyz, fac); + outcol.xyz = mix(col.xyz, vec3(1.0) - col.xyz, fac); outcol.w = col.w; } @@ -916,12 +936,12 @@ void texture_flip_blend(vec3 vec, out vec3 outvec) void texture_blend_lin(vec3 vec, out float outval) { - outval = (1.0 + vec.x) / 2.0; + outval = (1.0 + vec.x) * 0.5; } void texture_blend_quad(vec3 vec, out float outval) { - outval = max((1.0 + vec.x) / 2.0, 0.0); + outval = max((1.0 + vec.x) * 0.5, 0.0); outval *= outval; } @@ -932,12 +952,12 @@ void texture_wood_sin(vec3 vec, out float value, out vec4 color, out vec3 normal value = wi; color = vec4(wi, wi, wi, 1.0); - normal = vec3(0.0, 0.0, 0.0); + normal = vec3(0.0); } void texture_image(vec3 vec, sampler2D ima, out float value, out vec4 color, out vec3 normal) { - color = texture2D(ima, (vec.xy + vec2(1.0, 1.0)) * 0.5); + color = texture(ima, (vec.xy + vec2(1.0)) * 0.5); value = color.a; normal.x = 2.0 * (color.r - 0.5); @@ -955,7 +975,7 @@ void texco_orco(vec3 attorco, out vec3 orco) void texco_uv(vec2 attuv, out vec3 uv) { /* disabled for now, works together with leaving out mtex_2d_mapping - uv = vec3(attuv*2.0 - vec2(1.0, 1.0), 0.0); */ + uv = vec3(attuv * 2.0 - vec2(1.0), 0.0); */ uv = vec3(attuv, 0.0); } @@ -1277,11 +1297,7 @@ void mtex_har_divide(float har, out float outhar) void mtex_har_multiply_clamp(float har, out float outhar) { - har *= 128.0; - - if (har < 1.0) outhar = 1.0; - else if (har > 511.0) outhar = 511.0; - else outhar = har; + outhar = clamp(har * 128.0, 1.0, 511.0); } void mtex_alpha_from_col(vec4 col, out float alpha) @@ -1350,14 +1366,14 @@ vec3 mtex_2d_mapping(vec3 vec) void mtex_cube_map(vec3 co, samplerCube ima, out float value, out vec4 color) { - color = textureCube(ima, co); + color = texture(ima, co); value = 1.0; } void mtex_cube_map_refl_from_refldir( samplerCube ima, vec3 reflecteddirection, out float value, out vec4 color) { - color = textureCube(ima, reflecteddirection); + color = texture(ima, reflecteddirection); value = color.a; } @@ -1368,13 +1384,13 @@ void mtex_cube_map_refl( vec3 viewdirection = vec3(viewmatrixinverse * vec4(vp, 0.0)); vec3 normaldirection = normalize(vec3(vec4(vn, 0.0) * viewmatrix)); vec3 reflecteddirection = reflect(viewdirection, normaldirection); - color = textureCube(ima, reflecteddirection); + color = texture(ima, reflecteddirection); value = 1.0; } void mtex_image(vec3 texco, sampler2D ima, out float value, out vec4 color) { - color = texture2D(ima, texco.xy); + color = texture(ima, texco.xy); value = 1.0; } @@ -1385,7 +1401,7 @@ void mtex_normal(vec3 texco, sampler2D ima, out vec3 normal) // It needs to be done because in Blender // the normal used points inward. // Should this ever change this negate must be removed. - vec4 color = texture2D(ima, texco.xy); + vec4 color = texture(ima, texco.xy); normal = 2.0 * (vec3(-color.r, color.g, color.b) - vec3(-0.5, 0.5, 0.5)); } @@ -1413,8 +1429,8 @@ void mtex_bump_init_objspace( out float fPrevMagnitude_out, out vec3 vNacc_out, out vec3 vR1, out vec3 vR2, out float fDet) { - mat3 obj2view = to_mat3(gl_ModelViewMatrix); - mat3 view2obj = to_mat3(gl_ModelViewMatrixInverse); + mat3 obj2view = to_mat3(ModelViewMatrix); + mat3 view2obj = to_mat3(ModelViewMatrixInverse); vec3 vSigmaS = view2obj * dFdx(surf_pos); vec3 vSigmaT = view2obj * dFdy(surf_pos); @@ -1481,9 +1497,9 @@ void mtex_bump_tap3( vec2 STul = texco.xy + dFdy(texco.xy); float Hll, Hlr, Hul; - rgbtobw(texture2D(ima, STll), Hll); - rgbtobw(texture2D(ima, STlr), Hlr); - rgbtobw(texture2D(ima, STul), Hul); + rgbtobw(texture(ima, STll), Hll); + rgbtobw(texture(ima, STlr), Hlr); + rgbtobw(texture(ima, STul), Hul); dBs = hScale * (Hlr - Hll); dBt = hScale * (Hul - Hll); @@ -1508,10 +1524,10 @@ void mtex_bump_bicubic( vec2 STd = texco.xy - 0.5 * TexDy; vec2 STu = texco.xy + 0.5 * TexDy; - rgbtobw(texture2D(ima, STl), Hl); - rgbtobw(texture2D(ima, STr), Hr); - rgbtobw(texture2D(ima, STd), Hd); - rgbtobw(texture2D(ima, STu), Hu); + rgbtobw(texture(ima, STl), Hl); + rgbtobw(texture(ima, STr), Hr); + rgbtobw(texture(ima, STd), Hd); + rgbtobw(texture(ima, STu), Hu); vec2 dHdxy = vec2(Hr - Hl, Hu - Hd); float fBlend = clamp(1.0 - textureQueryLOD(ima, texco.xy).x, 0.0, 1.0); @@ -1597,11 +1613,11 @@ void mtex_bump_tap5( vec2 STu = texco.xy + 0.5 * TexDy; float Hc, Hl, Hr, Hd, Hu; - rgbtobw(texture2D(ima, STc), Hc); - rgbtobw(texture2D(ima, STl), Hl); - rgbtobw(texture2D(ima, STr), Hr); - rgbtobw(texture2D(ima, STd), Hd); - rgbtobw(texture2D(ima, STu), Hu); + rgbtobw(texture(ima, STc), Hc); + rgbtobw(texture(ima, STl), Hl); + rgbtobw(texture(ima, STr), Hr); + rgbtobw(texture(ima, STd), Hd); + rgbtobw(texture(ima, STu), Hu); dBs = hScale * (Hr - Hl); dBt = hScale * (Hu - Hd); @@ -1618,7 +1634,7 @@ void mtex_bump_deriv( // this variant using a derivative map is described here // http://mmikkelsen3d.blogspot.com/2011/07/derivative-maps.html vec2 dim = vec2(ima_x, ima_y); - vec2 dBduv = hScale * dim * (2.0 * texture2D(ima, texco.xy).xy - 1.0); + vec2 dBduv = hScale * dim * (2.0 * texture(ima, texco.xy).xy - 1.0); dBs = dBduv.x * TexDx.x + s * dBduv.y * TexDx.y; dBt = dBduv.x * TexDy.x + s * dBduv.y * TexDy.y; @@ -1670,7 +1686,7 @@ void mtex_nspace_world(mat4 viewmat, vec3 texnormal, out vec3 outnormal) void mtex_nspace_object(vec3 texnormal, out vec3 outnormal) { - outnormal = normalize(gl_NormalMatrix * texnormal); + outnormal = normalize(NormalMatrix * texnormal); } void mtex_blend_normal(float norfac, vec3 normal, vec3 newnormal, out vec3 outnormal) @@ -1727,7 +1743,7 @@ void lamp_falloff_invcoefficients(float coeff_const, float coeff_lin, float coef void lamp_falloff_curve(float lampdist, sampler2D curvemap, float dist, out float visifac) { - visifac = texture2D(curvemap, vec2(dist / lampdist, 0.0)).x; + visifac = texture(curvemap, vec2(dist / lampdist, 0.0)).x; } void lamp_visibility_sphere(float lampdist, float dist, float visifac, out float outvisifac) @@ -1794,7 +1810,7 @@ void lamp_visibility_clamp(float visifac, out float outvisifac) void world_paper_view(vec3 vec, out vec3 outvec) { vec3 nvec = normalize(vec); - outvec = (gl_ProjectionMatrix[3][3] == 0.0) ? vec3(nvec.x, 0.0, nvec.y) : vec3(0.0, 0.0, -1.0); + outvec = (ProjectionMatrix[3][3] == 0.0) ? vec3(nvec.x, 0.0, nvec.y) : vec3(0.0, 0.0, -1.0); } void world_zen_mapping(vec3 view, float zenup, float zendown, out float zenfac) @@ -1828,7 +1844,7 @@ void world_blend(vec3 vec, out float blend) void shade_view(vec3 co, out vec3 view) { /* handle perspective/orthographic */ - view = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(co) : vec3(0.0, 0.0, -1.0); + view = (ProjectionMatrix[3][3] == 0.0) ? normalize(co) : vec3(0.0, 0.0, -1.0); } void shade_tangent_v(vec3 lv, vec3 tang, out vec3 vn) @@ -2020,7 +2036,7 @@ void shade_add_to_diffuse(float i, vec3 lampcol, vec3 col, out vec3 outcol) if (i > 0.0) outcol = i * lampcol * col; else - outcol = vec3(0.0, 0.0, 0.0); + outcol = vec3(0.0); } void shade_hemi_spec(vec3 vn, vec3 lv, vec3 view, float spec, float hard, float visifac, out float t) @@ -2177,12 +2193,12 @@ void shade_madd(vec4 col, vec4 col1, vec4 col2, out vec4 outcol) void shade_add_clamped(vec4 col1, vec4 col2, out vec4 outcol) { - outcol = col1 + max(col2, vec4(0.0, 0.0, 0.0, 0.0)); + outcol = col1 + max(col2, vec4(0.0)); } void shade_madd_clamped(vec4 col, vec4 col1, vec4 col2, out vec4 outcol) { - outcol = col + max(col1 * col2, vec4(0.0, 0.0, 0.0, 0.0)); + outcol = col + max(col1 * col2, vec4(0.0)); } void env_apply(vec4 col, vec3 hor, vec3 zen, vec4 f, mat4 vm, vec3 vn, out vec4 outcol) @@ -2219,7 +2235,7 @@ void shade_obcolor(vec4 col, vec4 obcol, out vec4 outcol) void ramp_rgbtobw(vec3 color, out float outval) { - outval = color.r * 0.3 + color.g * 0.58 + color.b * 0.12; + outval = dot(color, vec3(0.3, 0.58, 0.12)); } void shade_only_shadow(float i, float shadfac, float energy, vec3 shadcol, out vec3 outshadrgb) @@ -2255,10 +2271,12 @@ void test_shadowbuf( //float bias = (1.5 - inp*inp)*shadowbias; co.z -= shadowbias * co.w; - if (co.w > 0.0 && co.x > 0.0 && co.x / co.w < 1.0 && co.y > 0.0 && co.y / co.w < 1.0) - result = shadow2DProj(shadowmap, co).x; - else + if (co.w > 0.0 && co.x > 0.0 && co.x / co.w < 1.0 && co.y > 0.0 && co.y / co.w < 1.0) { + result = textureProj(shadowmap, co); + } + else { result = 1.0; + } } } @@ -2272,7 +2290,7 @@ void test_shadowbuf_vsm( else { vec4 co = shadowpersmat * vec4(rco, 1.0); if (co.w > 0.0 && co.x > 0.0 && co.x / co.w < 1.0 && co.y > 0.0 && co.y / co.w < 1.0) { - vec2 moments = texture2DProj(shadowmap, co).rg; + vec2 moments = textureProj(shadowmap, co).rg; float dist = co.z / co.w; float p = 0.0; @@ -2331,7 +2349,7 @@ void shade_light_texture(vec3 rco, sampler2D cookie, mat4 shadowpersmat, out vec vec4 co = shadowpersmat * vec4(rco, 1.0); - result = texture2DProj(cookie, co); + result = textureProj(cookie, co); } void shade_exposure_correct(vec3 col, float linfac, float logfac, out vec3 outcol) @@ -2346,7 +2364,7 @@ void shade_mist_factor( if (enable == 1.0) { float fac, zcor; - zcor = (gl_ProjectionMatrix[3][3] == 0.0) ? length(co) : -co[2]; + zcor = (ProjectionMatrix[3][3] == 0.0) ? length(co) : -co[2]; fac = clamp((zcor - miststa) / mistdist, 0.0, 1.0); if (misttype == 0.0) fac *= fac; @@ -2421,7 +2439,7 @@ float hypot(float x, float y) void generated_from_orco(vec3 orco, out vec3 generated) { - generated = orco * 0.5 + vec3(0.5); + generated = orco; } int floor_to_int(float x) @@ -2434,7 +2452,6 @@ int quick_floor(float x) return int(x) - ((x < 0) ? 1 : 0); } -#ifdef BIT_OPERATIONS float integer_noise(int n) { int nn; @@ -2499,7 +2516,6 @@ vec3 cellnoise_color(vec3 p) return vec3(r, g, b); } -#endif // BIT_OPERATIONS float floorfrac(float x, out int i) { @@ -2562,6 +2578,17 @@ vec3 rotate_vector(vec3 p, vec3 n, float theta) { #define NUM_LIGHTS 3 +struct glLight { + vec4 position; + vec4 diffuse; + vec4 specular; + vec4 halfVector; +}; + +layout(std140) uniform lightSource { + glLight glLightSource[NUM_LIGHTS]; +}; + /* bsdfs */ void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out vec4 result) @@ -2571,8 +2598,8 @@ void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out vec4 result) /* directional lights */ for (int i = 0; i < NUM_LIGHTS; i++) { - vec3 light_position = gl_LightSource[i].position.xyz; - vec3 light_diffuse = gl_LightSource[i].diffuse.rgb; + vec3 light_position = glLightSource[i].position.xyz; + vec3 light_diffuse = glLightSource[i].diffuse.rgb; float bsdf = max(dot(N, light_position), 0.0); L += light_diffuse * bsdf; @@ -2588,10 +2615,10 @@ void node_bsdf_glossy(vec4 color, float roughness, vec3 N, out vec4 result) /* directional lights */ for (int i = 0; i < NUM_LIGHTS; i++) { - vec3 light_position = gl_LightSource[i].position.xyz; - vec3 H = gl_LightSource[i].halfVector.xyz; - vec3 light_diffuse = gl_LightSource[i].diffuse.rgb; - vec3 light_specular = gl_LightSource[i].specular.rgb; + vec3 light_position = glLightSource[i].position.xyz; + vec3 H = glLightSource[i].halfVector.xyz; + vec3 light_diffuse = glLightSource[i].diffuse.rgb; + vec3 light_specular = glLightSource[i].specular.rgb; /* we mix in some diffuse so low roughness still shows up */ float bsdf = 0.5 * pow(max(dot(N, H), 0.0), 1.0 / roughness); @@ -2662,12 +2689,12 @@ 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 = normalize(gl_NormalMatrix * light_position_world); + vec3 light_position_world = glLightSource[i].position.xyz; + vec3 light_position = normalize(NormalMatrix * light_position_world); vec3 H = normalize(light_position + V); - vec3 light_specular = gl_LightSource[i].specular.rgb; + vec3 light_specular = glLightSource[i].specular.rgb; float NdotL = dot(N, light_position); float NdotV = dot(N, V); @@ -2677,7 +2704,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); @@ -2791,14 +2818,29 @@ void node_emission(vec4 color, float strength, vec3 N, out vec4 result) void background_transform_to_world(vec3 viewvec, out vec3 worldvec) { - vec4 v = (gl_ProjectionMatrix[3][3] == 0.0) ? vec4(viewvec, 1.0) : vec4(0.0, 0.0, 1.0, 1.0); - vec4 co_homogenous = (gl_ProjectionMatrixInverse * v); + vec4 v = (ProjectionMatrix[3][3] == 0.0) ? vec4(viewvec, 1.0) : vec4(0.0, 0.0, 1.0, 1.0); + vec4 co_homogenous = (ProjectionMatrixInverse * v); vec4 co = vec4(co_homogenous.xyz / co_homogenous.w, 0.0); - worldvec = (gl_ModelViewMatrixInverse * co).xyz; +#ifdef WORLD_BACKGROUND + worldvec = (ViewMatrixInverse * co).xyz; +#else + worldvec = (ModelViewMatrixInverse * co).xyz; +#endif } -void node_background(vec4 color, float strength, vec3 N, out vec4 result) +#if defined(PROBE_CAPTURE) || defined(WORLD_BACKGROUND) +void environment_default_vector(out vec3 worldvec) +{ +#ifdef WORLD_BACKGROUND + background_transform_to_world(viewPosition, worldvec); +#else + worldvec = normalize(worldPosition); +#endif +} +#endif + +void node_background(vec4 color, float strength, out vec4 result) { result = color * strength; } @@ -2820,7 +2862,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); @@ -2832,7 +2874,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); @@ -2874,19 +2916,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; 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); @@ -2900,12 +2970,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; @@ -2920,13 +2990,20 @@ 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; + +#ifdef PROBE_CAPTURE + vec3 coords = normalize(worldPosition); +#elif defined(WORLD_BACKGROUND) + vec3 coords = (ViewMatrixInverse * co).xyz; +#else + vec3 coords = (ModelViewMatrixInverse * co).xyz; +#endif generated = coords; normal = -coords; @@ -2934,13 +3011,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) @@ -3007,7 +3088,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, @@ -3043,7 +3123,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, @@ -3054,7 +3133,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, @@ -3068,10 +3146,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) @@ -3086,7 +3160,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) @@ -3102,7 +3184,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) @@ -3112,7 +3194,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; } @@ -3180,13 +3262,13 @@ void node_tex_image_box(vec3 texco, } color = vec4(0); if (weight.x > 0.0) { - color += weight.x * texture2D(ima, texco.yz); + color += weight.x * texture(ima, texco.yz); } if (weight.y > 0.0) { - color += weight.y * texture2D(ima, texco.xz); + color += weight.y * texture(ima, texco.xz); } if (weight.z > 0.0) { - color += weight.z * texture2D(ima, texco.yx); + color += weight.z * texture(ima, texco.yx); } alpha = color.a; @@ -3259,7 +3341,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); @@ -3322,10 +3403,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); @@ -3335,7 +3415,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); @@ -3350,11 +3430,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) { @@ -3370,15 +3448,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 @@ -3394,9 +3465,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; @@ -3422,9 +3492,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; @@ -3450,13 +3519,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; @@ -3485,13 +3553,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; @@ -3522,14 +3589,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)); @@ -3551,19 +3617,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, @@ -3576,7 +3641,6 @@ void node_tex_musgrave(vec3 co, out vec4 color, out float fac) { -#ifdef BIT_OPERATIONS fac = svm_musgrave(int(type), dimension, lacunarity, @@ -3585,9 +3649,6 @@ void node_tex_musgrave(vec3 co, 1.0, gain, co * scale); -#else - fac = 1.0; -#endif color = vec4(fac, fac, fac, 1.0); } @@ -3599,7 +3660,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]; @@ -3664,13 +3724,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; @@ -3692,22 +3747,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 */ @@ -3727,13 +3776,21 @@ void node_light_path( out float transparent_depth, out float transmission_depth) { +#ifndef PROBE_CAPTURE is_camera_ray = 1.0; - is_shadow_ray = 0.0; - is_diffuse_ray = 0.0; is_glossy_ray = 0.0; - is_singular_ray = 0.0; + is_diffuse_ray = 0.0; is_reflection_ray = 0.0; is_transmission_ray = 0.0; +#else + is_camera_ray = 0.0; + is_glossy_ray = 1.0; + is_diffuse_ray = 1.0; + is_reflection_ray = 1.0; + is_transmission_ray = 1.0; +#endif + is_shadow_ray = 0.0; + is_singular_ray = 0.0; ray_length = 1.0; ray_depth = 1.0; diffuse_depth = 1.0; @@ -3800,30 +3857,62 @@ void node_output_material(vec4 surface, vec4 volume, float displacement, out vec void node_output_world(vec4 surface, vec4 volume, out vec4 result) { - result = surface; + result = vec4(surface.rgb, 1.0); +} + +void convert_metallic_to_specular(vec4 basecol, float metallic, float specular_fac, out vec4 diffuse, out vec4 f0) +{ + vec4 dielectric = vec4(0.034) * specular_fac * 2.0; + diffuse = mix(basecol, vec4(0.0), metallic); + f0 = mix(dielectric, basecol, metallic); +} + +/* TODO : clean this ifdef mess */ +/* EEVEE output */ +#ifdef EEVEE_ENGINE +void world_normals_get(out vec3 N) +{ + N = gl_FrontFacing ? worldNormal : -worldNormal; } +void node_output_metallic( + vec4 basecol, float metallic, float specular, float roughness, vec4 emissive, float transp, vec3 normal, + float clearcoat, float clearcoat_roughness, vec3 clearcoat_normal, + float occlusion, out vec4 result) +{ + vec4 diffuse, f0; + convert_metallic_to_specular(basecol, metallic, specular, diffuse, f0); + + result = vec4(eevee_surface_lit(normal, diffuse.rgb, f0.rgb, roughness, occlusion) + emissive.rgb, 1.0 - transp); +} + +void node_output_specular( + vec4 diffuse, vec4 specular, float roughness, vec4 emissive, float transp, vec3 normal, + float clearcoat, float clearcoat_roughness, vec3 clearcoat_normal, + float occlusion, out vec4 result) +{ + result = vec4(eevee_surface_lit(normal, diffuse.rgb, specular.rgb, roughness, occlusion) + emissive.rgb, 1.0 - transp); +} +#endif + /* ********************** matcap style render ******************** */ void material_preview_matcap(vec4 color, sampler2D ima, vec4 N, vec4 mask, out vec4 result) { vec3 normal; - vec2 tex; #ifndef USE_OPENSUBDIV /* remap to 0.0 - 1.0 range. This is done because OpenGL 2.0 clamps colors * between shader stages and we want the full range of the normal */ - normal = vec3(2.0, 2.0, 2.0) * vec3(N.x, N.y, N.z) - vec3(1.0, 1.0, 1.0); - if (normal.z < 0.0) { - normal.z = 0.0; - } + normal = 2.0 * N.xyz - vec3(1.0); + normal.z = max(normal.z, 0.0); normal = normalize(normal); #else normal = inpt.v.normal; - mask = vec4(1.0, 1.0, 1.0, 1.0); + mask = vec4(1.0); #endif - tex.x = 0.5 + 0.49 * normal.x; - tex.y = 0.5 + 0.49 * normal.y; - result = texture2D(ima, tex) * mask; + vec2 tex = 0.49 * normal.xy + vec2(0.5); + + result = texture(ima, tex) * mask; } |