-
Notifications
You must be signed in to change notification settings - Fork 354
/
Copy pathseriously.hue-saturation.js
119 lines (101 loc) · 2.89 KB
/
seriously.hue-saturation.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/* global define, require */
(function (root, factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['seriously'], factory);
} else if (typeof exports === 'object') {
// Node/CommonJS
factory(require('seriously'));
} else {
if (!root.Seriously) {
root.Seriously = { plugin: function (name, opt) { this[name] = opt; } };
}
factory(root.Seriously);
}
}(window, function (Seriously) {
'use strict';
//inspired by Evan Wallace (https://github.com/evanw/glfx.js)
Seriously.plugin('hue-saturation', {
commonShader: true,
shader: function (inputs, shaderSource) {
shaderSource.vertex = [
'precision mediump float;',
'attribute vec4 position;',
'attribute vec2 texCoord;',
'uniform vec2 resolution;',
'uniform mat4 projection;',
'uniform mat4 transform;',
'uniform float hue;',
'uniform float saturation;',
'varying vec2 vTexCoord;',
'varying vec3 weights;',
'void main(void) {',
' float angle = hue * 3.14159265358979323846264;',
' float s = sin(angle);',
' float c = cos(angle);',
' weights = (vec3(2.0 * c, -sqrt(3.0) * s - c, sqrt(3.0) * s - c) + 1.0) / 3.0;',
// first convert to screen space
' vec4 screenPosition = vec4(position.xy * resolution / 2.0, position.z, position.w);',
' screenPosition = transform * screenPosition;',
// convert back to OpenGL coords
' gl_Position = screenPosition;',
' gl_Position.xy = screenPosition.xy * 2.0 / resolution;',
' gl_Position.z = screenPosition.z * 2.0 / (resolution.x / resolution.y);',
' vTexCoord = texCoord;',
'}'
].join('\n');
shaderSource.fragment = [
'precision mediump float;',
'varying vec2 vTexCoord;',
'varying vec3 weights;',
'uniform sampler2D source;',
'uniform float hue;',
'uniform float saturation;',
'void main(void) {',
' vec4 color = texture2D(source, vTexCoord);',
//adjust hue
' float len = length(color.rgb);',
' color.rgb = vec3(' +
'dot(color.rgb, weights.xyz), ' +
'dot(color.rgb, weights.zxy), ' +
'dot(color.rgb, weights.yzx) ' +
');',
//adjust saturation
' vec3 adjustment = (color.r + color.g + color.b) / 3.0 - color.rgb;',
' if (saturation > 0.0) {',
' adjustment *= (1.0 - 1.0 / (1.0 - saturation));',
' } else {',
' adjustment *= (-saturation);',
' }',
' color.rgb += adjustment;',
' gl_FragColor = color;',
'}'
].join('\n');
return shaderSource;
},
inPlace: true,
inputs: {
source: {
type: 'image',
uniform: 'source'
},
hue: {
type: 'number',
uniform: 'hue',
defaultValue: 0.4,
min: -1,
max: 1
},
saturation: {
type: 'number',
uniform: 'saturation',
defaultValue: 0,
min: -1,
max: 1
}
},
title: 'Hue/Saturation',
description: 'Rotate hue and multiply saturation.'
});
}));