source: trunk/tutorial/11_fractal.lolfx @ 1928

Last change on this file since 1928 was 1928, checked in by sam, 8 years ago

lolfx: use square brackets to indicate shader sections.

File size: 7.0 KB
Line 
1[vert.glsl]
2
3#version 120
4
5#if defined GL_ES
6precision highp float;
7#endif
8
9uniform mat4 u_ZoomSettings;
10uniform vec4 u_TexelSize;
11uniform vec4 u_ScreenSize;
12
13attribute vec2 a_TexCoord;
14attribute vec2 a_Vertex;
15
16varying vec4 v_CenterX, v_CenterY, v_IndexX, v_IndexY;
17
18void main(void)
19{
20    gl_Position = vec4(a_Vertex, 0.0, 1.0);
21    /* Center point in [-.5,.5], apply zoom and translation
22     * transformation, and go back to texture coordinates
23     * in [0,1]. That's the ideal point we would like to
24     * compute the value for. Then add or remove half the
25     * size of a texel: the distance from this new point to
26     * the final point will be our error. */
27    vec4 offsets = vec4(0.5, -0.5, 0.015625, -0.015625);
28    vec4 zoomscale = vec4(u_ZoomSettings[0][2],
29                          u_ZoomSettings[1][2],
30                          u_ZoomSettings[2][2],
31                          u_ZoomSettings[3][2]);
32    vec4 zoomtx = vec4(u_ZoomSettings[0][0],
33                       u_ZoomSettings[1][0],
34                       u_ZoomSettings[2][0],
35                       u_ZoomSettings[3][0]);
36    vec4 zoomty = vec4(u_ZoomSettings[0][1],
37                       u_ZoomSettings[1][1],
38                       u_ZoomSettings[2][1],
39                       u_ZoomSettings[3][1]);
40    v_CenterX = zoomscale * a_TexCoord.x + zoomtx
41              + offsets.xyxy * u_TexelSize.x;
42    v_CenterY = zoomscale * a_TexCoord.y - zoomty
43              + offsets.xyyx * u_TexelSize.y;
44    /* Precompute the multiple of one texel where our ideal
45     * point lies. The fragment shader will call floor() on
46     * this value. We add or remove a slight offset to avoid
47     * rounding issues at the image's edges. */
48    v_IndexX = v_CenterX * u_ScreenSize.z - offsets.zwzw;
49    v_IndexY = v_CenterY * u_ScreenSize.w - offsets.zwwz;
50}
51
52[frag.glsl]
53
54#version 120
55
56#if defined GL_ES
57precision highp float;
58#endif
59
60uniform vec4 u_TexelSize;
61uniform sampler2D u_Texture;
62
63varying vec4 v_CenterX, v_CenterY, v_IndexX, v_IndexY;
64
65void main(void)
66{
67    vec4 v05 = vec4(0.5, 0.5, 0.5, 0.5);
68    vec4 rx, ry, t0, dx, dy, dd;
69    /* Get a pixel coordinate from each slice into rx & ry */
70    rx = u_TexelSize.x + u_TexelSize.z * floor(v_IndexX);
71    ry = u_TexelSize.y + u_TexelSize.w * floor(v_IndexY);
72    /* Compute inverse distance to expected pixel in dd,
73     * and put zero if we fall outside the texture. */
74    t0 = step(abs(rx - v05), v05) * step(abs(ry - v05), v05);
75    dx = rx - v_CenterX;
76    dy = ry - v_CenterY;
77#if 0
78    vec4 dd = t0 * (abs(dx) + abs(dy));
79    vec4 dd = t0 / (0.001 + sqrt((dx * dx) + (dy * dy)));
80#endif
81    dd = t0 / (0.000001 + (dx * dx) + (dy * dy));
82    /* Modify Y coordinate to select proper quarter. */
83    ry = ry * 0.25 + vec4(0.0, 0.25, 0.5, 0.75);
84
85#if 1
86#   if 0
87    /* XXX: disabled until we can autodetect i915 */
88    /* t1.x <-- dd.x > dd.y */
89    /* t1.y <-- dd.z > dd.w */
90    vec2 t1 = step(dd.xz, dd.yw);
91    /* ret.x <-- max(rx.x, rx.y) wrt. t1.x */
92    /* ret.y <-- max(rx.z, rx.w) wrt. t1.y */
93    /* ret.z <-- max(ry.x, ry.y) wrt. t1.x */
94    /* ret.w <-- max(ry.z, ry.w) wrt. t1.y */
95    vec4 ret = mix(vec4(rx.xz, ry.xz),
96                   vec4(rx.yw, ry.yw), t1.xyxy);
97    /* dd.x <-- max(dd.x, dd.y) */
98    /* dd.z <-- max(dd.z, dd.w) */
99    dd.xy = mix(dd.xz, dd.yw, t1);
100    /* t2 <-- dd.x > dd.z */
101    float t2 = step(dd.x, dd.y);
102    /* ret.x <-- max(ret.x, ret.y); */
103    /* ret.y <-- max(ret.z, ret.w); */
104    ret.xy = mix(ret.xz, ret.yw, t2);
105#   else
106    /* Fallback for i915 cards -- the trick to reduce the
107     * number of operations is to compute both step(a,b)
108     * and step(b,a) and hope that their sum is 1. This is
109     * almost always the case, and when it isn't we can
110     * afford to have a few wrong pixels. However, a real
111     * problem is when panning the image, because half the
112     * screen is likely to flicker. To avoid this problem,
113     * we cheat a little (see m_translate comment above). */
114    vec4 t1 = step(dd.xzyw, dd.ywxz);
115    vec4 ret = vec4(rx.xz, ry.xz) * t1.zwzw
116             + vec4(rx.yw, ry.yw) * t1.xyxy;
117    dd.xy = dd.xz * t1.zw + dd.yw * t1.xy;
118    vec2 t2 = step(dd.xy, dd.yx);
119    ret.xy = ret.xz * t2.yy + ret.yw * t2.xx;
120#   endif
121    /* Nearest neighbour */
122    gl_FragColor = texture2D(u_Texture, ret.xy);
123#else
124    /* Alternate version: some kind of linear interpolation */
125    vec4 p0 = texture2D(u_Texture, vec2(rx.x, ry.x));
126    vec4 p1 = texture2D(u_Texture, vec2(rx.y, ry.y));
127    vec4 p2 = texture2D(u_Texture, vec2(rx.z, ry.z));
128    vec4 p3 = texture2D(u_Texture, vec2(rx.w, ry.w));
129    gl_FragColor = 1.0 / (dd.x + dd.y + dd.z + dd.w)
130                 * (dd.x * p0 + dd.y * p1 + dd.z * p2 + dd.w * p3);
131#endif
132}
133
134[vert.hlsl]
135
136void main(float2 a_Vertex : POSITION,
137          float2 a_TexCoord : TEXCOORD0,
138          uniform float4x4 u_ZoomSettings,
139          uniform float4 u_TexelSize,
140          uniform float4 u_ScreenSize,
141          out float4 out_Position : POSITION0,
142          out float4 v_CenterX : TEXCOORD0,
143          out float4 v_CenterY : TEXCOORD1,
144          out float4 v_IndexX : TEXCOORD2,
145          out float4 v_IndexY : TEXCOORD3)
146{
147    out_Position = float4(a_Vertex, 0.0, 1.0);
148    float4 offsets = float4(0.5, -0.5, 0.015625, -0.015625);
149    float4 zoomscale = float4(u_ZoomSettings[2][0],
150                              u_ZoomSettings[2][1],
151                              u_ZoomSettings[2][2],
152                              u_ZoomSettings[2][3]);
153    float4 zoomtx = float4(u_ZoomSettings[0][0],
154                           u_ZoomSettings[0][1],
155                           u_ZoomSettings[0][2],
156                           u_ZoomSettings[0][3]);
157    float4 zoomty = float4(u_ZoomSettings[1][0],
158                           u_ZoomSettings[1][1],
159                           u_ZoomSettings[1][2],
160                           u_ZoomSettings[1][3]);
161    v_CenterX = zoomscale * a_TexCoord.x + zoomtx
162              + offsets.xyxy * u_TexelSize.x;
163    v_CenterY = zoomscale * a_TexCoord.y - zoomty
164              + offsets.xyyx * u_TexelSize.y;
165    v_IndexX = v_CenterX * u_ScreenSize.z - offsets.zwzw;
166    v_IndexY = v_CenterY * u_ScreenSize.w - offsets.zwwz;
167}
168
169[frag.hlsl]
170
171void main(in float4 v_CenterX : TEXCOORD0,
172          in float4 v_CenterY : TEXCOORD1,
173          in float4 v_IndexX : TEXCOORD2,
174          in float4 v_IndexY : TEXCOORD3,
175          uniform float4 u_TexelSize,
176          uniform sampler2D u_Texture,
177          out float4 out_FragColor : COLOR)
178{
179    float4 v05 = float4(0.5, 0.5, 0.5, 0.5);
180    float4 rx, ry, t0, dx, dy, dd;
181    rx = u_TexelSize.x + u_TexelSize.z * floor(v_IndexX);
182    ry = u_TexelSize.y + u_TexelSize.w * floor(v_IndexY);
183    t0 = step(abs(rx - v05), v05) * step(abs(ry - v05), v05);
184    dx = rx - v_CenterX;
185    dy = ry - v_CenterY;
186    dd = t0 / (0.000001 + (dx * dx) + (dy * dy));
187    ry = ry * 0.25 + float4(0.0, 0.25, 0.5, 0.75);
188    float2 t1 = step(dd.xz, dd.yw);
189    float4 ret = lerp(float4(rx.xz, ry.xz),
190                      float4(rx.yw, ry.yw), t1.xyxy);
191    dd.xy = lerp(dd.xz, dd.yw, t1);
192    float t2 = step(dd.x, dd.y);
193    ret.xy = lerp(ret.xz, ret.yw, t2);
194    out_FragColor = tex2D(u_Texture, ret.xy);
195}
196
Note: See TracBrowser for help on using the repository browser.