WEBGL学习【六】动起来的三棱锥和立方体

简介: 版权声明:本文为博主原创文章,未经博主允许不得转载。更多学习资料请访问我爱科技论坛:www.52tech.tech https://blog.csdn.net/m0_37981569/article/details/78429154 ...
版权声明:本文为博主原创文章,未经博主允许不得转载。更多学习资料请访问我爱科技论坛:www.52tech.tech https://blog.csdn.net/m0_37981569/article/details/78429154
<html lang="zh-CN">

<!--服务器运行地址:http://127.0.0.1:8080/webgl/LearnNeHeWebGL/NeHeWebGL4.html-->
<head>
    <title>NeHe's WebGL</title>
    <meta charset="UTF-8"/>
    <!--引入需要的库文件-->
    <script type="text/javascript" src="Oak3D_v_0_5.js"></script>

    <!--片元着色器;为JavaScript片段指定一个ID编号,后面我可以更具这个ID编号来获取这段片元着色器的JavaScript片段代码-->
    <script id="shader-fs" type="x-shader/x-fragment">
    precision mediump float;

    varying vec4 vTextureCoord;

    uniform sampler2D uSampler;

    void main(void) {
        gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
    }
    </script>

    <!--顶点着色器;后面可以通过ID编号来获取这段顶点着色器代码-->
    <script id="shader-vs" type="x-shader/x-vertex">
    attribute vec3 aVertexPosition;
    attribute vec4 aTextureCoord;

    uniform mat4 uMVMatrix;
    uniform mat4 uPMatrix;

    varying vec4 vTextureCoord;
    void main(void) {
        gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
        vTextureCoord = aTextureCoord;
    }
    </script>


    <script type="text/javascript">

        var gl;
        //初始化WEBGL
        function initGL(canvas) {
            try {
                //获取WEBGL上下文
                gl = canvas.getContext("experimental-webgl");
                //gl这个上下文中存放了一些属性(canvas的宽度、长度和其他相关属性数据)
                //设置我的视口的宽度和高度
                gl.viewportWidth = canvas.width;
                gl.viewportHeight = canvas.height;
            } catch (e) {
            }
            //如果获取失败
            if (!gl) {
                alert("Could not initialise WebGL, sorry :-(");
            }
        }


        //获取我的着色器对象
        function getShader(gl, id) {
            //根据id获取着色器源程序代码
            var shaderScript = document.getElementById(id);
            if (!shaderScript) {
                return null;
            }

            var str = "";
            var k = shaderScript.firstChild;
            while (k) {
                if (k.nodeType == 3) {
                    str += k.textContent;
                }
                k = k.nextSibling;
            }

            var shader;
            //1.根据着色器的类型创建相应的着色器对象
            if (shaderScript.type == "x-shader/x-fragment") {
                shader = gl.createShader(gl.FRAGMENT_SHADER);
            } else if (shaderScript.type == "x-shader/x-vertex") {
                shader = gl.createShader(gl.VERTEX_SHADER);
            } else {
                return null;
            }

            //2.向着色器对象中指定相应的GLSL ES源代码(以字符串的形式传递进去)
            gl.shaderSource(shader, str);
            //3.开始编译着色器(编译成为二进制的可执行文件)
            gl.compileShader(shader);

            //检查下着色器的状态(是否编译成功)
            if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
                alert(gl.getShaderInfoLog(shader));
                return null;
            }

            return shader;
        }


        //一个着色器对象必须包含一个顶点着色器和一个片元着色器
        var shaderProgram;

        //初始化着色器
        function initShaders() {
            //获取我的顶点着色器和片元着色器
            var fragmentShader = getShader(gl, "shader-fs");
            var vertexShader = getShader(gl, "shader-vs");

            //每一个program中可以存放一个顶点着色器和一个片元着色器
            //4.创建我的程序对象
            shaderProgram = gl.createProgram();
            //5.为程序对象分配着色器对象
            gl.attachShader(shaderProgram, vertexShader);
            gl.attachShader(shaderProgram, fragmentShader);

            //6.链接程序对象
            /**
             * 1.可以保证顶点着色器和片元着色器同名并且是同类型的
             * 2.attributeuniformvarying变量个数不超过着色器的上限
             */
            gl.linkProgram(shaderProgram);
            //检测是否连接成功
            if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
                alert("Could not initialise shaders");
            }
            //7.告诉WEBGL要使用的程序对象
            gl.useProgram(shaderProgram);

            //指定一个新的属性;gl.enableVertexAttribArray,我们使用它来告诉WebGL我们会用一个数组来为属性赋值
            //顶点的位置信息
            shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
            gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);

            //获取我的顶点着色器中的attribute纹理坐标参数数据
            shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord");
            gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute);

            //program中取得另外的两个属性值(模型视图投影矩阵)
            shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
            shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
        }


        //定义了我的模型视图矩阵和投影矩阵
        var mvMatrix;
        var pMatrix;

        //在这里实现我的矩阵的进栈和出栈操作
        var mvMatrixStack = [];
        function myPushMatrix() {
            var copy = new okMat4();
            mvMatrix.clone(copy);
            mvMatrixStack.push(copy);
        }

        function myPopMatrix() {
            if (mvMatrixStack.length == 0) {
                throw "Invalid popMatrix!";
            }
            mvMatrix = mvMatrixStack.pop();
        }

        //把我们新设置的模型视图投影矩阵传给顶点着色器中的uniform变量
        function setMatrixUniforms() {
            gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix.toArray());
            gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix.toArray());
        }


        //定义我的三角形和矩形缓冲区顶点位置
        var pyramidVertexPositionBuffer;
        var cubeVertexPositionBuffer;
        //定义我的三角形和矩形缓冲区的顶点颜色
        var pyramidVertexColorBuffer;
        var cubeVertexTextureCoordBuffer ;
        //定义我的立方体索引下标
        var cubeVertexIndexBuffer;

        //缓冲区的初始化
        function initBuffers() {
            //1.新建三角形顶点缓冲区对象
            pyramidVertexPositionBuffer = gl.createBuffer();
            //2.绑定目标对象到缓冲区
            gl.bindBuffer(gl.ARRAY_BUFFER, pyramidVertexPositionBuffer);
            //初始化我的顶点数组
            var vertices = [
                // Front face
                0.0,  1.0,  0.0,
                -1.0, -1.0,  1.0,
                1.0, -1.0,  1.0,

                // Right face
                0.0,  1.0,  0.0,
                1.0, -1.0,  1.0,
                1.0, -1.0, -1.0,

                // Back face
                0.0,  1.0,  0.0,
                1.0, -1.0, -1.0,
                -1.0, -1.0, -1.0,

                // Left face
                0.0,  1.0,  0.0,
                -1.0, -1.0, -1.0,
                -1.0, -1.0,  1.0
            ];
            //3.缓冲区对象中写入数据
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

            //计算顶点数组的大小和顶点个数
            pyramidVertexPositionBuffer.itemSize = 3;
            pyramidVertexPositionBuffer.numItems = 12;

            //1.创建我的颜色缓冲区
            pyramidVertexColorBuffer = gl.createBuffer();
            //2.绑定我的颜色缓冲区到目标对象
            gl.bindBuffer(gl.ARRAY_BUFFER, pyramidVertexColorBuffer);
            //初始化我的颜色数组(对每一个顶点指定相应的颜色)
            var colors = [
                //注意保证在同一个顶点上面的颜色要相同
                // Front face
                1.0, 0.0, 0.0, 1.0,
                0.0, 1.0, 0.0, 1.0,
                0.0, 0.0, 1.0, 1.0,

                // Right face
                1.0, 0.0, 0.0, 1.0,
                0.0, 0.0, 1.0, 1.0,
                0.0, 1.0, 0.0, 1.0,

                // Back face
                1.0, 0.0, 0.0, 1.0,
                0.0, 1.0, 0.0, 1.0,
                0.0, 0.0, 1.0, 1.0,

                // Left face
                1.0, 0.0, 0.0, 1.0,
                0.0, 0.0, 1.0, 1.0,
                0.0, 1.0, 0.0, 1.0
            ];
            //3.向缓冲区对象中写入数据
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
            //计算三角形顶点颜色数组的大小和顶点个数
            pyramidVertexColorBuffer.itemSize = 4;
            pyramidVertexColorBuffer.numItems = 12;



            //1.新建矩形顶点缓冲区对象
            cubeVertexPositionBuffer = gl.createBuffer();
            //2.绑定目标对象到缓冲区
            gl.bindBuffer(gl.ARRAY_BUFFER, cubeVertexPositionBuffer);
            //立方体的顶点位置数组
            vertices = [
                // Front face(123第一个三角形, 134第二个三角形)
                -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
            ];
            //3.向缓冲区对象中写入数据
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
            //计算矩形顶点数组每一项数据的大小,和顶点个数(有四个不同的顶点位置,每个顶点由3个数字组成)
            cubeVertexPositionBuffer.itemSize = 3;
            cubeVertexPositionBuffer.numItems = 24;

            //1.创建我的立方体的顶点纹理图片缓冲区
            cubeVertexTextureCoordBuffer  = gl.createBuffer();
            //2.绑定目标对象到缓冲区
            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,
            ];


            //3.向缓冲区对象中写入数据
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoords), gl.STATIC_DRAW);
            //计算我的正方形的顶点数组
            cubeVertexTextureCoordBuffer .itemSize = 2;
            cubeVertexTextureCoordBuffer .numItems = 24;


            //开始定义我的顶点位置数组
            //1.创建我的顶点索引缓冲区对象
            cubeVertexIndexBuffer = gl.createBuffer();
            //2.绑定目标对象到缓冲区
            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer);
            //设置我的顶点索引数组
            var cubeVertexIndices = [
                0, 1, 2,      0, 2, 3,    // Front face
                4, 5, 6,      4, 6, 7,    // Back face
                8, 9, 10,     8, 10, 11,  // Top face
                12, 13, 14,   12, 14, 15, // Bottom face
                16, 17, 18,   16, 18, 19, // Right face
                20, 21, 22,   20, 22, 23  // Left face
            ];
            //3.向缓冲区对象写入数据
            gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(cubeVertexIndices), gl.STATIC_DRAW);
            //计算我的顶点索引数组的大小(每一项数据的大小,总共36个数据)
            /**
             * 1个不同的顶点位置(numItems),每个顶点由36个数字组成(itemSize             * @type {number}
             */
            cubeVertexIndexBuffer.itemSize = 1;
            cubeVertexIndexBuffer.numItems = 36;
        }


        //定义我的三角形和我的矩形的初始旋转角度
        var rPyramid = 0;
        var rCube = 0;

        //初始化我的锥形和立方体的旋转变量
        var xRot = 0;
        var xSpeed = 0;

        var yRot = 0;
        var ySpeed = 0;

        var z = -8.0;
        //指定纹理过滤的方式
        var filter = 0;



        //绘制我的场景(三角形和矩形)
        function drawScene() {
            //设置视口大小
            gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
            //清空颜色缓存和深度缓存
            gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

            //建立一个透视投影(视场角,视口比例,最近,最远距离)
            pMatrix = okMat4Proj(45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0);
            //alert('width:'+gl.viewportWidth+'height:'+gl.viewportHeight); 500 500
            //pMatrix = okMat4Proj(45, 500/500, 0.1, 100.0);

            //新建一个模型视图矩阵
            mvMatrix = new okMat4();
            //保存矩阵的初始状态
            myPushMatrix();


            //设置我的模型视图矩阵为平移矩阵
            //mvMatrix = okMat4Trans(-1.5, 0.0, -7.0);
            mvMatrix.translate(OAK.SPACE_WORLD, -1.5, 0.0, z, true);
            //三角形的椎体绕着Y轴旋转(本地坐标系旋转)
            //mvMatrix.rotY(OAK.SPACE_LOCAL, rPyramid, true);
            mvMatrix.rotX(OAK.SPACE_LOCAL, xRot, true);
            mvMatrix.rotY(OAK.SPACE_LOCAL, yRot, true);


            //1.绑定三角形顶点数据到缓冲区对象
            gl.bindBuffer(gl.ARRAY_BUFFER, pyramidVertexPositionBuffer);
            gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, pyramidVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);

            //2.绑定三角形颜色信息到缓冲区对象,并且传递给顶点着色器
            gl.bindBuffer(gl.ARRAY_BUFFER, pyramidVertexColorBuffer);
            gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, pyramidVertexColorBuffer.itemSize, gl.FLOAT, false, 0, 0);



            //告诉WEBGL当前使用的模型视图投影矩阵
            setMatrixUniforms();
            //开始绘制三角形(从第0个位置开始,绘制numItems个顶点)
            gl.drawArrays(gl.TRIANGLES, 0, pyramidVertexPositionBuffer.numItems);
            //绘制完毕后再次恢复我的模型视图矩阵
            myPopMatrix();


            //再次保存我的模型视图矩阵
            myPushMatrix();
            //开始绘制立方体
            mvMatrix.translate(OAK.SPACE_WORLD, 1.5, 0.0, z, true);
            //让我的矩形绕着XYZ轴旋转
            //mvMatrix.rotX(OAK.SPACE_LOCAL, rCube, true);
            //mvMatrix.rot(OAK.SPACE_LOCAL, rCube, 1.0, 1.0, 1.0, true);
            mvMatrix.rotX(OAK.SPACE_LOCAL, xRot, true);
            mvMatrix.rotY(OAK.SPACE_LOCAL, yRot, true);


            //绑定四边形的顶点信息(与索引下标绑定在一起)
            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);

            //开始使用我的纹理图片来绘制我的立方体(在绘制之前使用这个函数drawElemenets());TEXTURE0TEXTURE31
            gl.activeTexture(gl.TEXTURE0);

            //告诉WEBGL要使用的纹理图片(0 1 2 )
            //gl.bindTexture(gl.TEXTURE_2D, neheTexture);
            gl.bindTexture(gl.TEXTURE_2D, createTextures[filter]);
            //0这个值推送到着色器的uniform变量中
            gl.uniform1i(shaderProgram.samplerUniform, 0);


            //开始绑定索引下标信息
            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVertexIndexBuffer);
            setMatrixUniforms();
            //开始绘制立方体
            //gl.drawArrays(gl.TRIANGLE_STRIP, 0, cubeVertexPositionBuffer.numItems);
            gl.drawElements(gl.TRIANGLES, cubeVertexIndexBuffer.numItems, gl.UNSIGNED_SHORT, 0);

            //绘制完毕后,恢复我的模型视图矩阵的初始状态
            myPopMatrix();
        }


        //实现我的载入图片的功能
        function handleLoadedTexture(textures) {
            //更正图形坐标
            gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);

            //指定要使用的纹理对象,并且指定了三种不同的纹理过滤方式
            gl.bindTexture(gl.TEXTURE_2D, textures[0]);
            //Nearest(最近点采样过滤)
            gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textures[0].image);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);

            //Linear(线性过滤),我们在放大缩小时还是使用同样的过滤方式
            gl.bindTexture(gl.TEXTURE_2D, textures[1]);
            gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textures[1].image);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);

            //Mipmaps(多级渐进纹理过滤)
            gl.bindTexture(gl.TEXTURE_2D, textures[2]);
            gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textures[2].image);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST);
            //告诉WebGL为当前活动纹理生成对应的一系列MipMap            gl.generateMipmap(gl.TEXTURE_2D);

            //清空当前纹理
            gl.bindTexture(gl.TEXTURE_2D, null);
        }

        //实现我的初始化纹理图片
        var createTextures = Array();

        //创建一个数组,这个数组中包含三个纹理对象
        function initTexture() {
            var createImage = new Image();

            //循环生成三个纹理图片
            for (var i=0; i<3; i++){
                var texture = gl.createTexture();
                texture.image = createImage;
                //向数组中存放数据
                createTextures.push(texture);
            }

            //纹理图片加载完成之后调用该函数
            createImage.onload = function () {
                handleLoadedTexture(createTextures);
            }

            //设置图片的纹理地址
            createImage.src = './Resources/woodbox.bmp';
        }


        //这里是我的主函数
        function webGLStart() {
            //获取canvas元素
            var canvas = document.getElementById("lesson01-canvas");

            //初始化WEBGL上下文信息
            initGL(canvas);

            //初始化着色器
            initShaders();

            //初始化缓冲区对象
            initBuffers();

            //初始化纹理图片
            initTexture();

            //指定清空画布的颜色,开启隐藏面消除的功能
            gl.clearColor(0.0, 0.0, 0.0, 1.0);
            gl.enable(gl.DEPTH_TEST);


            //添加按键控制的功能
            document.onkeydown = handleKeyDown;
            document.onkeyup = handleKeyUp;


            //开始绘制我的场景
            //drawScene();
            //开始使用动画效果来绘制我的图形
            tick();
        }

        //按键控制函数
        var currentPressKeys = {};
        function handleKeyDown(event) {
            //把当前的按下的按键键值缓存下来
            currentPressKeys[event.keyCode] = true;

            //开始循环切换纹理滤镜
            if (String.fromCharCode(event.keyCode) == 'F'){
                filter +=1;
                if (filter == 3){
                    filter = 0;
                }
            }
        }
        function handleKeyUp() {
            currentPressKeys[event.keyCode] = false;
        }

        //根据不同按键做出不同的反应
        function handleKeys() {
            if (currentPressKeys[33]) {
                // Page Up
                z -= 0.05;
            }
            if (currentPressKeys[34]) {
                // Page Down
                z += 0.05;
            }
            if (currentPressKeys[37]) {
                // Left cursor key
                ySpeed -= 1;
            }
            if (currentPressKeys[39]) {
                // Right cursor key
                ySpeed += 1;
            }
            if (currentPressKeys[38]) {
                // Up cursor key
                xSpeed -= 1;
            }
            if (currentPressKeys[40]) {
                // Down cursor key
                xSpeed += 1;
            }
        }


        //实现我的动画绘制函数
        function tick() {
            //重复调用tick函数
            okRequestAnimationFrame(tick);

            //处理按下的按键
            handleKeys();

            //开始绘制场景
            drawScene();

            //改变我的三角形和我的矩阵的旋转角度
            animate();
        }


        //开始不断修改我的旋转角度
        var lastTime = 0;
        function animate() {
            var timeNow = new Date().getTime();
            if (lastTime != 0) {
                var elapsed = timeNow - lastTime;

                //三角形 90/s, 矩形 75/s
                xRot += (xSpeed * elapsed) / 1000.0;
                yRot += (ySpeed * elapsed) / 1000.0;
            }
            lastTime = timeNow;
        }

    </script>


