diff --git a/data/post/blend.glsl b/data/post/blend.glsl index d7ecdbc7..25eb4c24 100644 --- a/data/post/blend.glsl +++ b/data/post/blend.glsl @@ -3,27 +3,74 @@ out vec4 color; in vec2 uv; uniform sampler2D a_pass; uniform sampler2D b_pass; -uniform int blend_type = 0; void main(){ - vec4 a = texture(a_pass, uv); - vec4 b = texture(b_pass, uv); + vec4 a_ = texture(a_pass, uv); + vec4 b_ = texture(b_pass, uv); + vec3 a = a_.rgb; + vec3 b = b_.rgb; + float a_a = a_.a; + float b_a = b_.a; + color.a = mix(a_a, b_a, b_a); - switch(blend_type){ + switch(BLEND_TYPE){ case 0: // b-over - color = mix(a, b, b.a); + color = mix(a_, b_, b_a); break; case 1: // a-over - color = mix(a, b, a.a); + color = mix(a_, b_, a_a); break; case 2: // Add - color = a+b; + color.rgb = a+b; break; case 3: // Subtract - color = a-b; + color.rgb = a-b; break; case 4: // Multiply - color = a*b; + color.rgb = a*b; + break; + case 5: // Screen + color.rgb = 1-(1-a)*(1-b); + break; + case 6: // Overlay + color.rgb = vec3((a.r < 0.5)? 2*a.r*b.r : 1-2*(1-a.r)*(1-b.r), + (a.g < 0.5)? 2*a.g*b.g : 1-2*(1-a.g)*(1-b.g), + (a.b < 0.5)? 2*a.b*b.b : 1-2*(1-a.b)*(1-b.b)); + break; + case 7: // Hard Light + color.rgb = vec3((b.r < 0.5)? 2*a.r*b.r : 1-2*(1-a.r)*(1-b.r), + (b.g < 0.5)? 2*a.g*b.g : 1-2*(1-a.g)*(1-b.g), + (b.b < 0.5)? 2*a.b*b.b : 1-2*(1-a.b)*(1-b.b)); + break; + case 8: // Soft Light + color.rgb = (1-2*b)*a*a + 2*b*a; + break; + case 9: // Color Dodge + color.rgb = b/(1-a); + break; + case 10: // Color Burn + color.rgb = 1-((1-b)/a); + break; + case 11: // Darken Only + color.rgb = min(a,b); + break; + case 12: // Lighten Only + color.rgb = max(a,b); + break; + case 13: // Divide + color.rgb = a/b; + break; + case 14: // Difference + color.rgb = vec3((a.r < b.r)? b.r-a.r : a.r-b.r, + (a.g < b.g)? b.g-a.g : a.g-b.g, + (a.b < b.b)? b.b-a.b : a.b-b.b); + break; + case 15: // Linear Burn + color.rgb = a+b-1; + break; + case 16: // Erase + color.rgb = a; + color.a = max(0.0,a_a-b_a); break; } } diff --git a/docs/post-processing.mess b/docs/post-processing.mess index 6084c3d3..08d79870 100644 --- a/docs/post-processing.mess +++ b/docs/post-processing.mess @@ -45,6 +45,18 @@ Trial also ships a number of useful preset post processing passes: - ``:add`` - ``:subtract`` - ``:multiply`` + - ``:screen`` + - ``:overlay`` + - ``:hard-light`` + - ``:soft-light`` + - ``:color-dodge`` + - ``:color-burn`` + - ``:darken-only`` + - ``:lighten-only`` + - ``:divide`` + - ``:difference`` + - ``:linear-burn`` + - ``:erase`` - ``high-pass-filter`` Only keeps pixels with a luminance above the threshold. Others are set to transparent. - ``low-pass-filter`` diff --git a/effects.lisp b/effects.lisp index 17c7b066..8008b5a7 100644 --- a/effects.lisp +++ b/effects.lisp @@ -167,7 +167,7 @@ void main(){ ((a-pass :port-type input) (b-pass :port-type input) (color :port-type output :reader color) - (blend-type :initarg :blend-type :initform 0 :uniform T :accessor blend-type)) + (blend-type :initarg :blend-type :initform 0 :constant T :accessor blend-type)) (:shader-file (trial "post/blend.glsl"))) (defmethod (setf blend-type) ((value symbol) (pass blend-pass)) @@ -177,7 +177,19 @@ void main(){ (:a-over 1) (:add 2) (:subtract 3) - (:multiply 4)))) + (:multiply 4) + (:screen 5) + (:overlay 6) + (:hard-light 7) + (:soft-light 8) + (:color-dodge 9) + (:color-burn 10) + (:darken-only 11) + (:lighten-only 12) + (:divide 13) + (:difference 14) + (:linear-burn 15) + (:erase 16)))) (define-shader-pass high-pass-filter (simple-post-effect-pass) ((threshold :initarg :threshold :initform 0.5 :uniform T :accessor threshold))