framework2
132 строки · 6.2 Кб
1/*
2* EdgePass.cpp
3*
4* Copyright (c) 2012, Neil Mendoza, http://www.neilmendoza.com
5* All rights reserved.
6*
7* Redistribution and use in source and binary forms, with or without
8* modification, are permitted provided that the following conditions are met:
9*
10* * Redistributions of source code must retain the above copyright notice,
11* this list of conditions and the following disclaimer.
12* * Redistributions in binary form must reproduce the above copyright
13* notice, this list of conditions and the following disclaimer in the
14* documentation and/or other materials provided with the distribution.
15* * Neither the name of Neil Mendoza nor the names of its contributors may be used
16* to endorse or promote products derived from this software without
17* specific prior written permission.
18*
19* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29* POSSIBILITY OF SUCH DAMAGE.
30*
31*/
32#include "EdgePass.h"
33
34namespace itg
35{
36EdgePass::EdgePass(const ofVec2f& aspect, bool arb) :
37RenderPass(aspect, arb, "edge"), hue(0.5f), saturation(0.f)
38{
39string fragShaderSrc = STRINGIFY(
40uniform SAMPLER_TYPE tex;
41uniform vec2 aspect;
42uniform float hue;
43uniform float saturation;
44
45vec2 texel = vec2(1.0 / aspect.x, 1.0 / aspect.y);
46
47// hard coded matrix values
48mat3 G[9] = mat3[]( mat3( 0.3535533845424652, 0, -0.3535533845424652, 0.5, 0, -0.5, 0.3535533845424652, 0, -0.3535533845424652 ),
49mat3( 0.3535533845424652, 0.5, 0.3535533845424652, 0, 0, 0, -0.3535533845424652, -0.5, -0.3535533845424652 ),
50mat3( 0, 0.3535533845424652, -0.5, -0.3535533845424652, 0, 0.3535533845424652, 0.5, -0.3535533845424652, 0 ),
51mat3( 0.5, -0.3535533845424652, 0, -0.3535533845424652, 0, 0.3535533845424652, 0, 0.3535533845424652, -0.5 ),
52mat3( 0, -0.5, 0, 0.5, 0, 0.5, 0, -0.5, 0 ),
53mat3( -0.5, 0, 0.5, 0, 0, 0, 0.5, 0, -0.5 ),
54mat3( 0.1666666716337204, -0.3333333432674408, 0.1666666716337204, -0.3333333432674408, 0.6666666865348816, -0.3333333432674408, 0.1666666716337204, -0.3333333432674408, 0.1666666716337204 ),
55mat3( -0.3333333432674408, 0.1666666716337204, -0.3333333432674408, 0.1666666716337204, 0.6666666865348816, 0.1666666716337204, -0.3333333432674408, 0.1666666716337204, -0.3333333432674408 ),
56mat3( 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408, 0.3333333432674408 ));
57
58vec3 hsv(float h,float s,float v) { return mix(vec3(1.),clamp((abs(fract(h+vec3(3.,2.,1.)/3.)*6.-3.)-1.),0.,1.),s)*v; }
59
60void main(void)
61{
62mat3 I;
63float cnv[9];
64vec3 sample;
65
66/* fetch the 3x3 neighbourhood and use the RGB vector's length as intensity value */
67for (int i=0; i<3; i++)
68{
69for (int j=0; j<3; j++)
70{
71sample = TEXTURE_FN(tex, gl_TexCoord[0].st + texel * vec2(i-1.0,j-1.0)).rgb;
72I[i][j] = length(sample);
73}
74}
75
76/* calculate the convolution values for all the masks */
77for (int i=0; i<9; i++)
78{
79float dp3 = dot(G[i][0], I[0]) + dot(G[i][1], I[1]) + dot(G[i][2], I[2]);
80cnv[i] = dp3 * dp3;
81}
82
83float M = (cnv[0] + cnv[1]) + (cnv[2] + cnv[3]);
84float S = (cnv[4] + cnv[5]) + (cnv[6] + cnv[7]) + (cnv[8] + M);
85
86gl_FragColor = vec4(hsv(hue, saturation, sqrt(M/S)), 1.0);
87}
88);
89
90ostringstream oss;
91oss << "#version 120" << endl;
92if (arb)
93{
94oss << "#define SAMPLER_TYPE sampler2DRect" << endl;
95oss << "#define TEXTURE_FN texture2DRect" << endl;
96oss << "#extension GL_ARB_texture_rectangle : enable" << endl;
97oss << fragShaderSrc;
98}
99else
100{
101oss << "#define SAMPLER_TYPE sampler2D" << endl;
102oss << "#define TEXTURE_FN texture2D" << endl;
103oss << fragShaderSrc;
104}
105
106shader.setupShaderFromSource(GL_FRAGMENT_SHADER, oss.str());
107shader.linkProgram();
108#ifdef _ITG_TWEAKABLE
109addParameter("hue", this->hue, "min=0 max=1");
110addParameter("saturation", this->saturation, "min=0 max=1");
111#endif
112}
113
114void EdgePass::render(ofFbo& readFbo, ofFbo& writeFbo)
115{
116writeFbo.begin();
117
118shader.begin();
119shader.setUniformTexture("tex", readFbo.getTexture(), 0);
120if (arb) shader.setUniform2f("aspect", 1.f, 1.f);
121else shader.setUniform2f("aspect", aspect.x, aspect.y);
122shader.setUniform1f("hue", hue);
123shader.setUniform1f("saturation", saturation);
124
125if (arb) texturedQuad(0, 0, writeFbo.getWidth(), writeFbo.getHeight(), readFbo.getWidth(), readFbo.getHeight());
126else texturedQuad(0, 0, writeFbo.getWidth(), writeFbo.getHeight());
127
128shader.end();
129
130writeFbo.end();
131}
132}
133