Updates to the Pixellate shader.
[bsnes:xml-shaders.git] / shaders / OpenGL / v1.0 / Pixellate.shader
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!--
3     Copyright (c) 2011, 2012 Fes
4
5     Permission to use, copy, modify, and/or distribute this software for any
6     purpose with or without fee is hereby granted, provided that the above
7     copyright notice and this permission notice appear in all copies.
8
9     THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10     WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11     MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
12     SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13     WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14     ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
15     IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
17     (Fes gave their permission to have this shader distributed under this
18     licence in this forum post:
19
20         http://board.byuu.org/styles/serenity/imageset/icon_topic_latest.gif
21
22     )
23
24 -->
25 <shader language="GLSL">
26     <vertex><![CDATA[
27         void main()
28         {
29                 gl_Position    = ftransform();
30                 gl_TexCoord[0] = gl_MultiTexCoord0;
31         }
32     ]]></vertex>
33
34     <fragment filter="nearest"><![CDATA[
35         uniform sampler2D rubyTexture;
36         uniform vec2      rubyTextureSize;
37
38         #define round(x) floor( (x) + 0.5 )
39
40         void main()
41         {
42                 vec2 texelSize = 1.0 / rubyTextureSize;
43                 vec2 texCoord = gl_TexCoord[0].xy;
44
45                 vec2 range = vec2(abs(dFdx(texCoord.x)), abs(dFdy(texCoord.y)));
46                 range = range / 2.0 * 0.999;
47
48                 float left   = texCoord.x - range.x;
49                 float top    = texCoord.y + range.y;
50                 float right  = texCoord.x + range.x;
51                 float bottom = texCoord.y - range.y;
52
53                 vec4 topLeftColor     = texture2D(rubyTexture, vec2(left, top));
54                 vec4 bottomRightColor = texture2D(rubyTexture, vec2(right, bottom));
55                 vec4 bottomLeftColor  = texture2D(rubyTexture, vec2(left, bottom));
56                 vec4 topRightColor    = texture2D(rubyTexture, vec2(right, top));
57
58                 vec2 border = clamp(
59                         round(texCoord / texelSize) * texelSize,
60                         vec2(left, bottom),
61                         vec2(right, top)
62                     );
63
64                 float totalArea = 4.0 * range.x * range.y;
65
66                 vec4 averageColor;
67                 averageColor  = ((border.x - left)  * (top - border.y)    / totalArea) * topLeftColor;
68                 averageColor += ((right - border.x) * (border.y - bottom) / totalArea) * bottomRightColor;
69                 averageColor += ((border.x - left)  * (border.y - bottom) / totalArea) * bottomLeftColor;
70                 averageColor += ((right - border.x) * (top - border.y)    / totalArea) * topRightColor;
71
72                 gl_FragColor = averageColor;
73         }
74     ]]></fragment>
75 </shader>