done with blend modes
This commit is contained in:
parent
facd0d7022
commit
151d10671b
2 changed files with 100 additions and 46 deletions
|
@ -1,4 +1,4 @@
|
|||
/* Reference: https://drafts.fxtf.org/compositing-1 */
|
||||
/* Reference: https://drafts.fxtf.org/compositing-1, https://www.shadertoy.com/view/XdS3RW */
|
||||
|
||||
$input v_texcoord0
|
||||
|
||||
|
@ -9,6 +9,44 @@ uniform vec4 u_mode;
|
|||
SAMPLER2D(s_A, 0);
|
||||
SAMPLER2D(s_B, 1);
|
||||
|
||||
vec3 rgb2hsv(vec3 c) {
|
||||
vec4 K = vec4(0.0f, -1.0f / 3.0f, 2.0f / 3.0f, -1.0f);
|
||||
vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
|
||||
vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
|
||||
|
||||
float d = q.x - min(q.w, q.y);
|
||||
float e = 1.0e-10;
|
||||
return vec3(abs(q.z + (q.w - q.y) / (6.0f * d + e)), d / (q.x + e), q.x);
|
||||
}
|
||||
|
||||
vec3 hsv2rgb(vec3 c) {
|
||||
vec4 K = vec4(1.0f, 2.0f / 3.0, 1.0 / 3.0, 3.0);
|
||||
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0f - K.www);
|
||||
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0f, 1.0f), c.y);
|
||||
}
|
||||
|
||||
float Overlay(float s, float d) {
|
||||
return (d < 0.5) ? 2.0 * s * d : 1.0 - 2.0 * (1.0 - s) * (1.0 - d);
|
||||
}
|
||||
|
||||
float HardLight(float s, float d) {
|
||||
return (s < 0.5) ? 2.0 * s * d : 1.0 - 2.0 * (1.0 - s) * (1.0 - d);
|
||||
}
|
||||
|
||||
float SoftLight(float s, float d) {
|
||||
return (s < 0.5) ? d - (1.0 - 2.0 * s) * d * (1.0 - d)
|
||||
: (d < 0.25) ? d + (2.0 * s - 1.0) * d * ((16.0 * d - 12.0) * d + 4.0)
|
||||
: d + (2.0 * s - 1.0) * (sqrt(d) - d);
|
||||
}
|
||||
|
||||
float VividLight(float s, float d) {
|
||||
return (s < 0.5) ? 1.0 - (1.0 - d) / (2.0 * s) : d / (2.0 * (1.0 - s));
|
||||
}
|
||||
|
||||
float PinLight(float s, float d){
|
||||
return (2.0 * s - 1.0 > d) ? 2.0 * s - 1.0 : (s < 0.5 * d) ? 2.0 * s : d;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 uv = vec2(v_texcoord0.x, 1.0f - v_texcoord0.y);
|
||||
vec4 _A = texture2D(s_A, uv);
|
||||
|
@ -41,68 +79,85 @@ void main() {
|
|||
else if (mode == 5) { // Exclusion
|
||||
blend = _B.xyz + _A.xyz - 2.0f * _B.xyz * _A.xyz;
|
||||
}
|
||||
else if (mode == 6) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
else if (mode == 6) { // Multiply
|
||||
blend = _A.xyz * _B.xyz;
|
||||
}
|
||||
else if (mode == 7) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
else if (mode == 7) { // Divide
|
||||
blend = _A.xyz / _B.xyz;
|
||||
}
|
||||
else if (mode == 8) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
else if (mode == 8) { // Lighten
|
||||
blend = max(_A.xyz, _B.xyz);
|
||||
}
|
||||
else if (mode == 9) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
else if (mode == 9) { // Darken
|
||||
blend = min(_A.xyz, _B.xyz);
|
||||
}
|
||||
else if (mode == 10) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
else if (mode == 10) { // Lighter Colour -- Why do these two use l1 instead of l2?
|
||||
blend = (_A.x + _A.y + _A.z > _B.x + _B.y + _B.z) ? _A.xyz : _B.xyz;
|
||||
}
|
||||
else if (mode == 11) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
else if (mode == 11) { // Darker Colour
|
||||
blend = (_A.x + _A.y + _A.z < _B.x + _B.y + _B.z) ? _A.xyz : _B.xyz;
|
||||
}
|
||||
else if (mode == 12) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
else if (mode == 12) { // Screen
|
||||
blend = _A.xyz + _B.xyz - _A.xyz * _B.xyz;
|
||||
}
|
||||
else if (mode == 13) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
else if (mode == 13) { // Overlay
|
||||
blend = vec3(Overlay(_A.x, _B.x), Overlay(_A.y, _B.y), Overlay(_A.z, _B.z));
|
||||
}
|
||||
else if (mode == 14) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
else if (mode == 14) { // Hard Light
|
||||
blend = vec3(HardLight(_A.x, _B.x), HardLight(_A.y, _B.y), HardLight(_A.z, _B.z));
|
||||
}
|
||||
else if (mode == 15) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
else if (mode == 15) { // Soft Light
|
||||
blend = vec3(SoftLight(_A.x, _B.x), SoftLight(_A.y, _B.y), SoftLight(_A.z, _B.z));
|
||||
}
|
||||
else if (mode == 16) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
else if (mode == 16) { // Vivid Light
|
||||
blend = vec3(VividLight(_A.x, _B.x), VividLight(_A.y, _B.y), VividLight(_A.z, _B.z));
|
||||
}
|
||||
else if (mode == 17) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
else if (mode == 17) { // Linear Light
|
||||
blend = 2.0f * _A.xyz + _B.xyz - 1.0f;
|
||||
}
|
||||
else if (mode == 18) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
else if (mode == 18) { // Pin Light
|
||||
blend = vec3(PinLight(_A.x, _B.x), PinLight(_A.y, _B.y), PinLight(_A.z, _B.z));
|
||||
}
|
||||
else if (mode == 19) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
else if (mode == 19) { // Colour Burn
|
||||
blend = 1.0f - (1.0f - _B.xyz) / _A.xyz;
|
||||
}
|
||||
else if (mode == 20) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
else if (mode == 20) { // Linear Burn
|
||||
blend = _A.xyz + _B.xyz - 1.0f;
|
||||
}
|
||||
else if (mode == 21) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
else if (mode == 21) { // Colour Dodge
|
||||
blend = _B.xyz / (1.0f - _A.xyz);
|
||||
}
|
||||
else if (mode == 22) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
else if (mode == 22) { // Hue
|
||||
vec3 d = rgb2hsv(_B.xyz);
|
||||
d.x = rgb2hsv(_A.xyz).x;
|
||||
blend = hsv2rgb(d);
|
||||
}
|
||||
else if (mode == 23) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
else if (mode == 23) { // Saturation
|
||||
vec3 d = rgb2hsv(_B.xyz);
|
||||
d.y = rgb2hsv(_A.xyz).y;
|
||||
blend = hsv2rgb(d);
|
||||
}
|
||||
else if (mode == 24) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
else if (mode == 24) { // Colour
|
||||
vec3 s = rgb2hsv(_A.xyz);
|
||||
s.z = rgb2hsv(_B.xyz).z;
|
||||
blend = hsv2rgb(s);
|
||||
}
|
||||
else if (mode == 25) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
else if (mode == 25) { // Luminosity
|
||||
float dLum = dot(_B.xyz, vec3(0.3, 0.59, 0.11));
|
||||
float sLum = dot(_A.xyz, vec3(0.3, 0.59, 0.11));
|
||||
float lum = sLum - dLum;
|
||||
vec3 c = _B.xyz + lum;
|
||||
float minC = min(min(c.x, c.y), c.z);
|
||||
float maxC = max(max(c.x, c.y), c.z);
|
||||
if (minC < 0.0)
|
||||
blend = sLum + ((c - sLum) * sLum) / (sLum - minC);
|
||||
else if (maxC > 1.0)
|
||||
blend = sLum + ((c - sLum) * (1.0 - sLum)) / (maxC - sLum);
|
||||
else
|
||||
blend = c;
|
||||
}
|
||||
else {
|
||||
gl_FragColor = vec4(uv, 0.0f, 1.0f);
|
||||
blend = vec3(uv, 0.0f);
|
||||
}
|
||||
|
||||
// Porter-Duff Source Over
|
||||
|
|
7
TODO.md
7
TODO.md
|
@ -1,6 +1,5 @@
|
|||
# NOW
|
||||
## Chores
|
||||
- actually write the blending modes (everything is just alpha over right now)
|
||||
- Node groups
|
||||
|
||||
## Compositor
|
||||
|
@ -16,11 +15,11 @@
|
|||
- Motion blur
|
||||
|
||||
## UI
|
||||
- Viewport gizmos (Layer-specific & nodes -- can separate into different tools?) -- Not sure how to go about this
|
||||
- Node loop detection (separate DFS (extra work) or be smart in recursion)
|
||||
- detect time-sensitive nodes in tree and display on timeline
|
||||
- Key selection in comp panel
|
||||
- Graph editor
|
||||
- Node loop detection (separate DFS (extra work) or be smart in recursion)
|
||||
- detect time-sensitive nodes in tree and display on timeline
|
||||
- Viewport gizmos (Layer-specific & nodes -- can separate into different tools?) -- Not sure how to go about this
|
||||
|
||||
# Later
|
||||
## Compositor
|
||||
|
|
Loading…
Add table
Reference in a new issue