#yyds干货盘点#愚公系列2022年12月 微信小程序-WebGL画渐变色正方形

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了#yyds干货盘点#愚公系列2022年12月 微信小程序-WebGL画渐变色正方形相关的知识,希望对你有一定的参考价值。

前言

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

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

一、webgl的使用

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

1.画正方形

import drawRectangle from ./draw-rectangle


Page(

  /**
   * 页面的初始数据
   */
  data: 

  ,

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) 

  ,

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () 
    wx.createSelectorQuery()
      .select(#myCanvas1)
      .node()
      .exec((res) => 
        const canvas = res[0].node
        const 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);

        // 画的是一个正方形
        drawRectangle(gl)
)
import 
  mat4
 from ../../lib/gl-matrix


function drawColorRectangle(gl) 

  // Vertex shader program

  const 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 program

  // 每个片段只是根据其相对于顶点的位置得到一个插值过的颜色,而不是一个指定的颜色值。
  // lowp表示低精度
  // lowp, mediump和highp
  const 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),
    ,
  ;

  // Heres where we call the routine that builds all the
  // objects well be drawing.
  const buffers = initBuffers(gl);

  // Draw the scene
  drawScene(gl, programInfo, buffers);


//
// initBuffers
//
// Initialize the buffers well need. For this demo, we just
// have one object -- a simple two-dimensional square.
//
function initBuffers(gl) 

  // Create a buffer for the squares 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 square.

  const positions = [
    1.0,  1.0,  0.0,
    -1.0, 1.0,  0.0,
    1.0,  -1.0, 0.0,
    -1.0, -1.0, 0.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 vertices

  // 此数组中包含四组四值向量,每一组向量代表一个顶点的颜色。
var colors = [
  1.0,  1.0,  1.0,  1.0,    // white
  1.0,  0.0,  0.0,  1.0,    // red
  0.0,  1.0,  0.0,  1.0,    // green
  0.0,  0.0,  1.0,  1.0,    // blue
];

  const colorBuffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);

  return 
    position: positionBuffer,
    color: colorBuffer,
  ;


//
// Draw the scene.
//
function drawScene(gl, programInfo, buffers) 
  gl.clearColor(0.0, 0.0, 0.0, 1.0);  // Clear to black, fully opaque
  gl.clearDepth(1.0);                 // Clear everything
  gl.enable(gl.DEPTH_TEST);           // Enable depth testing
  gl.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 radians
  const 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 matrix
                 modelViewMatrix,     // matrix to translate
                 [-0.0, 0.0, -6.0]);  // amount to translate

  // 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);
    

  // Tell WebGL to use our program when drawing

  gl.useProgram(programInfo.program);

  // Set the shader uniforms

  gl.uniformMatrix4fv(
      programInfo.uniformLocations.projectionMatrix,
      false,
      projectionMatrix);

  gl.uniformMatrix4fv(
      programInfo.uniformLocations.modelViewMatrix,
      false,
      modelViewMatrix);

  
    const offset = 0;
    const vertexCount = 4;
    gl.drawArrays(gl.TRIANGLE_STRIP, offset, vertexCount);
  


//
// 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 program

  const shaderProgram = gl.createProgram();
  gl.attachShader(shaderProgram, vertexShader);
  gl.attachShader(shaderProgram, fragmentShader);
  gl.linkProgram(shaderProgram);

  // If creating the shader program failed, alert

  if (!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 object

  gl.shaderSource(shader, source);

  // Compile the shader program

  gl.compileShader(shader);

  // See if it compiled successfully

  if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) 
    alert(An error occurred compiling the shaders:  + gl.getShaderInfoLog(shader));
    gl.deleteShader(shader);
    return null;
  

  return shader;


export default drawColorRectangle

实际效果

二、相关包源码

gl-matrix相关包源码链接如下: https://download.csdn.net/download/aa2528877987/86513333

三、总结

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

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

以上是关于#yyds干货盘点#愚公系列2022年12月 微信小程序-WebGL画渐变色正方形的主要内容,如果未能解决你的问题,请参考以下文章

#yyds干货盘点#愚公系列2022年12月 微信小程序-WebGL纹理材质的使用

#yyds干货盘点#愚公系列2022年12月 微信小程序-项目篇(公交查询)-06站点查询

#yyds干货盘点#愚公系列2022年12月 微信小程序-three.js绘制球体

#yyds干货盘点#愚公系列2022年12月 微信小程序-WebGL画渐变色正方形

#yyds干货盘点#愚公系列2022年12月 微信小程序-图片加载和全屏适配问题

#yyds干货盘点#愚公系列2022年12月 微信小程序-项目篇(公交查询)-01周边站点