Browse Source

tutorial: smarter register and instruction usage in the Mandelbrot zooming

shader.
legacy
Sam Hocevar sam 14 years ago
parent
commit
6640cacd29
1 changed files with 57 additions and 85 deletions
  1. +57
    -85
      test/tutorial/tut03.cpp

+ 57
- 85
test/tutorial/tut03.cpp View File

@@ -394,8 +394,7 @@ public:
"attribute vec2 a_TexCoord;"
"attribute vec2 a_Vertex;"
""
"varying vec2 A0, A1, A2, A3;"
"varying vec2 B0, B1, B2, B3;"
"varying vec4 v_CenterX, v_CenterY, v_IndexX, v_IndexY;"
""
"void main(void)"
"{"
@@ -406,26 +405,30 @@ public:
* compute the value for. Then add or remove half the
* size of a texel: the distance from this new point to
* the final point will be our error. */
" A0 = a_TexCoord * u_ZoomSettings[0][2]"
" + vec2(u_ZoomSettings[0][0], -u_ZoomSettings[0][1])"
" + 0.5 * u_TexelSize.xy;"
" A1 = a_TexCoord * u_ZoomSettings[1][2]"
" + vec2(u_ZoomSettings[1][0], -u_ZoomSettings[1][1])"
" + -0.5 * u_TexelSize.xy;"
" A2 = a_TexCoord * u_ZoomSettings[2][2]"
" + vec2(u_ZoomSettings[2][0], -u_ZoomSettings[2][1])"
" + vec2(0.5, -0.5) * u_TexelSize.xy;"
" A3 = a_TexCoord * u_ZoomSettings[3][2]"
" + vec2(u_ZoomSettings[3][0], -u_ZoomSettings[3][1])"
" + vec2(-0.5, 0.5) * u_TexelSize.xy;"
" vec4 offsets = vec4(0.5, -0.5, 0.015625, -0.015625);"
" vec4 zoomscale = vec4(u_ZoomSettings[0][2],"
" u_ZoomSettings[1][2],"
" u_ZoomSettings[2][2],"
" u_ZoomSettings[3][2]);"
" vec4 zoomtx = vec4(u_ZoomSettings[0][0],"
" u_ZoomSettings[1][0],"
" u_ZoomSettings[2][0],"
" u_ZoomSettings[3][0]);"
" vec4 zoomty = vec4(u_ZoomSettings[0][1],"
" u_ZoomSettings[1][1],"
" u_ZoomSettings[2][1],"
" u_ZoomSettings[3][1]);"
/* Pass all this to the fragment shader */
" v_CenterX = zoomscale * a_TexCoord.x + zoomtx"
" + offsets.xyxy * u_TexelSize.x;"
" v_CenterY = zoomscale * a_TexCoord.y - zoomty"
" + offsets.xyyx * u_TexelSize.y;"
/* Precompute the multiple of one texel where our ideal
* point lies. The fragment shader will call floor() on
* this value. We add or remove a slight offset to avoid
* rounding issues at the image's edges. */
" B0 = (A0 * u_TexelSize.zw + vec2(-0.015625, -0.015625));"
" B1 = (A1 * u_TexelSize.zw + vec2( 0.015625, 0.015625));"
" B2 = (A2 * u_TexelSize.zw + vec2(-0.015625, 0.015625));"
" B3 = (A3 * u_TexelSize.zw + vec2( 0.015625, -0.015625));"
" v_IndexX = v_CenterX * u_TexelSize.z - offsets.zwzw;"
" v_IndexY = v_CenterY * u_TexelSize.w - offsets.zwwz;"
"}",

