Effect of 0.

  • The picture

  • video

1. Implementation principle

1.1 RGB to grayscale value

First, we know that in OpenGL colors have 4 channels RGBA for general images. That leaves three more channels to deal with, RGB.

And our character drawing uses 1 character to represent 1 block color, that is, we need to RGB three channels for some processing (3 values), so that they become 1 value, we can match a certain 1 character.

One of the processing mentioned above is conversion of RGB values to grayscale values.

This part we can convert with shader from GPUImageGrayscaleFilter:

precision highp float;
varying vec2 textureCoordinate;
uniform sampler2D inputImageTexture;
const highp vec3 W = vec3(0.2125.0.7154.0.0721);
void main()
{
   lowp vec4 textureColor = texture2D(inputImageTexture, textureCoordinate);
   float luminance = dot(textureColor.rgb, W);
   gl_FragColor = vec4(vec3(luminance), textureColor.a);
}
Copy the code

With the above processing, we convert RGB values to grayscale values, or luminance in the shader.

At this point, RGB values are equal to luminance. (Use any value in RGB.)

1.2 Conversion of gray value to character

The gray value range is now, we quantified it into 15 levels.

Grade segmentation can be customized according to requirements.

From low to high:

The text in the picture can be selected by itself, so that the ratio of black and white in the picture is close to the corresponding level.

1.3 Size conversion of grayscale diagram

If we use a pixel to represent a character, it is impossible to see the shape of the character, so it is generally used to display multiple pixels to represent a character. So if you use dots to represent a grayscale without converting it to characters, you get the Mosaic below.

In the example, I useTo represent a gray value.It’s a little harder to draw, so let me usePixel points to explain.

If you useWe need to use the gray values of 25 points to calculate an average, and then use this gray value to fill the 25 pixel grid. So if I reduce the length and width of the image by 5 times and draw it in grayscale, then the GPU will do the calculation for us, and now I only need 1 grid.

Let’s do one more concrete example. Let’s say I have a sheetBy grayscale shader and drawing on a 0.1x frame buffer, one can be obtainedGrayscale map query texture.

That is, for the original coordinatesFor these pixels, you only need to query the texture using a grayscale mapThis is the gray value of a pixel point.

1.4 Grayscale value mapping character texture

varying highp vec2 textureCoordinate; // Texture coordinates
varying highp vec2 textureCoordinate2; // Texture coordinates (not used)

uniform sampler2D inputImageTexture; // Character texture
uniform sampler2D inputImageTexture2; // Grayscale reference texture

uniform highp vec2 textureSize; // Original size

void main()
{
  // Pixel coordinates
  highp vec2 coordinate = textureCoordinate * textureSize;

  // The demo is written dead, can be adjusted according to the actual situation
  highp float width = 10.0;
  // Calculate the midpoint of the width*width region
  highp vec2 midCoor = min((floor(coordinate / width) * width + width * 0.5) / textureSize.1.0);
  // Get the gray value of the midpoint
  lowp vec4 color = texture2D(inputImageTexture2, midCoor);
  // A character's normalized texture coordinates
  coordinate = mod(coordinate, width) / width;
  // In order to save performance, we put 15 characters on a texture, which needs to be x offset according to the gray value
  coordinate.x = (floor(color.r * 14.0) + coordinate.x) / 15.0;

  gl_FragColor = texture2D(inputImageTexture, coordinate);
}
Copy the code
  1. We calculate the corresponding pixel coordinates according to texture coordinates and texture size.

  2. To calculateAnd get the gray value of the center point.

    Since the gray texture of small size is obtained separately, it cannot guarantee to meet the ideal effect mentioned above, so the gray value of the center point is adopted.

  3. We useThe pixel point represents a character, and the normalized texture coordinates of the corresponding character are calculated.

  4. In order to save performance, 15 character textures are horizontally merged into one texture, so they should be offset according to gray value, and the corresponding character texture should be selected according to gray value.

2. Demo

The Demo code.

If you found this article helpful, give me a thumbs up