Define transition effect between pictures by texture map in Web GL

Time:2020-5-13

Define transition effect between pictures by texture map in Web GL


In this chapter, we have basically mastered how to draw graphics in 2D or 3D plane (of course, we can read on if we don’t know how to draw pictures in 2D or 3D plane). We can use web GL to draw the patterns we need in 2D plane, but in practice, we can’t draw all the graphics one by one. Texture mapping solves this problem You can use existing images to fill in the graphics in the web BGL.

  • Texture basis
  • Texture mapping of 2D graphics
  • Texture mapping of multi texture units
  • Transition effect between different textures

The original address is from my blog: https://github.com/forthealll…

The source address of this series is: https://github.com/fortealll

1、 Texture basis

Before we learn about texture mapping, let’s take a look at the preliminary knowledge. First, what is texture mapping or texture mapping?

    Attach an image to the surface of a geometry

This is the meaning of texture mapping. This image is called texture. This work is called texture mapping. Its essence is to extract the color in the image, and then assign the corresponding position to the geometric plane, so as to render the image on the surface of the geometry.

There is a mapping from texture (image) to geometry surface. In order to understand how this mapping occurs, we must understand texture coordinates and clipping coordinates.

clip coordinates

The coordinates of the clipping surface in the web GL are as follows:

Define transition effect between pictures by texture map in Web GL

From the sketch of the above clipping coordinate system, we can see that the central coordinate of the whole clipping plane in webgl is (0,0), for the 2D clipping plane, its horizontal direction is from (- 1,0) to (1,0), and its vertical direction is from (0, – 1) to (0,1)

That is to say, the value of any direction of its clipping coordinate is within the interval [- 1,1].

Note:The clipping plane determines how to map to the canvas, because the canvas is two-dimensional, so the clipping plane is also two-dimensional. The coordinates of Z-axis in webgl are not limited to (- 1,1), and can be any value

Texture coordinates

Texture coordinates are different from clipping coordinates, and their values are not from [- 1,1] but from [0,1]:

Define transition effect between pictures by texture map in Web GL

In the mapping process, we need to make the vertex coordinates in the clipping coordinates correspond to the texture coordinate system points one by one. That is, how to cut the texture in the texture coordinates and paste it into the geometry.

It should be noted that,The coordinates of the image itself and the texture are the same on the left and right, and the top and bottom are opposite. Therefore, there is a coordinate transformation of the up and down directions。 In the texture in webgl, by:

 gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,1)

To reverse the direction on the Y axis.

Disable security detection for Chrome

In the example of this article, you can directly open HTML through a file file. If there is an Ajax cross domain request in this HTML file, because of the security detection of the browser, you will be prompted with the following information error:

Cross origin requests are only supported for HTTP....

Of course, if you start a local server, there will be no impact. There is a lazy solution here, which is to disable the security detection method. Take MAC as an example, start chrome from the command line window, and the startup command is

open /Applications/Google\ Chrome.app --args --allow-file-access-from-files

In addition, you can also install HTTP server to quickly start a server locally

2、 Texture mapping of 2D graphics

Let’s use texture mapping of 2D geometry to introduce how to implement texture mapping in webgl.

(1) . first create a texture buffer

function createTexture (gl, filter, data, width, height) {
  let textureRef = gl.createTexture();
  gl.bindTexture(gl.TEXTURE_2D, textureRef);
  gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,1)
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filter);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, data);
  return textureRef;
}

The above is an example of creating a texture cache. Create a texture cache through GL. Createtexture(), and associate the system variable GL. Text? 2D. In addition, because in texture rendering, the y-axis direction is completely opposite to the picture, if you need to present the texture rendering results in a positive way, for example, reverse the y-axis direction, that is, gl.pixelstorei (GL. Unpack? Flip? Y? Webgl, 1).

In addition, we can use the gl.texparameteri function to specify how to render correctly when the image texture is larger than the rendering area or smaller than the rendering area.

Finally, it was adopted:

gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, data);

Extract the elements in data and save them to texture cache. Data can be image, video, or even the rendering result of another canvas.That is to say, the source of texture map of Web BGL can be not only a picture, but also a frame of video, or even another cavans

(2) . load image using texture buffer

 let image = new Image()
 image.src = './cubetexture.png'
 image.onload = function(){
    let textureRef  = createTexture(gl,gl.LINEAR,image1);
    gl.activeTexture(gl.TEXTURE0)
    gl.bindTexture(gl.TEXTURE_2D,textureRef)
    gl.uniform1i(u_Sampler, 0);  // texture unit 0
    gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
  }

The above code loads the image image image. When onload, the texture is created by the previously defined createtexture, and then the texture unit 0 is activated. Web BGL can support multiple texture units at the same time and render multiple textures to the same visual area at the same time. After activating the texture unit, we pass 0 to the sampler variable U ﹐ sampler in the shader

Finally, we accept the texture unit number and texture coordinates in the slice shader, and finally render the map to the render area:

uniform sampler2D u_ Sampler; // color picker variable
    Varying low vec2 V ﹣ texcoord; // texture coordinates
    void main() {
      gl_FragColor = texture2D(u_Sampler,v_TexCoord); 
    }

Finally, we get a correct image in the specified area. The rendering results are as follows:

Define transition effect between pictures by texture map in Web GL

3、 Texture mapping of multi texture units