#if !defined HAVE_GLES_2X
@@ -437,77 +440,46 @@ public:
"uniform vec4 u_TexelSize;"
"uniform sampler2D in_Texture;"
""
"varying vec2 A0, A1, A2, A3;"
"varying vec2 B0, B1, B2, B3;"
""
"vec2 v05 = vec2(0.5, 0.5);"
""
"float mylen(vec2 p)"
"{"
" p *= u_TexelSize.zw;" /* Correct for aspect ratio */
//" return 0.001 + abs(p.x) + abs(p.y);"
//" return 0.1 + length(p);"
" vec2 q = p * p;"
" return 0.01 + q.x + q.y;"
"}"
""
/* Get the coordinate of the nearest point in slice 0 in xy,
* and the squared distance to that point in z.
* return value has the 0.25 Y scaling. */
"vec3 nearest0()"
"{"
" vec2 r = u_TexelSize.xy * (1.0 + 2.0 * floor(B0));"
" vec2 t = step(abs(r - v05), v05);"
" float l = t.x * t.y / mylen(r - A0);"
" return vec3(r * vec2(1.0, 0.25), l);"
"}"
""
"vec3 nearest1()"
"{"
" vec2 r = u_TexelSize.xy * (1.0 + 2.0 * floor(B1));"
" vec2 t = step(abs(r - v05), v05);"
" float l = t.x * t.y / mylen(r - A1);"
" return vec3(r * vec2(1.0, 0.25) + vec2(0.0, 0.25), l);"
"}"
""
"vec3 nearest2()"
"{"
" vec2 r = u_TexelSize.xy * (1.0 + 2.0 * floor(B2));"
" vec2 t = step(abs(r - v05), v05);"
" float l = t.x * t.y / mylen(r - A2);"
" return vec3(r * vec2(1.0, 0.25) + vec2(0.0, 0.50), l);"
"}"
""
"vec3 nearest3()"
"{"
" vec2 r = u_TexelSize.xy * (1.0 + 2.0 * floor(B3));"
" vec2 t = step(abs(r - v05), v05);"
" float l = t.x * t.y / mylen(r - A3);"
" return vec3(r * vec2(1.0, 0.25) + vec2(0.0, 0.75), l);"
"}"
"varying vec4 v_CenterX, v_CenterY, v_IndexX, v_IndexY;"
""
"void main(void)"
"{"
/* Get a pixel coordinate from each slice */
" vec3 k0 = nearest0();"
" vec3 k1 = nearest1();"
" vec3 k2 = nearest2();"
" vec3 k3 = nearest3();"
/* Get the nearest pixel */
" float t01 = step(k0.z, k1.z);"
" k0 = mix(k0, k1, t01);"
" float t23 = step(k2.z, k3.z);"
" k2 = mix(k2, k3, t23);"
" float t02 = step(k0.z, k2.z);"
" k0 = mix(k0, k2, t02);"
" gl_FragColor = texture2D(in_Texture, k0.xy);"
/* Get a pixel coordinate from each slice into rx & ry */
" vec4 rx = u_TexelSize.x * (1.0 + 2.0 * floor(v_IndexX));"
" vec4 ry = u_TexelSize.y * (1.0 + 2.0 * floor(v_IndexY));"
/* Compute distance to expected pixel in dd */
" vec4 v05 = vec4(0.5, 0.5, 0.5, 0.5);"
" vec4 t0 = step(abs(rx - v05), v05)"
" * step(abs(ry - v05), v05);"
" vec4 dx = rx - v_CenterX;"
" vec4 dy = ry - v_CenterY;"
//" vec4 dd = t0 * (abs(dx) + abs(dy));"
//" vec4 dd = t0 / (0.001 + sqrt((dx * dx) + (dy * dy)));"
" vec4 dd = t0 / (0.000001 + (dx * dx) + (dy * dy));"
/* Modify Y coordinate to select proper quarter. */
" ry = ry * 0.25 + vec4(0.0, 0.25, 0.5, 0.75);"
""
#if 1
/* Put min(.x,.y) in .x and min(.z,.w) in .z */
" vec4 t1 = step(dd, dd.yyww);"
" rx = mix(rx, rx.yyww, t1);"
" ry = mix(ry, ry.yyww, t1);"
" dd = mix(dd, dd.yyww, t1);"
/* Put min(x,z) in x */
" vec4 t2 = step(dd, dd.zzzz);"
" rx = mix(rx, rx.zzzz, t2);"
" ry = mix(ry, ry.zzzz, t2);"
/* Nearest neighbour */
" gl_FragColor = texture2D(in_Texture, vec2(rx.x, ry.x));"
#else
/* Alternate version: some kind of linear interpolation */
// " vec4 p0 = texture2D(in_Texture, k0.xy);"
// " vec4 p1 = texture2D(in_Texture, k1.xy);"
// " vec4 p2 = texture2D(in_Texture, k2.xy);"
// " vec4 p3 = texture2D(in_Texture, k3.xy);"
// " gl_FragColor = 1.0 / (k0.z + k1.z + k2.z + k3.z)"
// " * (k0.z * p0 + k1.z * p1 + k2.z * p2 + k3.z * p3);"
" vec4 p0 = texture2D(in_Texture, vec2(rx.x, ry.x));"
" vec4 p1 = texture2D(in_Texture, vec2(rx.y, ry.y));"
" vec4 p2 = texture2D(in_Texture, vec2(rx.z, ry.z));"
" vec4 p3 = texture2D(in_Texture, vec2(rx.w, ry.w));"
" gl_FragColor = 1.0 / (dd.x + dd.y + dd.z + dd.w)"
" * (dd.x * p0 + dd.y * p1 + dd.z * p2 + dd.w * p3);"
#endif
"}"
#else
"void main(float4 in_Position : POSITION,"


Loading…
Cancel
Save