The purpose of this case is to understand how to implement split screen (2/3/4/6/9) filters with GLSL
The renderings of the case are shown below
The preparatory work
Custom shaders
Complete the shader code without split-screen filters
- Vertex shader
attribute vec4 Position;
attribute vec2 TextureCoords;
varying vec2 TextureCoordsVarying;
void main(){
gl_Position = Position;
TextureCoordsVarying = TextureCoords;
}
Copy the code
- Chip shader
precision highp float; uniform sampler2D Texture; varying vec2 TextureCoordsVarying; void main(){ vec4 mask = texture2D(Texture, TextureCoordsVarying); Gl_FragColor = vec4 (mask. RGB, 1.0); }Copy the code
View Controller class
Before the split-screen filter is implemented, an original image, namely an image with no filter effect, should be presented first. The general process is as follows
It is mainly divided into three parts
- SetupFilterBar function: bottom filter scroll bar
- FilterInit function: Filter handles initialization
- The startFilterAnimation function has two entrances to the filter animation:
- ViewDidLoad –> filterInit –> Shader loads & compilers & Program using –> call startFilterAnimation
- When toggling the bottom FilterBar –> select a split-screen effect –> corresponding set of shader files –> Shader load & compile & Program use –> call startFilterAnimation
SetupFilterBar function
It is mainly to add the custom filter scroll bar and use collectionView to realize the custom scroll view at the bottom. This part is not explained. If you have any questions, you can refer to the complete demo at the end of this article
FilterInit function
It is mainly to achieve the image display without split-screen filter effect, and the implementation process is as follows
According to the diagram, it is divided into the following parts
-
SetupContext function: Sets the context
-
SetupLayer function: creates layer & bind render and frame cache
-
SetupVertexData function: sets vertex data & vertex cache
-
SetupTexture function: Unzip the image & load the texture
-
Set the viewport
-
The setupNormalShaderProgram function: Sets the default shader, which has no split-screen effect
The above parts of the code are covered in the previous OpenGL ES case, which is not explained here. For details, please refer to the complete code at the end of the article
Split screen filter implementation
Split-screen filter is mainly realized by split-screen algorithm, which is mainly completed in the main function of the chip shader. Therefore, the following changes are mainly needed to switch different split-screen effects
-
Create a new set of shader files, without any changes to the vertex shader file, and add the corresponding split-screen algorithm code to the main function of the slice shader file
-
Add the data source of the FilterBar to the view controller class, and add the click event of its item. Add a function to load the corresponding shader file, similar to the setupNormalShaderProgram function, just change the name of the shader file
The following describes the realization of the split-screen algorithm for different split-screen effects
Binary screen
In this case, the binary screen displays the middle half of the image up and down respectively. The algorithm is shown in the figure below
When the binary screen filter is implemented, the x value of the image texture coordinate does not change at all, mainly the Y value changes
- When y is in the range [0, 0.5], the screen’s (0, 0) coordinates need the corresponding image’s (0, 0.25), so y = y+0.25
- When y is in the range of [0.5, 1], the screen’s (0,0.5) coordinates need the corresponding image’s (0,0.25), so y = y-0.25
The split-screen algorithm code of main function in the fragment shader is as follows
void main(){ vec2 uv = TextureCoordsVarying.xy; float y; If (uv) > = 0.0 && y uv) < = 0.5) {y y = uv. Y + 0.25; }else{y = uv. y-0.25; } gl_FragColor = texture2D(Texture, vec2(uv.x, y)); }Copy the code
Three split screen
The screen is divided into three parts, showing one third of the pictures respectively. The realization principle is as follows
When the three-split screen filter is implemented, the x value of the image texture coordinate does not change at all, but the y value changes mainly
- When y is in the [0, 1/3] range, the screen’s (0, 0) coordinates need to correspond to the image’s (0, 1/3), so y = y+1/3
- When y is in the [1/3, 2/3] range, the screen’s (0, 1/3) coordinates need the corresponding image’s (0, 1/3), so y stays the same
- When y is in the [2/3, 1] range, the screen’s (0, 2/3) coordinates need to correspond to the image’s (0, 1/3), so y = y-1/3
The split-screen algorithm code of main function in the fragment shader is as follows
void main(){ vec2 uv = TextureCoordsVarying.xy; If (uv.y < 1.0/3.0) {uv.y = uv.y + 1.0/3.0; } else if (uv) y > 2.0/3.0) {uv. Y = uv. Y - 1.0/3.0. } gl_FragColor = texture2D(Texture, uv); }Copy the code
Four split screen
The four-split screen display is divided into four equal parts of the screen to display the reduced texture picture respectively. Its implementation principle is as follows
The texture image can be mapped to the screen either as a consistent coordinate or as a zoomed out coordinate, as shown in the image above.
When the quad-screen is realized, the texture coordinates x and Y need to be changed, and the screen coordinates need to be mapped to texture coordinates one by one. For example, when the value of (x, y) (0.5, 0.5) needs to be mapped to texture coordinates (1, 1), x and y need to be multiplied by 2, that is, 0.5 * 2 = 1. The change rule is as follows:
- When x is in the range [0, 0.5], x = x*2
- When x is in the range of [0.5, 1], x = (x-0.5)*2
- When y is in the range [0, 0.5], y = y*2
- When y is in the range of [0.5, 1], y = (y-0.5)*2
The split-screen algorithm code of main function in the fragment shader is as follows
void main(){ vec2 uv = TextureCoordsVarying.xy; If (uv.x <= 0.5) {uv.x = uv.x * 2.0; }else{uv.x = (uv.x -0.5) * 2.0; } if (uv.y <= 0.5) {uv.y = uv.y * 2.0; }else{uv.y = (uV. y-0.5) * 2.0; } gl_FragColor = texture2D(Texture, uv); }Copy the code
Six split screen
Six – split screen is the evolution of two – split screen, its implementation principle is as follows
When the sextet screen is realized, texture coordinates X and Y need to change, and the change rules are as follows:
- When x is in the range [0, 1/3], x is equal to x plus 1/3
- When x is in the range 1/3, 2/3, x doesn’t change
- When x is in the [2/3, 1] range, x is equal to x minus 1/3
- When y is in the range [0, 0.5], y = y+0.25
- When y is in the range of [0.5, 1], y = y-0.24
The split-screen algorithm code of main function in the fragment shader is as follows
void main(){ vec2 uv = TextureCoordsVarying.xy; If (uv.x <= 1.0/3.0) {uv.x = uv.x + 1.0/3.0; } else if (uv) x > = 2.0/3.0) {uv. X = uv. X - 1.0/3.0. } if (uv.y <= 0.5) {uv.y = uv.y + 0.25; }else{uv.y = uv.y -0.25; } gl_FragColor = texture2D(Texture, uv); }Copy the code
Nine points screen
Nine split screen is the evolution of four split screen, its implementation principle is as follows
When nine-split screen is realized, texture coordinates X and Y need to be changed, and their change rules are as follows:
- When x is in the range [0, 1/3], x is equal to x times 3
- When x is in the range 1/3, 2/3, x is equal to x minus 1/3 times 3
- When x is in the [2/3, 1] range, x is equal to x minus 2/3 times 3
- When y is in the range 0, 1/3, y is equal to y times 3
- When y is in the 1/3, 2/3 range, y is equal to y minus 1/3 times 3
- When y is in the [2/3, 1] range, y is equal to y minus 2/3 times 3
The split-screen algorithm code of main function in the fragment shader is as follows
void main(){ vec2 uv = TextureCoordsVarying.xy; If (uv.x <= 1.0/3.0) {uv.x = uv.x * 3.0; } else if (uv) x > = 2.0/3.0) {uv. X = (uv) x - 2.0/3.0) * 3.0; }else{uv.x = (uv.x - 1.0/3.0)*3.0; } if (uv.y <= 1.0/3.0) {uv.y = uv.y * 3.0; } else if (uv) y > = 2.0/3.0) {uv. Y = (uv) y - 2.0/3.0) * 3.0; }else{uv.y = (uv.y - 1.0/3.0)*3.0; } gl_FragColor = texture2D(Texture, uv); }Copy the code
See Github-13_split Filter OC, 13 Split Filter _Swift for the complete code
Author: Style_ month links: www.jianshu.com/p/2121b93ee… The copyright of the book belongs to the author. Commercial reprint please contact the author for authorization, non-commercial reprint please indicate the source.