1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > 【愚公系列】09月 微信小程序-WebGL立体图形的绘制

【愚公系列】09月 微信小程序-WebGL立体图形的绘制

时间:2022-03-08 13:16:15

相关推荐

【愚公系列】09月 微信小程序-WebGL立体图形的绘制

文章目录

前言一、webgl的使用1.立体图形的绘制二、相关包源码三、总结

前言

WebGL(全写Web Graphics Library)是一种3D绘图协议,这种绘图技术标准允许把JavaScript和OpenGL ES 2.0结合在一起,通过增加OpenGL ES 2.0的一个JavaScript绑定,WebGL可以为HTML5 Canvas提供硬件3D加速渲染,这样Web开发人员就可以借助系统显卡来在浏览器里更流畅地展示3D场景和模型了,还能创建复杂的导航和数据视觉化。显然,WebGL技术标准免去了开发网页专用渲染插件的麻烦,可被用于创建具有复杂3D结构的网站页面,甚至可以用来设计3D网页游戏等等。–百度百科

在现实中webgl的用途很多,比如医院运维网站,地铁运维网站,海绵城市,可以以三维网页形式展示出现实状态。

WebGL相关文档:/doc/wiki/project/webgl/webgL-fundamentals.html

一、webgl的使用

安装第三方包:npm i --save threejs-miniprogram

1.立体图形的绘制

