Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0a101322 authored by Ruei-sung Lin's avatar Ruei-sung Lin
Browse files

Fix b/6575950 make shader program to support different precisions.

1. In shade code of Vignette and Fisheye, change from
   pixel coordinates to texture coordinates to avoid overflow.

2. Fix bug in ColorTemperature shader code

3. Revise shader code pseudo random number generator (used by
   BlackWhite, Grain, Lomo, Documentary filters) to ensure
   it produces no artifacts among devices with different precisions.

Change-Id: Ifb67f12f114bc9cd7fbfa74f7782f130c5244e5d
parent 9d820ecc
Loading
Loading
Loading
Loading
+19 −7
Original line number Diff line number Diff line
@@ -56,13 +56,25 @@ public class BlackWhiteFilter extends Filter {
            "uniform float stepsize;\n" +
            "varying vec2 v_texcoord;\n" +
            "float rand(vec2 loc) {\n" +
            "  const float divide = 0.00048828125;\n" +
            "  const float factor = 2048.0;\n" +
            "  float value = sin(dot(loc, vec2(12.9898, 78.233)));\n" +
            "  float residual = mod(dot(mod(loc, divide), vec2(0.9898, 0.233)), divide);\n" +
            "  float part2 = mod(value, divide);\n" +
            "  float part1 = value - part2;\n" +
            "  return fract(0.5453 * part1 + factor * (part2 + residual));\n" +
            // Compute sin(theta), theta = 12.9898 x + 78.233y
            // because floating point has limited range, make theta = theta1 + theta2
            // where theta1 = 12x + 78y and theta2 = 0.9898x + 0.233y)
            // Note that theta1 and theta2 cover diffent range of theta.
            "  float theta1 = dot(loc, vec2(0.9898, 0.233));\n" +
            "  float theta2 = dot(loc, vec2(12.0, 78.0));\n" +
            // Use the property sin(theta) = cos(theta1)*sin(theta2)+sin(theta1)*cos(theta2)
            // this approach also increases the precisions of sin(theta)
            "  float value = cos(theta1) * sin(theta2) + sin(theta1) * cos(theta2);\n" +
            // fract(43758.5453 * x) = fract(43758 * x + 0.5453 * x)
            // keep value of part1 in range: (2^-14 to 2^14). Since 43758 = 117 * 374
            // fract(43758 * sin(theta)) = mod(221 * mod(198*sin(theta), 1.0), 1.0)
            // also to keep as much decimal digits, use the property
            // mod(mod(198*sin(theta)) = mod(mod(197*sin(theta) + sin(theta))
            "  float temp = mod(197.0 * value, 1.0) + value;\n" +
            "  float part1 = mod(220.0 * temp, 1.0) + temp;\n" +
            "  float part2 = value * 0.5453;\n" +
            "  float part3 = cos(theta1 + theta2) * 0.43758;\n" +
            "  return fract(part1 + part2 + part3);\n" +
            "}\n" +
            "void main() {\n" +
            "  vec4 color = texture2D(tex_sampler_0, v_texcoord);\n" +
+1 −1
Original line number Diff line number Diff line
@@ -51,7 +51,7 @@ public class ColorTemperatureFilter extends Filter {
            "  new_color.r = color.r + color.r * ( 1.0 - color.r) * scale;\n" +
            "  new_color.b = color.b - color.b * ( 1.0 - color.b) * scale;\n" +
            "  if (scale > 0.0) { \n" +
            "    color.g = color.g + color.g * ( 1.0 - color.g) * scale * 0.25;\n" +
            "    new_color.g = color.g + color.g * ( 1.0 - color.g) * scale * 0.25;\n" +
            "  }\n" +
            "  float max_value = max(new_color.r, max(new_color.g, new_color.b));\n" +
            "  if (max_value > 1.0) { \n" +
+23 −15
Original line number Diff line number Diff line
@@ -49,16 +49,18 @@ public class DocumentaryFilter extends Filter {
            "uniform vec2 seed;\n" +
            "uniform float stepsize;\n" +
            "uniform float inv_max_dist;\n" +
            "uniform vec2 center;\n" +
            "uniform vec2 scale;\n" +
            "varying vec2 v_texcoord;\n" +
            "float rand(vec2 loc) {\n" +
            "  const float divide = 0.00048828125;\n" +
            "  const float factor = 2048.0;\n" +
            "  float value = sin(dot(loc, vec2(12.9898, 78.233)));\n" +
            "  float residual = mod(dot(mod(loc, divide), vec2(0.9898, 0.233)), divide);\n" +
            "  float part2 = mod(value, divide);\n" +
            "  float part1 = value - part2;\n" +
            "  return fract(0.5453 * part1 + factor * (part2 + residual));\n" +
            "  float theta1 = dot(loc, vec2(0.9898, 0.233));\n" +
            "  float theta2 = dot(loc, vec2(12.0, 78.0));\n" +
            "  float value = cos(theta1) * sin(theta2) + sin(theta1) * cos(theta2);\n" +
            // keep value of part1 in range: (2^-14 to 2^14).
            "  float temp = mod(197.0 * value, 1.0) + value;\n" +
            "  float part1 = mod(220.0 * temp, 1.0) + temp;\n" +
            "  float part2 = value * 0.5453;\n" +
            "  float part3 = cos(theta1 + theta2) * 0.43758;\n" +
            "  return fract(part1 + part2 + part3);\n" +
            "}\n" +
            "void main() {\n" +
            // black white
@@ -71,7 +73,8 @@ public class DocumentaryFilter extends Filter {
            "  float gray = dot(new_color, vec3(0.299, 0.587, 0.114));\n" +
            "  new_color = vec3(gray, gray, gray);\n" +
            // vignette
            "  float dist = distance(gl_FragCoord.xy, center);\n" +
            "  vec2 coord = v_texcoord - vec2(0.5, 0.5);\n" +
            "  float dist = length(coord * scale);\n" +
            "  float lumen = 0.85 / (1.0 + exp((dist * inv_max_dist - 0.83) * 20.0)) + 0.15;\n" +
            "  gl_FragColor = vec4(new_color * lumen, color.a);\n" +
            "}\n";
@@ -141,12 +144,17 @@ public class DocumentaryFilter extends Filter {

    private void initParameters() {
        if (mProgram != null) {
            float centerX = (float) (0.5 * mWidth);
            float centerY = (float) (0.5 * mHeight);
            float center[] = {centerX, centerY};
            float max_dist = (float) Math.sqrt(centerX * centerX + centerY * centerY);
            float scale[] = new float[2];
            if (mWidth > mHeight) {
                scale[0] = 1f;
                scale[1] = ((float) mHeight) / mWidth;
            } else {
                scale[0] = ((float) mWidth) / mHeight;
                scale[1] = 1f;
            }
            float max_dist = ((float) Math.sqrt(scale[0] * scale[0] + scale[1] * scale[1])) * 0.5f;

            mProgram.setHostValue("center", center);
            mProgram.setHostValue("scale", scale);
            mProgram.setHostValue("inv_max_dist", 1.0f / max_dist);
            mProgram.setHostValue("stepsize", 1.0f / 255.0f);

+17 −22
Original line number Diff line number Diff line
@@ -58,24 +58,19 @@ public class FisheyeFilter extends Filter {
    private static final String mFisheyeShader =
            "precision mediump float;\n" +
            "uniform sampler2D tex_sampler_0;\n" +
            "uniform vec2 center;\n" +
            "uniform vec2 scale;\n" +
            "uniform float alpha;\n" +
            "uniform float bound;\n" +
            "uniform float radius2;\n" +
            "uniform float factor;\n" +
            "uniform float inv_height;\n" +
            "uniform float inv_width;\n" +
            "varying vec2 v_texcoord;\n" +
            "void main() {\n" +
            "  const float m_pi_2 = 1.570963;\n" +
            "  float dist = distance(gl_FragCoord.xy, center);\n" +
            "  vec2 coord = v_texcoord - vec2(0.5, 0.5);\n" +
            "  float dist = length(coord * scale);\n" +
            "  float radian = m_pi_2 - atan(alpha * sqrt(radius2 - dist * dist), dist);\n" +
            "  float scale = radian * factor / dist;\n" +
            "  vec2 new_coord = gl_FragCoord.xy * scale + (1.0 - scale) * center;\n" +
            "  new_coord.x *= inv_width;\n" +
            "  new_coord.y *= inv_height;\n" +
            "  vec4 color = texture2D(tex_sampler_0, new_coord);\n" +
            "  gl_FragColor = color;\n" +
            "  float scalar = radian * factor / dist;\n" +
            "  vec2 new_coord = coord * scalar + vec2(0.5, 0.5);\n" +
            "  gl_FragColor = texture2D(tex_sampler_0, new_coord);\n" +
            "}\n";

    public FisheyeFilter(String name) {
@@ -145,12 +140,6 @@ public class FisheyeFilter extends Filter {
    }

    private void updateFrameSize(int width, int height) {
        float center[] = {0.5f * width, 0.5f * height};

        mProgram.setHostValue("center", center);
        mProgram.setHostValue("inv_width", 1.0f / width);
        mProgram.setHostValue("inv_height", 1.0f / height);

        mWidth = width;
        mHeight = height;

@@ -159,9 +148,16 @@ public class FisheyeFilter extends Filter {

    private void updateProgramParams() {
        final float pi = 3.14159265f;

        float scale[] = new float[2];
        if (mWidth > mHeight) {
          scale[0] = 1f;
          scale[1] = ((float) mHeight) / mWidth;
        } else {
          scale[0] = ((float) mWidth) / mHeight;
          scale[1] = 1f;
        }
        float alpha = mScale * 2.0f + 0.75f;
        float bound2 = 0.25f * (mWidth * mWidth  + mHeight * mHeight);
        float bound2 = 0.25f * (scale[0] * scale[0] + scale[1] * scale[1]);
        float bound = (float) Math.sqrt(bound2);
        float radius = 1.15f * bound;
        float radius2 = radius * radius;
@@ -169,10 +165,9 @@ public class FisheyeFilter extends Filter {
            (float) Math.atan(alpha / bound * (float) Math.sqrt(radius2 - bound2));
        float factor = bound / max_radian;

        mProgram.setHostValue("scale", scale);
        mProgram.setHostValue("radius2",radius2);
        mProgram.setHostValue("factor", factor);
        mProgram.setHostValue("alpha", (float) (mScale * 2.0 + 0.75));
        mProgram.setHostValue("alpha", alpha);
    }


}
+9 −7
Original line number Diff line number Diff line
@@ -57,13 +57,15 @@ public class GrainFilter extends Filter {
            "uniform vec2 seed;\n" +
            "varying vec2 v_texcoord;\n" +
            "float rand(vec2 loc) {\n" +
            "  const float divide = 0.00048828125;\n" +
            "  const float factor = 2048.0;\n" +
            "  float value = sin(dot(loc, vec2(12.9898, 78.233)));\n" +
            "  float residual = mod(dot(mod(loc, divide), vec2(0.9898, 0.233)), divide);\n" +
            "  float part2 = mod(value, divide);\n" +
            "  float part1 = value - part2;\n" +
            "  return fract(0.5453 * part1 + factor * (part2 + residual));\n" +
            "  float theta1 = dot(loc, vec2(0.9898, 0.233));\n" +
            "  float theta2 = dot(loc, vec2(12.0, 78.0));\n" +
            "  float value = cos(theta1) * sin(theta2) + sin(theta1) * cos(theta2);\n" +
            // keep value of part1 in range: (2^-14 to 2^14).
            "  float temp = mod(197.0 * value, 1.0) + value;\n" +
            "  float part1 = mod(220.0 * temp, 1.0) + temp;\n" +
            "  float part2 = value * 0.5453;\n" +
            "  float part3 = cos(theta1 + theta2) * 0.43758;\n" +
            "  return fract(part1 + part2 + part3);\n" +
            "}\n" +
            "void main() {\n" +
            "  gl_FragColor = vec4(rand(v_texcoord + seed), 0.0, 0.0, 1.0);\n" +
Loading