</head>

<body onload="webGLStart();">
<canvas id="lesson01-canvas" style="border: none;" width="700" height="700"></canvas>
</body>

</html>
相关文章
|
28天前
ThreeJs创建球体
这篇文章讲解了如何在Three.js中创建并添加一个球体到场景中,包括定义球体的几何形状、赋予材质以及最终渲染球体的过程。
34 1
|
3月前
PPT 动画-多层旋转(圆角三角形)
PPT 动画-多层旋转(圆角三角形)
33 0
|
30天前
|
JavaScript API 图形学
ThreeJS入门-创建一个正方体
这篇文章介绍了如何使用Three.js创建一个基本的正方体模型,并提供了实现这一功能的详细步骤和代码示例。
31 0
ThreeJS入门-创建一个正方体
|
3月前
|
前端开发 API
【threejs教程】让你的场景动起来!深入了解threejs场景及坐标轴
【8月更文挑战第5天】让你的场景动起来!深入了解threejs场景及坐标轴
38 0
【threejs教程】让你的场景动起来!深入了解threejs场景及坐标轴
|
3月前
|
缓存 图形学 C++
Unreal学习笔记2-绘制简单三角形
Unreal学习笔记2-绘制简单三角形
25 0
|
移动开发 前端开发 HTML5
前端|3D立体视频翻转动画
前端|3D立体视频翻转动画
222 0
|
前端开发 JavaScript API
⚡初识Three.js,在场景中创建一个旋转的正方体~
⚡初识Three.js,在场景中创建一个旋转的正方体~
325 3
⚡初识Three.js,在场景中创建一个旋转的正方体~
|
前端开发 JavaScript
canvas中的拖拽、缩放、旋转 (上) —— 数学知识准备
canvas中的拖拽、缩放、旋转 (上) —— 数学知识准备
883 0
canvas中的拖拽、缩放、旋转 (上) —— 数学知识准备
|
图形学
Unity3D旋转
Unity3D旋转
131 0
|
前端开发 Android开发
autojs加载3D旋转立方体效果
autojs加载3D旋转立方体效果
372 0