欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 能源 > WebGL进阶(八)绘制正方体

WebGL进阶(八)绘制正方体

2025/2/5 12:06:15 来源:https://blog.csdn.net/Ian1025/article/details/143925721  浏览:    关键词:WebGL进阶(八)绘制正方体

基础知识:

绘制基础正方体:

 构成正方体的基础单元为三角形,顶点默认逆时针连接,此时的面为正面,顺时针点连接的面为背面。

Q:为什么使用三角形?

A:1、简单 2、生成模型拟合度高较光滑 3、图形处理的高效性

多边形和曲面可能具有复杂的几何形状,但是由于三角形具有逼近性,通过合理的三角剖分可以很好地逼近复杂形状。在每个小三角形内部可以进行插值计算,从而实现光滑的渐变效果,提高渲染质量。计算机图形学中很多技术和算法都是基于三角形的,如光栅化、像素填充、着色和纹理映射等。通过使用三角形作为基本元素,这些算法可以更加高效地运行,从而加速图像处理和渲染过程。(Imagination官方博客-CSDN博客)

背面剔除:

绘制简单纯色正方体:

绘制贴图正方体:

添加事件: 

效果:

源码:

绘制正方形(initBuffer)

            //    v6----- v5//   /|      /|//  v1------v0|//  | |     | |//  | |v7---|-|v4//  |/      |///  v2------v3
// 初始化缓冲区并设置矩阵
function initBuffer() {// 定义立方体的顶点数据,每个顶点包含4个分量(x, y, z, w),其中w通常用于齐次坐标let arr = [// 前面1, 1, 1, 1,  -1, 1, 1, 1,  -1, -1, 1, 1,  1, 1, 1, 1,  -1, -1, 1, 1,  1, -1, 1, 1,// 右面1, 1, -1, 1,  1, 1, 1, 1,  1, -1, 1, 1,  1, 1, -1, 1,  1, -1, 1, 1,  1, -1, -1, 1,// 后面-1, 1, -1, 1,  1, 1, -1, 1,  1, -1, -1, 1,  -1, 1, -1, 1,  1, -1, -1, 1,  -1, -1, -1, 1,// 左面-1, 1, 1, 1,  -1, 1, -1, 1,  -1, -1, -1, 1,  -1, 1, 1, 1,  -1, -1, -1, 1,  -1, -1, 1, 1,// 上面-1, 1, -1, 1,  -1, 1, 1, 1,  1, 1, 1, 1,  -1, 1, -1, 1,  1, 1, 1, 1,  1, 1, -1, 1,// 下面-1, -1, 1, 1,  -1, -1, -1, 1,  1, -1, -1, 1,  -1, -1, 1, 1,  1, -1, -1, 1,  1, -1, 1, 1]// 创建一个Float32Array类型的数组来存储顶点数据let pointPosition = new Float32Array(arr);// 获取顶点着色器中位置属性的位置let aPosition = webgl.getAttribLocation(webgl.program, "a_position");// 创建一个缓冲区对象let triangleBuffer = webgl.createBuffer();webgl.bindBuffer(webgl.ARRAY_BUFFER, triangleBuffer);webgl.bufferData(webgl.ARRAY_BUFFER, pointPosition, webgl.STATIC_DRAW);webgl.enableVertexAttribArray(aPosition);webgl.vertexAttribPointer(aPosition, 4, webgl.FLOAT, false, 4 * 4, 0);// 初始化投影矩阵let ProjMatrix = glMatrix.mat4.create();glMatrix.mat4.identity(ProjMatrix);// 设置透视投影矩阵,参数为:矩阵、角度(转换为弧度)、宽高比、近剪裁面、远剪裁面glMatrix.mat4.perspective(ProjMatrix, angle * Math.PI / 180, webglDiv.clientWidth / webglDiv.clientHeight, 1, 1000);// 获取uniform变量u_formMatrix的位置let uniformMatrix1 = webgl.getUniformLocation(webgl.program, "u_formMatrix");// 初始化模型矩阵let ModelMatrix = glMatrix.mat4.create();glMatrix.mat4.identity(ModelMatrix);// 沿x轴平移模型glMatrix.mat4.translate(ModelMatrix, ModelMatrix, [1, 0, 0]);// 初始化视图矩阵let ViewMatrix = glMatrix.mat4.create();glMatrix.mat4.identity(ViewMatrix);// 设置视图矩阵,参数为:矩阵、相机位置、目标位置、上方向glMatrix.mat4.lookAt(ViewMatrix, [5, 0, 0], [0, 0, 0], [0, 1, 0]);// 计算模型视图矩阵let mvMatrix = glMatrix.mat4.create();glMatrix.mat4.identity(mvMatrix);glMatrix.mat4.multiply(mvMatrix, ViewMatrix, ModelMatrix);// 计算模型视图投影矩阵let mvpMatrix = glMatrix.mat4.create();glMatrix.mat4.identity(mvpMatrix);glMatrix.mat4.multiply(mvpMatrix, ProjMatrix, mvMatrix);// 将模型视图投影矩阵传递给着色器webgl.uniformMatrix4fv(uniformMatrix1, false, mvpMatrix);// 设置清除颜色为黑色,并清除颜色缓冲区和深度缓冲区webgl.clearColor(0, 0, 0, 1);webgl.clear(webgl.COLOR_BUFFER_BIT | webgl.DEPTH_BUFFER_BIT);// 启用深度测试webgl.enable(webgl.DEPTH_TEST);// 绘制36个顶点的三角形webgl.drawArrays(webgl.TRIANGLES, 0, 36);
}

