framework2
134 строки · 6.0 Кб
1/*
2* FxaaPass.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 "FxaaPass.h"
33
34namespace itg
35{
36FxaaPass::FxaaPass(const ofVec2f& aspect, bool arb) : RenderPass(aspect, arb, "fxaa")
37{
38string fragShaderSrc = STRINGIFY(
39uniform SAMPLER_TYPE tDiffuse;
40uniform vec2 resolution;
41
42varying vec2 vUv;
43
44const float FXAA_REDUCE_MIN = 1.0/128.0;
45const float FXAA_REDUCE_MUL = 1.0/8.0;
46const float FXAA_SPAN_MAX = 8.0;
47
48void main() {
49
50vec3 rgbNW = TEXTURE_FN( tDiffuse, ( gl_FragCoord.xy + vec2( -1.0, -1.0 ) ) * resolution ).xyz;
51vec3 rgbNE = TEXTURE_FN( tDiffuse, ( gl_FragCoord.xy + vec2( 1.0, -1.0 ) ) * resolution ).xyz;
52vec3 rgbSW = TEXTURE_FN( tDiffuse, ( gl_FragCoord.xy + vec2( -1.0, 1.0 ) ) * resolution ).xyz;
53vec3 rgbSE = TEXTURE_FN( tDiffuse, ( gl_FragCoord.xy + vec2( 1.0, 1.0 ) ) * resolution ).xyz;
54vec4 rgbaM = TEXTURE_FN( tDiffuse, gl_FragCoord.xy * resolution );
55vec3 rgbM = rgbaM.xyz;
56float opacity = rgbaM.w;
57
58vec3 luma = vec3( 0.299, 0.587, 0.114 );
59
60float lumaNW = dot( rgbNW, luma );
61float lumaNE = dot( rgbNE, luma );
62float lumaSW = dot( rgbSW, luma );
63float lumaSE = dot( rgbSE, luma );
64float lumaM = dot( rgbM, luma );
65float lumaMin = min( lumaM, min( min( lumaNW, lumaNE ), min( lumaSW, lumaSE ) ) );
66float lumaMax = max( lumaM, max( max( lumaNW, lumaNE) , max( lumaSW, lumaSE ) ) );
67
68vec2 dir;
69dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
70dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
71
72float dirReduce = max( ( lumaNW + lumaNE + lumaSW + lumaSE ) * ( 0.25 * FXAA_REDUCE_MUL ), FXAA_REDUCE_MIN );
73
74float rcpDirMin = 1.0 / ( min( abs( dir.x ), abs( dir.y ) ) + dirReduce );
75dir = min( vec2( FXAA_SPAN_MAX, FXAA_SPAN_MAX),
76max( vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
77dir * rcpDirMin)) * resolution;
78
79vec3 rgbA = 0.5 * (
80TEXTURE_FN( tDiffuse, gl_FragCoord.xy * resolution + dir * ( 1.0 / 3.0 - 0.5 ) ).xyz +
81TEXTURE_FN( tDiffuse, gl_FragCoord.xy * resolution + dir * ( 2.0 / 3.0 - 0.5 ) ).xyz );
82
83vec3 rgbB = rgbA * 0.5 + 0.25 * (
84TEXTURE_FN( tDiffuse, gl_FragCoord.xy * resolution + dir * -0.5 ).xyz +
85TEXTURE_FN( tDiffuse, gl_FragCoord.xy * resolution + dir * 0.5 ).xyz );
86
87float lumaB = dot( rgbB, luma );
88
89if ( ( lumaB < lumaMin ) || ( lumaB > lumaMax ) ) {
90
91gl_FragColor = vec4( rgbA, opacity );
92
93} else {
94
95gl_FragColor = vec4( rgbB, opacity );
96
97}
98
99}
100);
101ostringstream oss;
102oss << "#version 120" << endl;
103if (arb)
104{
105oss << "#define SAMPLER_TYPE sampler2DRect" << endl;
106oss << "#define TEXTURE_FN texture2DRect" << endl;
107oss << fragShaderSrc;
108}
109else
110{
111oss << "#define SAMPLER_TYPE sampler2D" << endl;
112oss << "#define TEXTURE_FN texture2D" << endl;
113oss << fragShaderSrc;
114}
115shader.setupShaderFromSource(GL_FRAGMENT_SHADER, oss.str());
116shader.linkProgram();
117}
118
119void FxaaPass::render(ofFbo& readFbo, ofFbo& writeFbo)
120{
121writeFbo.begin();
122
123shader.begin();
124
125shader.setUniformTexture("tDiffuse", readFbo.getTexture(), 0);
126if (arb) shader.setUniform2f("resolution", 1.f, 1.f);
127else shader.setUniform2f("resolution", 1.f / writeFbo.getWidth(), 1.f / writeFbo.getHeight());
128
129texturedQuad(0, 0, writeFbo.getWidth(), writeFbo.getHeight());
130
131shader.end();
132writeFbo.end();
133}
134}