diff options
author | Charlie Jolly <charlie> | 2022-08-30 13:05:46 +0300 |
---|---|---|
committer | Charlie Jolly <mistajolly@gmail.com> | 2022-08-31 02:13:57 +0300 |
commit | bfa0ee13d5395fa2cf622b6808e93d0a7cd4f3ea (patch) | |
tree | 60a8fece4797903560d7892d6e388030a3566a2b /source/blender/gpu/shaders | |
parent | 0331a8c67c8035c29ac6b7655cb4e4d837ddabba (diff) |
Node: Mix node
This patch is a response to T92588 and is implemented
as a Function/Shader node.
This node has support for Float, Vector and Color data types.
For Vector it supports uniform and non-uniform mixing.
For Color it now has the option to remove factor clamping.
It replaces the Mix RGB for Shader and Geometry node trees.
As discussed in T96219, this patch converts existing nodes
in .blend files. The old node is still available in the
Python API but hidden from the menus.
Reviewed By: HooglyBoogly, JacquesLucke, simonthommes, brecht
Maniphest Tasks: T92588
Differential Revision: https://developer.blender.org/D13749
Diffstat (limited to 'source/blender/gpu/shaders')
-rw-r--r-- | source/blender/gpu/shaders/material/gpu_shader_material_mix_color.glsl | 537 |
1 files changed, 537 insertions, 0 deletions
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_mix_color.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_mix_color.glsl new file mode 100644 index 00000000000..933a8de9cb7 --- /dev/null +++ b/source/blender/gpu/shaders/material/gpu_shader_material_mix_color.glsl @@ -0,0 +1,537 @@ +#pragma BLENDER_REQUIRE(gpu_shader_common_color_utils.glsl) + +void node_mix_blend(float fac, + vec3 facvec, + float f1, + float f2, + vec3 v1, + vec3 v2, + vec4 col1, + vec4 col2, + out float outfloat, + out vec3 outvec, + out vec4 outcol) +{ + outcol = mix(col1, col2, fac); + outcol.a = col1.a; +} + +void node_mix_add(float fac, + vec3 facvec, + float f1, + float f2, + vec3 v1, + vec3 v2, + vec4 col1, + vec4 col2, + out float outfloat, + out vec3 outvec, + out vec4 outcol) +{ + + outcol = mix(col1, col1 + col2, fac); + outcol.a = col1.a; +} + +void node_mix_mult(float fac, + vec3 facvec, + float f1, + float f2, + vec3 v1, + vec3 v2, + vec4 col1, + vec4 col2, + out float outfloat, + out vec3 outvec, + out vec4 outcol) +{ + + outcol = mix(col1, col1 * col2, fac); + outcol.a = col1.a; +} + +void node_mix_screen(float fac, + vec3 facvec, + float f1, + float f2, + vec3 v1, + vec3 v2, + vec4 col1, + vec4 col2, + out float outfloat, + out vec3 outvec, + out vec4 outcol) +{ + + float facm = 1.0 - fac; + + outcol = vec4(1.0) - (vec4(facm) + fac * (vec4(1.0) - col2)) * (vec4(1.0) - col1); + outcol.a = col1.a; +} + +void node_mix_overlay(float fac, + vec3 facvec, + float f1, + float f2, + vec3 v1, + vec3 v2, + vec4 col1, + vec4 col2, + out float outfloat, + out vec3 outvec, + out vec4 outcol) +{ + + float facm = 1.0 - fac; + + outcol = col1; + + if (outcol.r < 0.5) { + outcol.r *= facm + 2.0 * fac * col2.r; + } + else { + outcol.r = 1.0 - (facm + 2.0 * fac * (1.0 - col2.r)) * (1.0 - outcol.r); + } + + if (outcol.g < 0.5) { + outcol.g *= facm + 2.0 * fac * col2.g; + } + else { + outcol.g = 1.0 - (facm + 2.0 * fac * (1.0 - col2.g)) * (1.0 - outcol.g); + } + + if (outcol.b < 0.5) { + outcol.b *= facm + 2.0 * fac * col2.b; + } + else { + outcol.b = 1.0 - (facm + 2.0 * fac * (1.0 - col2.b)) * (1.0 - outcol.b); + } +} + +void node_mix_sub(float fac, + vec3 facvec, + float f1, + float f2, + vec3 v1, + vec3 v2, + vec4 col1, + vec4 col2, + out float outfloat, + out vec3 outvec, + out vec4 outcol) +{ + + outcol = mix(col1, col1 - col2, fac); + outcol.a = col1.a; +} + +/* A variant of mix_div that fallback to the first color upon zero division. */ +void node_mix_div_fallback(float fac, + vec3 facvec, + float f1, + float f2, + vec3 v1, + vec3 v2, + vec4 col1, + vec4 col2, + out float outfloat, + out vec3 outvec, + out vec4 outcol) +{ + + float facm = 1.0 - fac; + + outcol = col1; + + if (col2.r != 0.0) { + outcol.r = facm * outcol.r + fac * outcol.r / col2.r; + } + if (col2.g != 0.0) { + outcol.g = facm * outcol.g + fac * outcol.g / col2.g; + } + if (col2.b != 0.0) { + outcol.b = facm * outcol.b + fac * outcol.b / col2.b; + } +} + +void node_mix_diff(float fac, + vec3 facvec, + float f1, + float f2, + vec3 v1, + vec3 v2, + vec4 col1, + vec4 col2, + out float outfloat, + out vec3 outvec, + out vec4 outcol) +{ + + outcol = mix(col1, abs(col1 - col2), fac); + outcol.a = col1.a; +} + +void node_mix_dark(float fac, + vec3 facvec, + float f1, + float f2, + vec3 v1, + vec3 v2, + vec4 col1, + vec4 col2, + out float outfloat, + out vec3 outvec, + out vec4 outcol) +{ + + outcol.rgb = mix(col1.rgb, min(col1.rgb, col2.rgb), fac); + outcol.a = col1.a; +} + +void node_mix_light(float fac, + vec3 facvec, + float f1, + float f2, + vec3 v1, + vec3 v2, + vec4 col1, + vec4 col2, + out float outfloat, + out vec3 outvec, + out vec4 outcol) +{ + outcol.rgb = mix(col1.rgb, max(col1.rgb, col2.rgb), fac); + outcol.a = col1.a; +} + +void node_mix_dodge(float fac, + vec3 facvec, + float f1, + float f2, + vec3 v1, + vec3 v2, + vec4 col1, + vec4 col2, + out float outfloat, + out vec3 outvec, + out vec4 outcol) +{ + outcol = col1; + + if (outcol.r != 0.0) { + float tmp = 1.0 - fac * col2.r; + if (tmp <= 0.0) { + outcol.r = 1.0; + } + else if ((tmp = outcol.r / tmp) > 1.0) { + outcol.r = 1.0; + } + else { + outcol.r = tmp; + } + } + if (outcol.g != 0.0) { + float tmp = 1.0 - fac * col2.g; + if (tmp <= 0.0) { + outcol.g = 1.0; + } + else if ((tmp = outcol.g / tmp) > 1.0) { + outcol.g = 1.0; + } + else { + outcol.g = tmp; + } + } + if (outcol.b != 0.0) { + float tmp = 1.0 - fac * col2.b; + if (tmp <= 0.0) { + outcol.b = 1.0; + } + else if ((tmp = outcol.b / tmp) > 1.0) { + outcol.b = 1.0; + } + else { + outcol.b = tmp; + } + } +} + +void node_mix_burn(float fac, + vec3 facvec, + float f1, + float f2, + vec3 v1, + vec3 v2, + vec4 col1, + vec4 col2, + out float outfloat, + out vec3 outvec, + out vec4 outcol) +{ + + float tmp, facm = 1.0 - fac; + + outcol = col1; + + tmp = facm + fac * col2.r; + if (tmp <= 0.0) { + outcol.r = 0.0; + } + else if ((tmp = (1.0 - (1.0 - outcol.r) / tmp)) < 0.0) { + outcol.r = 0.0; + } + else if (tmp > 1.0) { + outcol.r = 1.0; + } + else { + outcol.r = tmp; + } + + tmp = facm + fac * col2.g; + if (tmp <= 0.0) { + outcol.g = 0.0; + } + else if ((tmp = (1.0 - (1.0 - outcol.g) / tmp)) < 0.0) { + outcol.g = 0.0; + } + else if (tmp > 1.0) { + outcol.g = 1.0; + } + else { + outcol.g = tmp; + } + + tmp = facm + fac * col2.b; + if (tmp <= 0.0) { + outcol.b = 0.0; + } + else if ((tmp = (1.0 - (1.0 - outcol.b) / tmp)) < 0.0) { + outcol.b = 0.0; + } + else if (tmp > 1.0) { + outcol.b = 1.0; + } + else { + outcol.b = tmp; + } +} + +void node_mix_hue(float fac, + vec3 facvec, + float f1, + float f2, + vec3 v1, + vec3 v2, + vec4 col1, + vec4 col2, + out float outfloat, + out vec3 outvec, + out vec4 outcol) +{ + + float facm = 1.0 - fac; + + outcol = col1; + + vec4 hsv, hsv2, tmp; + rgb_to_hsv(col2, hsv2); + + if (hsv2.y != 0.0) { + rgb_to_hsv(outcol, hsv); + hsv.x = hsv2.x; + hsv_to_rgb(hsv, tmp); + + outcol = mix(outcol, tmp, fac); + outcol.a = col1.a; + } +} + +void node_mix_sat(float fac, + vec3 facvec, + float f1, + float f2, + vec3 v1, + vec3 v2, + vec4 col1, + vec4 col2, + out float outfloat, + out vec3 outvec, + out vec4 outcol) +{ + + float facm = 1.0 - fac; + + outcol = col1; + + vec4 hsv, hsv2; + rgb_to_hsv(outcol, hsv); + + if (hsv.y != 0.0) { + rgb_to_hsv(col2, hsv2); + + hsv.y = facm * hsv.y + fac * hsv2.y; + hsv_to_rgb(hsv, outcol); + } +} + +void node_mix_val(float fac, + vec3 facvec, + float f1, + float f2, + vec3 v1, + vec3 v2, + vec4 col1, + vec4 col2, + out float outfloat, + out vec3 outvec, + out vec4 outcol) +{ + + float facm = 1.0 - fac; + + vec4 hsv, hsv2; + rgb_to_hsv(col1, hsv); + rgb_to_hsv(col2, hsv2); + + hsv.z = facm * hsv.z + fac * hsv2.z; + hsv_to_rgb(hsv, outcol); +} + +void node_mix_color(float fac, + vec3 facvec, + float f1, + float f2, + vec3 v1, + vec3 v2, + vec4 col1, + vec4 col2, + out float outfloat, + out vec3 outvec, + out vec4 outcol) +{ + + float facm = 1.0 - fac; + + outcol = col1; + + vec4 hsv, hsv2, tmp; + rgb_to_hsv(col2, hsv2); + + if (hsv2.y != 0.0) { + rgb_to_hsv(outcol, hsv); + hsv.x = hsv2.x; + hsv.y = hsv2.y; + hsv_to_rgb(hsv, tmp); + + outcol = mix(outcol, tmp, fac); + outcol.a = col1.a; + } +} + +void node_mix_soft(float fac, + vec3 facvec, + float f1, + float f2, + vec3 v1, + vec3 v2, + vec4 col1, + vec4 col2, + out float outfloat, + out vec3 outvec, + out vec4 outcol) +{ + + float facm = 1.0 - fac; + + vec4 one = vec4(1.0); + vec4 scr = one - (one - col2) * (one - col1); + outcol = facm * col1 + fac * ((one - col1) * col2 * col1 + col1 * scr); +} + +void node_mix_linear(float fac, + vec3 facvec, + float f1, + float f2, + vec3 v1, + vec3 v2, + vec4 col1, + vec4 col2, + out float outfloat, + out vec3 outvec, + out vec4 outcol) +{ + + outcol = col1 + fac * (2.0 * (col2 - vec4(0.5))); +} + +void node_mix_float(float fac, + vec3 facvec, + float f1, + float f2, + vec3 v1, + vec3 v2, + vec4 col1, + vec4 col2, + out float outfloat, + out vec3 outvec, + out vec4 outcol) +{ + + outfloat = mix(f1, f2, fac); +} + +void node_mix_vector(float fac, + vec3 facvec, + float f1, + float f2, + vec3 v1, + vec3 v2, + vec4 col1, + vec4 col2, + out float outfloat, + out vec3 outvec, + out vec4 outcol) +{ + + outvec = mix(v1, v2, fac); +} + +void node_mix_vector_non_uniform(float fac, + vec3 facvec, + float f1, + float f2, + vec3 v1, + vec3 v2, + vec4 col1, + vec4 col2, + out float outfloat, + out vec3 outvec, + out vec4 outcol) +{ + outvec = mix(v1, v2, facvec); +} + +void node_mix_rgba(float fac, + vec3 facvec, + float f1, + float f2, + vec3 v1, + vec3 v2, + vec4 col1, + vec4 col2, + out float outfloat, + out vec3 outvec, + out vec4 outcol) +{ + outcol = mix(col1, col2, fac); +} + +void node_mix_clamp_vector(vec3 vec, vec3 min, vec3 max, out vec3 outvec) +{ + outvec = clamp(vec, min, max); +} + +void node_mix_clamp_value(float value, float min, float max, out float outfloat) +{ + outfloat = clamp(value, min, max); +} |