简单矩形


let aColor = webgl.getAttribLocation(webgl.program, "a_color");
webgl.enableVertexAttribArray(aColor);
webgl.vertexAttribPointer(aColor, 4, webgl.FLOAT, false, 8 * 4, 4 * 4);

vertexAttribPointer(index, size, type, normalized, stride, offset)

告诉显卡从当前绑定的缓冲区(bindBuffer() 指定的缓冲区)中读取顶点数据。WebGL API 的 WebGLRenderingContext.vertexAttribPointer() 方法绑定当前缓冲区范围到gl.ARRAY_BUFFER,成为当前顶点缓冲区对象的通用顶点属性并指定它的布局 (缓冲区对象中的偏移量)。

index

指定要修改的顶点属性的索引。

size

指定每个顶点属性的组成数量,必须是 1,2,3 或 4。

type

指定数组中每个元素的数据类型可能是:

  • gl.BYTE:  有符号的 8 位整数,范围 [-128, 127]

  • gl.SHORT: 有符号的 16 位整数,范围 [-32768, 32767]

  • gl.UNSIGNED_BYTE:无符号的 8 位整数,范围 [0, 255]

  • gl.UNSIGNED_SHORT: 无符号的 16 位整数,范围 [0, 65535]

  • gl.FLOAT:  32 位 IEEE 标准的浮点数

  • 使用 WebGL2 版本的还可以使用以下值:

    • gl.HALF_FLOAT: 16 位 IEEE 标准的浮点数

normalized

当转换为浮点数时是否应该将整数数值归一化到特定的范围。

  •  对于类型gl.BYTEgl.SHORT,如果是 true 则将值归一化为 [-1, 1]
  •  对于类型gl.UNSIGNED_BYTEgl.UNSIGNED_SHORT,如果是 true 则将值归一化为 [0, 1]
  • 对于类型gl.FLOATgl.HALF_FLOAT,此参数无效

stride

一个 GLsizei,以字节为单位指定连续顶点属性开始之间的偏移量 (即数组中一行长度)。不能大于 255。如果 stride 为 0,则假定该属性是紧密打包的,即不交错属性,每个属性在一个单独的块中,下一个顶点的属性紧跟当前顶点之后。

offset

GLintptr指定顶点属性数组中第一部分的字节偏移量。必须是类型的字节长度的倍数。