import drawCube from './drawCube'Page({/*** 页面的初始数据*/data: {},/*** 生命周期函数--监听页面加载*/onLoad: function (options) {},/*** 生命周期函数--监听页面初次渲染完成*/onReady: function () {wx.createSelectorQuery().select('#myCanvas1').node().exec((res) => {const canvas = res[0].nodeconst gl = canvas.getContext('webgl')if (!gl) {console.log('webgl未受支持');return}// 检查所有支持的扩展var available_extensions = gl.getSupportedExtensions();console.log(available_extensions);// 清除画布// 使用完全不透明的黑色清除所有图像,我们将清除色设为黑色,此时并没有开始清除gl.clearColor(0.0, 0.0, 0.0, 1.0);// 用上面指定的颜色清除缓冲区gl.clear(gl.COLOR_BUFFER_BIT);// 画的是一个正方形drawCube(gl, canvas)})

import {mat4} from '../../lib/gl-matrix'var cubeRotation = 0.0;//// Start here//function drawCube(gl,canvas) {// Vertex shader programconst vsSource = `attribute vec4 aVertexPosition;attribute vec4 aVertexColor;uniform mat4 uModelViewMatrix;uniform mat4 uProjectionMatrix;varying lowp vec4 vColor;void main(void) {gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition;vColor = aVertexColor;}`;// Fragment shader programconst fsSource = `varying lowp vec4 vColor;void main(void) {gl_FragColor = vColor;}`;// Initialize a shader program; this is where all the lighting// for the vertices and so forth is established.const shaderProgram = initShaderProgram(gl, vsSource, fsSource);// Collect all the info needed to use the shader program.// Look up which attributes our shader program is using// for aVertexPosition, aVevrtexColor and also// look up uniform locations.const programInfo = {program: shaderProgram,attribLocations: {vertexPosition: gl.getAttribLocation(shaderProgram, 'aVertexPosition'),vertexColor: gl.getAttribLocation(shaderProgram, 'aVertexColor'),},uniformLocations: {projectionMatrix: gl.getUniformLocation(shaderProgram, 'uProjectionMatrix'),modelViewMatrix: gl.getUniformLocation(shaderProgram, 'uModelViewMatrix'),},};// Here's where we call the routine that builds all the// objects we'll be drawing.const buffers = initBuffers(gl);var then = 0;// Draw the scene repeatedlyfunction render(now) {now *= 0.001; // convert to secondsconst deltaTime = now - then;then = now;drawScene(gl, programInfo, buffers, deltaTime);canvas.requestAnimationFrame(render);}canvas.requestAnimationFrame(render);}//// initBuffers//// Initialize the buffers we'll need. For this demo, we just// have one object -- a simple three-dimensional cube.//function initBuffers(gl) {// Create a buffer for the cube's vertex positions.const positionBuffer = gl.createBuffer();// Select the positionBuffer as the one to apply buffer// operations to from here out.gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);// Now create an array of positions for the cube.const positions = [// 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 face1.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,];// Now pass the list of positions into WebGL to build the// shape. We do this by creating a Float32Array from the// JavaScript array, then use it to fill the current buffer.gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);// Now set up the colors for the faces. We'll use solid colors// for each face.const faceColors = [[1.0, 1.0, 1.0, 1.0], // Front face: white[1.0, 0.0, 0.0, 1.0], // Back face: red[0.0, 1.0, 0.0, 1.0], // Top face: green[0.0, 0.0, 1.0, 1.0], // Bottom face: blue[1.0, 1.0, 0.0, 1.0], // Right face: yellow[1.0, 0.0, 1.0, 1.0], // Left face: purple];// Convert the array of colors into a table for all the vertices.var colors = [];for (var j = 0; j < faceColors.length; ++j) {const c = faceColors[j];// Repeat each color four times for the four vertices of the facecolors = colors.concat(c, c, c, c);// colors = colors.concat(c);// colors = colors.concat(c);// colors = colors.concat(c);// colors = colors.concat(c);}const colorBuffer = gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);// Build the element array buffer; this specifies the indices// into the vertex arrays for each face's vertices.const indexBuffer = gl.createBuffer();gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);// This array defines each face as two triangles, using the// indices into the vertex array to specify each triangle's// position.const indices = [0, 1, 2,0, 2, 3, // front4, 5, 6,4, 6, 7, // back8, 9, 10,8, 10, 11, // top12, 13, 14,12, 14, 15, // bottom16, 17, 18,16, 18, 19, // right20, 21, 22,20, 22, 23, // left];// Now send the element array to GLgl.bufferData(gl.ELEMENT_ARRAY_BUFFER,new Uint16Array(indices), gl.STATIC_DRAW);return {position: positionBuffer,color: colorBuffer,indices: indexBuffer,};}//// Draw the scene.//function drawScene(gl, programInfo, buffers, deltaTime) {gl.clearColor(0.0, 0.0, 0.0, 1.0); // Clear to black, fully opaquegl.clearDepth(1.0); // Clear everythinggl.enable(gl.DEPTH_TEST); // Enable depth testinggl.depthFunc(gl.LEQUAL); // Near things obscure far things// Clear the canvas before we start drawing on it.gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);// Create a perspective matrix, a special matrix that is// used to simulate the distortion of perspective in a camera.// Our field of view is 45 degrees, with a width/height// ratio that matches the display size of the canvas// and we only want to see objects between 0.1 units// and 100 units away from the camera.const fieldOfView = 45 * Math.PI / 180; // in radiansconst aspect = gl.canvas.clientWidth / gl.canvas.clientHeight;const zNear = 0.1;const zFar = 100.0;const projectionMatrix = mat4.create();// note: glmatrix.js always has the first argument// as the destination to receive the result.mat4.perspective(projectionMatrix,fieldOfView,aspect,zNear,zFar);// Set the drawing position to the "identity" point, which is// the center of the scene.const modelViewMatrix = mat4.create();// Now move the drawing position a bit to where we want to// start drawing the square.mat4.translate(modelViewMatrix,// destination matrixmodelViewMatrix,// matrix to translate[-0.0, 0.0, -6.0]); // amount to translatemat4.rotate(modelViewMatrix, // destination matrixmodelViewMatrix, // matrix to rotatecubeRotation,// amount to rotate in radians[0, 0, 1]); // axis to rotate around (Z)mat4.rotate(modelViewMatrix, // destination matrixmodelViewMatrix, // matrix to rotatecubeRotation * .7,// amount to rotate in radians[0, 1, 0]); // axis to rotate around (Y)// Tell WebGL how to pull out the positions from the position// buffer into the vertexPosition attribute{const numComponents = 3;const type = gl.FLOAT;const normalize = false;const stride = 0;const offset = 0;gl.bindBuffer(gl.ARRAY_BUFFER, buffers.position);gl.vertexAttribPointer(programInfo.attribLocations.vertexPosition,numComponents,type,normalize,stride,offset);gl.enableVertexAttribArray(programInfo.attribLocations.vertexPosition);}// Tell WebGL how to pull out the colors from the color buffer// into the vertexColor attribute.{const numComponents = 4;const type = gl.FLOAT;const normalize = false;const stride = 0;const offset = 0;gl.bindBuffer(gl.ARRAY_BUFFER, buffers.color);gl.vertexAttribPointer(programInfo.attribLocations.vertexColor,numComponents,type,normalize,stride,offset);gl.enableVertexAttribArray(programInfo.attribLocations.vertexColor);}// gl.ARRAY_BUFFER: 包含顶点属性的Buffer,如顶点坐标,纹理坐标数据或顶点颜色数据。// gl.ELEMENT_ARRAY_BUFFER: 用于元素索引的Buffer。// Tell WebGL which indices to use to index the verticesgl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffers.indices);// Tell WebGL to use our program when drawinggl.useProgram(programInfo.program);// Set the shader uniformsgl.uniformMatrix4fv(programInfo.uniformLocations.projectionMatrix,false,projectionMatrix);gl.uniformMatrix4fv(programInfo.uniformLocations.modelViewMatrix,false,modelViewMatrix);{// 6个面,12个三角形,每个三角3个顶点,共36个顶点const vertexCount = 36;const type = gl.UNSIGNED_SHORT;const offset = 0;gl.drawElements(gl.TRIANGLES, vertexCount, type, offset);}// Update the rotation for the next drawcubeRotation += deltaTime;}//// Initialize a shader program, so WebGL knows how to draw our data//function initShaderProgram(gl, vsSource, fsSource) {const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);// Create the shader programconst shaderProgram = gl.createProgram();gl.attachShader(shaderProgram, vertexShader);gl.attachShader(shaderProgram, fragmentShader);gl.linkProgram(shaderProgram);// If creating the shader program failed, alertif (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {alert('Unable to initialize the shader program: ' + gl.getProgramInfoLog(shaderProgram));return null;}return shaderProgram;}//// creates a shader of the given type, uploads the source and// compiles it.//function loadShader(gl, type, source) {const shader = gl.createShader(type);// Send the source to the shader objectgl.shaderSource(shader, source);// Compile the shader pileShader(shader);// See if it compiled successfullyif (!gl.getShaderParameter(shader, PILE_STATUS)) {alert('An error occurred compiling the shaders: ' + gl.getShaderInfoLog(shader));gl.deleteShader(shader);return null;}return shader;}export default drawCube

实际效果

二、相关包源码

gl-matrix相关包源码链接如下:

/download/aa2528877987/86513333

三、总结

画一个图形主要经历如下四个步骤:

1.编写GLSL着色器代码,一个是顶点着色器,一个是片断着色器。2.加载着色器,组成着色器程序。3.创建缓冲区对象,填充缓冲区。4.创建摄像机透视距阵,把元件放到适当的位置。5.给着色器中的变量绑定值。6.调用gl.drawArrays,从向量数组中开始绘制。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。