WebGL实现两个模型的独立运动:旋转、前进后退、缩放

本文介绍了如何使用WebGL实现两个三维模型的独立运动,包括模型的旋转、前进后退和缩放功能。通过控制视图矩阵、模型视图矩阵和矩阵运算,实现了模型的动态效果。详细讲解了关键代码部分,包括顶点着色器、片元着色器、矩阵运算和事件监听。示例代码展示了模型的初始化、矩阵计算和渲染过程。
摘要由CSDN通过智能技术生成

实现两个三维模型的独立运动,包括每个模型的转向、前进后退、缩放功能。此处方向均以运动模型作为参考,模型正面方向为前进,相反方向为后退,绕动物中轴线转向。

完整代码已在传送门给出,效果图如下:
效果图

html文件:

首先,在html文件中定义了顶点着色器和片元着色器:

<script id="vertex-shader" type="x-shader/x-vertex">

attribute  vec4 vPosition;
attribute  vec4 vColor;
varying vec4 fColor;

uniform mat4 viewMatrix;
uniform mat4 modelViewMatrix;

void main()
{
    
    fColor = vColor;
    gl_Position = viewMatrix * modelViewMatrix * vPosition;
    gl_Position.z = -gl_Position.z;
}
</script>

<script id="fragment-shader" type="x-shader/x-fragment">

precision mediump float;

varying vec4 fColor;

void
main()
{
    
    gl_FragColor = fColor;
}
</script>

在顶点着色器中,viewMatrix矩阵为视图矩阵,用于调整视线的方向;modelViewMatrix矩阵为模型视图矩阵,用于控制模型的方向。

js文件

在js文件中,首先做好准备工作,声明了一系列全局变量,以供后续的使用。此处给出了海绵宝宝身体各部位(立方体)的长宽高大小。值得一提的是,这里我们可以看到两个变量,direct和direct2,它们用于记录两个模型的正面方向,用于模型执行前进后退操作时确定方向。

var canvas;
var gl;

var ms = 180; // 画圆的面数

// 海绵宝宝
var points = []; // 顶点容器
var colors = []; // 颜色容器
var vColor, vPosition;
var cBuffer, vBuffer; // 海绵宝宝的buffer
var numVertices = 36*9 + ms*3*2*3 + 12; // 海绵宝宝顶点个数
var modelViewMatrix = mat4(); // 当前变换矩阵
var modelViewMatrixLoc; // shader变量
var CubeTx = 0, CubeTy = 0, CubeTz = 0; //海绵宝宝平移量
var CubeRotateAngle = 0; //海绵宝宝旋转角度
var scalePercent = 0.5; // 缩放比例
var direct = vec4( 0.0, 0.0, 1.0, 1.0 ); // 当前正面方向

// 粉色海绵宝宝
var points2 = []; // 顶点容器
var colors2 = []; // 颜色容器
var vColor2, vPosition2;
var cBuffer2, vBuffer2; // 粉色海绵宝宝的buffer
var numVertices2 = 36*9 + ms*3*2*3 + 12; // 粉色海绵宝宝顶点个数
var CubeTx2 = 0, CubeTy2 = 0, CubeTz2 = 0; // 粉色海绵宝宝平移量
var CubeRotateAngle2 = 0; // 粉色海绵宝宝旋转角度
var scalePercent2 = 0.5; // 缩放比例
var direct2 = vec4( 0.0, 0.0, 1.0, 1.0 ); // 当前正面方向

var viewMatrixLoc; // 视图矩阵的存储地址
var viewMatrix; // 当前视图矩阵
var viewIndex = 0; // 视图编号

var body = vec3( 0.4, 0.45, 0.2 );
var cloth = vec3( 0.4, 0.05, 0.2 );
var pants = vec3( 0.4, 0.1, 0.2 );
var leg = vec3( 0.06, 0.25, 0.05 );
var shoe = vec3( 0.12, 0.05, 0.05 );

// 所有的备选颜色
var chooseColors = [
    vec4(1.0, 0.96, 0.30, 1.0), // 黄色
    vec4(1.0, 1.0, 1.0, 1.0), // 白色
    vec4(0.51, 0.33, 0.24, 1.0), // 褐色
    vec4(0.0, 0.0, 0.0, 1.0), // 黑色
    vec4(0.96, 0.64, 0.66, 1.0) // 粉色
];

下面进入页面加载完成后的init()函数部分。按照常规,此处获取了着色器中各个变量的地址、创建绑定缓冲区,做了一些初始化工作。
第9行:setPoints()函数的内容将在后续给出,此函数就是分别设置了两个模型的所有顶点位置及颜色,写入两个模型的points[]和colors[]数组中。由于此段代码比较长,将在最后给出。
第16-21行:设置了默认的照相机方向。lookAt()三个参数分别为:视点方向,视线方向,上方向。

	canvas = document.getElementById( "gl-canvas" );

    gl = WebGLUtils.setupWebGL( canvas, null );
    if ( !gl ) {
    alert( "WebGL isn't available" ); }

    gl.viewport( 0, 0, canvas.width, canvas.height );
    gl.clearColor( 0.91, 0.92, 0.93, 1.0 ); // 灰色背景色

    setPoints(); // 设置所有顶点位置及颜色
    gl.enable(gl.DEPTH_TEST); // 消除隐藏面

    // 初始化着色器
    var program = initShaders( gl, "vertex-shader", "fragment-shader" );
    gl.useProgram( program );

    // 获取viewMatrix变量的存储地址
    viewMatrixLoc = gl.getUniformLocation(program, 'viewMatrix');
    // 设置视点、视线和上方向
    viewMatrix = lookAt(vec3(0, 0, 0), vec3(0, 0, 0), vec3(0, 1, 0));
    // 将视图矩阵传递给viewMatrix变量
    gl.uniformMatrix4fv(viewMatrixLoc, false, flatten(viewMatrix));

    // 创建缓冲区,并向缓冲区写入立方体每个面的颜色信息
    cBuffer = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, cBuffer );
    gl.bufferData( gl.ARRAY_BUFFER, flatten(colors), gl.STATIC_DRAW );
    //获取着色器中vColor变量,并向其传递数据
    vColor = gl.getAttribLocation( program, "vColor" );
    gl.enableVertexAttribArray( vColor );

    cBuffer2 = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, cBuffer2 );
    gl.bufferData( gl.ARRAY_BUFFER, flatten(colors2
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值