As mentioned earlier, web BGL can support multiple texture units at the same time. Web BGL can process multiple textures at the same time. Texture units are designed for this purpose. In the above example, we only use one texture unit to render a texture to the render area. Next we try to use two texture units to render two images to the same area.

<div align=center>
<img width=256 height=256 /><br/>
Texture picture 1
</div>

<div align=center>
<img width=256 height=256 /><br/>
Texture picture 2
</div>

We use two texture units of webgl China, gl.texture0 and gl.texture1. The modified code is as follows.

The first is the logic of loading and rendering:

let textures = []
  image.onload = function(){
     let textureRef  = createTexture(gl,gl.LINEAR,image);
     gl.activeTexture(gl.TEXTURE0);
     gl.bindTexture(gl.TEXTURE_2D,textureRef)
     textures.push(textureRef)    
  }
  image.src = './cubetexture.png'
  let image1 = new Image();
  image1.onload = function(){
    let textureRef1  = createTexture(gl,gl.LINEAR,image1);
    gl.activeTexture(gl.TEXTURE1)
    gl.bindTexture(gl.TEXTURE_2D,textureRef1)
    textures.push(textureRef1)
  }
  image1.src = './img.png'
  
  //Activate texture cells and paint
  gl.uniform1i(u_Sampler, 0);  // texture unit 0
  gl.uniform1i(u_Sampler1, 1);  // texture unit 1
  gl.activeTexture(gl.TEXTURE0);
  gl.bindTexture(gl.TEXTURE_2D, textures[0]);
  gl.activeTexture(gl.TEXTURE1);
  gl.bindTexture(gl.TEXTURE_2D, textures[1]);

Finally, modify the chip shader:

uniform sampler2D u_Sampler;
uniform sampler2D u_Sampler1;
void main(){
  gl_FragColor = texture2D(u_Sampler,v_TexCoord) + texture2D(u_Sampler1,v_TexCoord); 
}

The final rendering result is:

<div align=center>
<img width=256 height=256 /><br/>
Finally, two texture units synthesize the rendering results
</div>

The completed code address is: https://github.com/forthealll…

4、 Transition effect between different textures

Through the use of multi texture units, we can achieve the transition effect between pictures. First, let’s see what is the transition effect.

As the name implies, transition effect is the animation effect between picture a and picture B, similar to the dynamic effect of fade in and fade out when we are doing ppt. In Web BGL, the texture of rendering is also a picture in nature, so we can control the rendering results of different textures in time order among different textures, and realize the effect of transition.

<img /><img /><img />

The animation shown above lists some transition effects.

Let’s take the two previous images as examples to study the transition effect between images or textures.

Look directly at the code in the chip metashader:

vec4 transition (vec2 uv) {
  float time = progress;
  float stime = sin(time * PI / 2.);
  float phase = time * PI * bounces;
  float y = (abs(cos(phase))) * (1.0 - stime);
  float d = uv.y - y;
  return mix(
    mix(
      getToColor(uv),
      shadow_colour,
      step(d, shadow_height) * (1. - mix(
        ((d / shadow_height) * shadow_colour.a) + (1.0 - shadow_colour.a),
        1.0,
        smoothstep(0.95, 1., progress) // fade-out the shadow at the end
      ))
    ),
    getFromColor(vec2(uv.x, uv.y + (1.0 - y))),
    step(d, 0.0)
  );
}

We see that this transition function is a transformation function, which determines how to switch textures over time for rendering. We specify two textures of different texture units through getfromcolor and gettocolor:

    vec4 getToColor(vec2  uv){
      return texture2D(u_Sampler,uv);
    }
    vec4 getFromColor(vec2 uv){
      return texture2D(u_Sampler1,uv);
    }

Finally, the color of the chip shader is the result of calling the transition function. When calling the transition, we passed in the texture coordinates.

void main() {
    gl_FragColor =  transition(v_TexCoord);
}

Finally, if you want the rendering result to move, you must write a timer to dynamically change the parameter progress in the transition, which is the change from 0 to 1.


setInterval(()=>{
    if(textures.length === 2){
      if(i >= 1){
        i = 0.01
      }
      gl.uniform1i(u_Sampler, 0);  // texture unit 0
      gl.uniform1i(u_Sampler1, 1);  // texture unit 1
      gl.activeTexture(gl.TEXTURE0);
      gl.bindTexture(gl.TEXTURE_2D, textures[0]);
      gl.activeTexture(gl.TEXTURE1);
      gl.bindTexture(gl.TEXTURE_2D, textures[1]);
      let progress = gl.getUniformLocation(shaderProgram,'progress')
      gl.uniform1f(progress,i)
      i += 0.05
      gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
    
    }
  },100)

The final rendering results we can see are as follows:

Define transition effect between pictures by texture map in Web GL

The completed code address is: https://github.com/fortheall

In addition, in https://github.com/gl-transit… There are a variety of transition effects included on. Transition can not only be applied to pictures, but also to different frames of video. In the next article, we will talk about how to realize rendering video in webgl and the inter frame animation of video.

Recommended Today

Analysis of super comprehensive MySQL statement locking (Part 1)

A series of articles: Analysis of super comprehensive MySQL statement locking (Part 1) Analysis of super comprehensive MySQL statement locking (Part 2) Analysis of super comprehensive MySQL statement locking (Part 2) Preparation in advance Build a system to store heroes of the Three KingdomsheroTable: CREATE TABLE hero ( number INT, name VARCHAR(100), country varchar(100), PRIMARY […]