1
头图

background

This article is included in the "Data Visualization and Graphics" column

Previously introduced texture-related theories and simple use of If you need it, you can refer to above for multi-texture practice based on the above (more to help small partners in the group get out of the hole in advance!!!!)

Outline of this article

  1. Multi-texture rendering realization ideas
  2. Multi-texture rendering coding (several scenarios)

1. Ideas for implementing multi-texture rendering

Multi-texture rendering refers more to the relationship of gl_FragColor taking mixed texture texture2D * texture2D. The original intention of this article is to help the friends in the group's advanced bumpy road~ The need for multiple vertex (texture) rendering and overlapping coordinates will be mentioned.
  1. Define vertexArray (2point in the example in this article)
  2. Define textureArray
  3. Create a buffer (note the common buffer of multiple render nodes here)
  4. Register the shader step by step. Bind data and render.

Multi-texture rendering coding (several scenarios)

The first gl_FragColor takes a mixed texture texture2D * texture2D
image.png
The shader part is not difficult...
// vertex
attribute vec2 a_position; //坐标
attribute vec2 a_texCoord; //纹理

uniform vec2 u_resolution;

varying vec2 v_texCoord;

void main() {
   //  坐标转换像素->1.0,0.0...
   vec2 zeroToOne = a_position / u_resolution;

   vec2 zeroToTwo = zeroToOne * 2.0;

   vec2 clipSpace = zeroToTwo - 1.0;
    
   gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);
   // 纹理 给fragment使用 
   v_texCoord = a_texCoord;
}

// fragment
uniform sampler2D u_image0;  // 纹理
uniform sampler2D u_image1;

// 来自vertex shader
varying vec2 v_texCoord;

void main() {
   vec4 color0 = texture2D(u_image0, v_texCoord);
   vec4 color1 = texture2D(u_image1, v_texCoord);
   gl_FragColor = color0 * color1;  // 可以理解为混合纹理
}
JavaScript is also very simple to create node coordinates/texture/shader&data connection/rendering!
// 此处示意代码 完整代码上传github
 var texcoordBuffer = gl.createBuffer();  //纹理
 gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer);
 // bufferData 
 ...
 for(...images length){
     // 循环遍历
     gl.bindTexture(gl.TEXTURE_2D, texture);
 }

 var positionBuffer = gl.createBuffer(); //节点坐标  此处绘制TRIANGLES 三角形
 gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
 // bufferData
 
 // 缓冲区分配给attribute变量
 gl.vertexAttribPointer(
  texcoordLocation, size, type, normalize, stride, offset);
 gl.vertexAttribPointer(
  positionLocation, size, type, normalize, stride, offset);
 // 开启attribute变量
 gl.enableVertexAttribArray(positionLocation);
 gl.enableVertexAttribArray(texcoordLocation);
 
 // 纹理!!!!激活纹理单元
 gl.activeTexture(gl.TEXTURE0);
 //给定的纹理绑定到目标(vertex)
 gl.bindTexture(gl.TEXTURE_2D, textures[0]);
 
 // 绘制!!! 大功告成
 gl.drawArrays(gl.TRIANGLES, 0, 6);

The second type of multiple node textures (in fact, the coordinates overlap the latter to cover the former...)
image.png
There is no difficulty in the shader part (no changes)...
// vertex
attribute vec2 a_position;
attribute vec2 a_texCoord;
attribute lowp float textureIndex;

uniform vec2 u_resolution;
varying vec2 v_texCoord;
varying lowp float indexPicker;

void main() {
   vec2 zeroToOne = a_position / u_resolution;
   vec2 zeroToTwo = zeroToOne * 2.0;
   vec2 clipSpace = zeroToTwo - 1.0;
   
   gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);
   v_texCoord = a_texCoord;
   indexPicker = textureIndex; // 控制fragment shader选哪一个纹理
}

// fragment
precision mediump float;

// 纹理
uniform sampler2D u_image[2];

// the texCoords passed in from the vertex shader.
varying vec2 v_texCoord;
varying lowp float indexPicker;

void main() {
   if (indexPicker < 0.5) {
       gl_FragColor = texture2D(u_image[0], v_texCoord);
   } else {
       gl_FragColor = texture2D(u_image[1], v_texCoord);
   }
}

JavaScript is also very simple to create node coordinates/texture/shader&data connection/rendering!
// 此处示意代码 完整代码上传github
 var texcoordBuffer = gl.createBuffer();  //纹理
 gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer);
 // bufferData 
 ...
 for(...images length){
     // 循环遍历
     gl.bindTexture(gl.TEXTURE_2D, texture);
 }
 
 
 // 注意vertex!!!!! 此处与上文不同 
 var positionBuffer = gl.createBuffer(); //节点坐标  此处绘制TRIANGLES 三角形
 gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
 // bufferData
 
 // 缓冲区分配给attribute变量
 gl.vertexAttribPointer(
  texcoordLocation, size, type, normalize, stride, offset);
 gl.vertexAttribPointer(
  positionLocation, size, type, normalize, stride, offset);
 // 开启attribute变量
 gl.enableVertexAttribArray(positionLocation);
 gl.enableVertexAttribArray(texcoordLocation);
 
 // 纹理!!!!激活纹理单元
 gl.activeTexture(gl.TEXTURE0);
 //给定的纹理绑定到目标(vertex)
 gl.bindTexture(gl.TEXTURE_2D, textures[0]);
 
 // 绘制!!! 大功告成
 gl.drawArrays(gl.TRIANGLES, 0, vertextArray.length/2); // 绘制多个(三角形组合)正方形

!!!! Pay attention to the comments in the code (solve your doubts)

image.png

1. webgl-utils.js webgl related function packaging tool library

Complete code example [please click the git repository to view the code example]
texture.html

texture1.html

What you may need to know about 2D rendering

  1. Texture cache
  2. Texture compression
  3. 2D/2D texture optimization
  4. Rendering optimization...

finally

Finally, I strongly hope that everyone learns relevant theoretical knowledge; theory may be used in very few places in daily life, but it can determine how far you go. (Some people ask what to do, practice hard) I feel like I'm good at writing speed, hahaha... I will continue to update recently (because I am developing my own rendering engine. Alas, it's hard to say... Sorry)

wlove
6.9k 声望1.8k 粉丝

wx:wywin2023