贴图矩形

  let attribOutUV = webgl.getAttribLocation(webgl.program, "a_outUV");webgl.enableVertexAttribArray(attribOutUV);webgl.vertexAttribPointer(attribOutUV, 2, webgl.FLOAT, false, 6 * 4, 4 * 4);//矩阵变换let ProjMatrix = glMatrix.mat4.create();glMatrix.mat4.identity(ProjMatrix);//角度小,看到的物体大,角度大,看到的物体小。glMatrix.mat4.perspective(ProjMatrix, angle * Math.PI / 180, webglDiv.clientWidth / webglDiv.clientHeight, 1, 1000)    //修改可视域范围let uniformMatrix1 = webgl.getUniformLocation(webgl.program, "u_formMatrix");let ModelMatrix = glMatrix.mat4.create();glMatrix.mat4.identity(ModelMatrix);glMatrix.mat4.translate(ModelMatrix, ModelMatrix, [0, 0, 0]);let ViewMatrix = glMatrix.mat4.create();glMatrix.mat4.identity(ViewMatrix);glMatrix.mat4.lookAt(ViewMatrix, [5, 5, 5], [0, 0, 0], [0, 1, 0]);let mvMatrix = glMatrix.mat4.create();glMatrix.mat4.identity(mvMatrix);glMatrix.mat4.multiply(mvMatrix, ViewMatrix, ModelMatrix);let mvpMatrix = glMatrix.mat4.create();glMatrix.mat4.identity(mvpMatrix);glMatrix.mat4.multiply(mvpMatrix, ProjMatrix, mvMatrix);webgl.uniformMatrix4fv(uniformMatrix1, false, mvpMatrix)//纹理绘制uniformTexture = webgl.getUniformLocation(webgl.program, "texture");texture = initTexture("container2_specular.png");

 

交互事件

