We are still exploring how to use html5 + webGL to implement 3D street view. The topic of this article is how to add multiple textures to a 3D model and why there are multiple textures: because it is a network application, you must consider the network bandwidth issue, if a texture image is directly transmitted from the server to the client without processing, the speed will be very slow. To solve this problem, we must cut a complete texture image into multiple images, this leads to today's topic: How to splice multiple textures after cutting on a 3D model? We know that WebGL is a 3D drawing standard that allows JavaScript and OpenGL
ES 2.0 is combined. By adding a JavaScript binding of OpenGL ES 2.0, WebGL can provide hardware 3D acceleration rendering for HTML5 Canvas, in this way, Web developers can use the system graphics card to display 3D scenes and models more smoothly in the browser;
For simplicity, we use a cube as our 3D model and place different textures on the six sides of the cube.
Principle:
1. generate an array of vertex coordinates of the cube. Code:
cubeVertexPositionBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); vertices = [ // Front face -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, // Back face -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, // Top face -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, // Bottom face -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, // Right face 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, // Left face -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, ]; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW); cubeVertexPositionBuffer.itemSize = 3; cubeVertexPositionBuffer.numItems = 24;
2. Generate the coordinate array of the texture vertex of the cube. Code:
cubeVertexTextureCoordBuffer = gl.createBuffer(); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexTextureCoordBuffer); var textureCoords = [ // Front face 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, // Back face 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, // Top face 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, // Bottom face 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, // Right face 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, // Left face 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, ]; gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoords), gl.STATIC_DRAW); cubeVertexTextureCoordBuffer.itemSize = 2; cubeVertexTextureCoordBuffer.numItems = 24;
3. Create an index on the six sides of the cube to prepare for subsequent rendering:
cubeVertexTextureIndex0 = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexTextureIndex0); var Indices0 = [0, 1, 2, 0, 2, 3]; gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(Indices0), gl.STATIC_DRAW); cubeVertexTextureIndex0.itemSize = 1; cubeVertexTextureIndex0.numItems = 6; cubeVertexTextureIndex1 = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexTextureIndex1); var Indices1 = [4, 5, 6, 4, 6, 7]; gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(Indices1), gl.STATIC_DRAW); cubeVertexTextureIndex1.itemSize = 1; cubeVertexTextureIndex1.numItems = 6; cubeVertexTextureIndex2 = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexTextureIndex2); var Indices2 = [8, 9, 10, 8, 10, 11]; gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(Indices2), gl.STATIC_DRAW); cubeVertexTextureIndex2.itemSize = 1; cubeVertexTextureIndex2.numItems = 6; cubeVertexTextureIndex3 = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexTextureIndex3); var Indices3 = [12, 13, 14, 12, 14, 15]; gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(Indices3), gl.STATIC_DRAW); cubeVertexTextureIndex3.itemSize = 1; cubeVertexTextureIndex3.numItems = 6; cubeVertexTextureIndex4 = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexTextureIndex4); var Indices4 = [16, 17, 18, 16, 18, 19]; gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(Indices4), gl.STATIC_DRAW); cubeVertexTextureIndex4.itemSize = 1; cubeVertexTextureIndex4.numItems = 6; cubeVertexTextureIndex5 = gl.createBuffer(); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexTextureIndex5); var Indices5 = [20, 21, 22, 20, 22, 23]; gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(Indices5), gl.STATIC_DRAW); cubeVertexTextureIndex5.itemSize = 1; cubeVertexTextureIndex5.numItems = 6;
4. render the six faces of the cube and bind the corresponding texture image. Code:
gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer); gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, cubeVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0); gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexTextureCoordBuffer); gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, cubeVertexTextureCoordBuffer.itemSize, gl.FLOAT, false, 0, 0); setMatrixUniforms(); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, crateTextures[0+filter]); gl.uniform1i(shaderProgram.samplerUniform, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexTextureIndex0); gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, crateTextures[0+filter]); gl.uniform1i(shaderProgram.samplerUniform, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexTextureIndex1); gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, crateTextures[3+filter]); gl.uniform1i(shaderProgram.samplerUniform, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexTextureIndex2); // gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, crateTextures[3+filter]); gl.uniform1i(shaderProgram.samplerUniform, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexTextureIndex3); gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, crateTextures[6+filter]); gl.uniform1i(shaderProgram.samplerUniform, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexTextureIndex4); gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0); gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, crateTextures[6+filter]); gl.uniform1i(shaderProgram.samplerUniform, 0); gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexTextureIndex5); gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0);
:
The above is the entire process. Some of the Code borrowed the HiWebGL tutorial. Thank you!