// 初始化缓冲区并设置矩阵变换
function initBuffer() {// 顶点数据准备,包含顶点位置和UV坐标let arr = [// 前面1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 0, 1, -1, -1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 0, 0, 1, -1, 1, 1, 1, 0,// 右面1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, -1, 1, 1, 0, 0, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 0, 0, 1, -1, -1, 1, 1, 0,// 后面-1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 0, 1, 1, -1, -1, 1, 0, 0, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 0, 0, -1, -1, -1, 1, 1, 0,// 左面-1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 0, -1, -1, -1, 1, 0, 0, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 0, 0, -1, -1, 1, 1, 1, 0,// 上面-1, 1, -1, 1, 0, 1, -1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, -1, 1, -1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, -1, 1, 1, 1,// 下面-1, -1, 1, 1, 0, 1, -1, -1, -1, 1, 0, 0, 1, -1, -1, 1, 1, 0, -1, -1, 1, 1, 0, 1, 1, -1, -1, 1, 1, 0, 1, -1, 1, 1, 1, 1]// 创建一个Float32Array类型的数组来存储顶点数据let pointPosition = new Float32Array(arr);// 获取顶点着色器中位置属性的位置let aPosition = webgl.getAttribLocation(webgl.program, "a_position");// 创建一个缓冲区对象let triangleBuffer = webgl.createBuffer();webgl.bindBuffer(webgl.ARRAY_BUFFER, triangleBuffer);webgl.bufferData(webgl.ARRAY_BUFFER, pointPosition, webgl.STATIC_DRAW);webgl.enableVertexAttribArray(aPosition);webgl.vertexAttribPointer(aPosition, 4, webgl.FLOAT, false, 6 * 4, 0);// 获取顶点着色器中UV坐标属性的位置let attribOutUV = webgl.getAttribLocation(webgl.program, "a_outUV");webgl.enableVertexAttribArray(attribOutUV);webgl.vertexAttribPointer(attribOutUV, 2, webgl.FLOAT, false, 6 * 4, 4 * 4);// 矩阵变换let ProjMatrix = glMatrix.mat4.create();glMatrix.mat4.identity(ProjMatrix);// 设置透视投影矩阵glMatrix.mat4.perspective(ProjMatrix, angle * Math.PI / 180, webglDiv.clientWidth / webglDiv.clientHeight, 1, 1000);let uniformMatrix1 = webgl.getUniformLocation(webgl.program, "u_formMatrix");// 模型矩阵的旋转let ModelMatrixx = glMatrix.mat4.create();glMatrix.mat4.identity(ModelMatrixx);glMatrix.mat4.rotate(ModelMatrixx, ModelMatrixx, offsetX * Math.PI / 180, [0, 1, 0]);let ModelMatrixy = glMatrix.mat4.create();glMatrix.mat4.identity(ModelMatrixy);glMatrix.mat4.rotate(ModelMatrixy, ModelMatrixy, offsetY * Math.PI / 180, [1, 0, 0]);let ModelMatrixxy = glMatrix.mat4.create();glMatrix.mat4.identity(ModelMatrixxy);glMatrix.mat4.multiply(ModelMatrixxy, ModelMatrixx, ModelMatrixy);// 模型矩阵的平移let ModelMatrixWheel = glMatrix.mat4.create();glMatrix.mat4.identity(ModelMatrixWheel);console.log(wheelMove);glMatrix.mat4.translate(ModelMatrixWheel, ModelMatrixWheel, [0, 0, wheelMove]);glMatrix.mat4.multiply(ModelMatrixWheel, ModelMatrixWheel, ModelMatrixxy);// 视图矩阵let ViewMatrix = glMatrix.mat4.create();glMatrix.mat4.identity(ViewMatrix);glMatrix.mat4.lookAt(ViewMatrix, [0, 0, 10], [0, 0, 0], [0, 1, 0]);// 模型视图矩阵let mvMatrix = glMatrix.mat4.create();glMatrix.mat4.identity(mvMatrix);glMatrix.mat4.multiply(mvMatrix, ViewMatrix, ModelMatrixWheel);// 模型视图投影矩阵let mvpMatrix = glMatrix.mat4.create();glMatrix.mat4.identity(mvpMatrix);glMatrix.mat4.multiply(mvpMatrix, ProjMatrix, mvMatrix);webgl.uniformMatrix4fv(uniformMatrix1, false, mvpMatrix);// 纹理绘制let uniformTexture = webgl.getUniformLocation(webgl.program, "texture");let texture = initTexture("container2_specular.png");
}// 初始化纹理
function initTexture(imageFile) {let textureHandle = webgl.createTexture();textureHandle.image = new Image();textureHandle.image.src = imageFile;textureHandle.image.onload = function () {handleLoadedTexture(textureHandle);}return textureHandle;
}// 处理加载完成的纹理
function handleLoadedTexture(texture) {webgl.bindTexture(webgl.TEXTURE_2D, texture);webgl.pixelStorei(webgl.UNPACK_FLIP_Y_WEBGL, true);webgl.texImage2D(webgl.TEXTURE_2D, 0, webgl.RGBA, webgl.RGBA, webgl.UNSIGNED_BYTE, texture.image);webgl.texParameteri(webgl.TEXTURE_2D, webgl.TEXTURE_MAG_FILTER, webgl.LINEAR); // 纹理放大方式webgl.texParameteri(webgl.TEXTURE_2D, webgl.TEXTURE_MIN_FILTER, webgl.LINEAR); // 纹理缩小方式webgl.texParameteri(webgl.TEXTURE_2D, webgl.TEXTURE_WRAP_S, webgl.CLAMP_TO_EDGE); // 纹理水平填充方式webgl.texParameteri(webgl.TEXTURE_2D, webgl.TEXTURE_WRAP_T, webgl.CLAMP_TO_EDGE); // 纹理垂直填充方式// 清除颜色缓冲区和深度缓冲区webgl.clearColor(0, 0, 0, 1);webgl.clear(webgl.COLOR_BUFFER_BIT | webgl.DEPTH_BUFFER_BIT);// 启用深度测试webgl.enable(webgl.DEPTH_TEST);// 激活纹理单元webgl.activeTexture(webgl.TEXTURE0);// 绑定纹理webgl.bindTexture(webgl.TEXTURE_2D, texture);// 将纹理传递给着色器webgl.uniform1i(uniformTexture, 0);// 绘制三角形webgl.drawArrays(webgl.TRIANGLES, 0, 36);
}

WebGL API 的 WebGLRenderingContext.bindTexture() 方法将给定的 WebGLTexture 绑定到目标(绑定点)。

复盘:

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com