精华内容
下载资源
问答
  • 28 WebGL绘制立方体

    千次阅读 2017-06-02 17:54:28
    下面,我们将学习如何绘制如图所示的一个立方体,目标:如果按以前所学的知识,制作这个正方体就需要使用三角形两个拼一个矩形,最后拼出来六个正方形来组成这个立方体,由于绘制三角形需要重复调用顶点,虽然只需要...

    案例查看地址:点击这里

    到现在为止,一直学的都是绘制一些简单的三角形。下面,我们将学习如何绘制如图所示的一个立方体,目标:


    如果按以前所学的知识,制作这个正方体就需要使用三角形两个拼一个矩形,最后拼出来六个正方形来组成这个立方体,由于绘制三角形需要重复调用顶点,虽然只需要8个顶点的位置,但是,绘制三角形的时候,却需要多次调用,所以给我们提供了一个gl.drawElements()函数的解决方案。使用该函数替代gl.drawArrays()函数进行绘制,能够避免重复定义顶点,报错顶点数量最小。为此,你需要知道模型的每一个顶点的坐标,这些顶点坐标描述了整个模型。

    我们将立方体拆成顶点和三角形,如图7.32所示。立方体呗拆成6个面:前、后、左、右、上、下,每个面都由两个三角形组成,与三角形列表中的两个三角形相关联。每个三角形都有3个顶点,与顶点列表中的3个顶点相关联。三角形列表中的数字表示该三角形的3个顶点在顶点列表中的索引值。顶点列表中共有8个顶点,索引值为从0到7。


    而现在新的gl.drawElements()方法就是通过顶点索引绘制物体,首先我们来看一下如何使用gl.drawElements(),我们需要在gl.ELEMENT_ARRAY_BUFFER(而不是之前一直使用的gl.ARRAY_BUFFER)中指定顶点的索引值。所以两种方法最重要的区别就在于gl.ELEMENT_ARRAY_BUFFER,它管理这具有索引结构的三位模型数据。


    如果传入的type参数和gl.ELEMENT_ARRAY_BUFFER中的数据类型(Uint8Array或Uint16Array)不一致,也并不会出现错误。但是如果两者不一致,比如缓冲区是Uint16Array类型的,而传入的参数为gl.UNSIGNED_SHORT,那么程序会错误地理解缓冲区中的数据,并会绘制出一些不可预测的东西。

    下面书写一个案例:


    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Title</title>
        <style>
            body {
                margin: 0;
                text-align: center;
            }
    
            #canvas {
                margin: 0;
            }
        </style>
    </head>
    <body οnlοad="main()">
    <canvas id="canvas" height="800" width="1200"></canvas>
    </body>
    <script src="lib/webgl-utils.js"></script>
    <script src="lib/webgl-debug.js"></script>
    <script src="lib/cuon-utils.js"></script>
    <script src="lib/cuon-matrix.js"></script>
    <script>
        //顶点着色器
        var VSHADER_SOURCE = "" +
            "attribute vec4 a_Position;\n" +
            "attribute vec4 a_Color;\n" +
            "uniform mat4 u_ModelViewMatrix;\n" +
            "varying vec4 v_Color;\n" +
            "void main(){" +
            "   gl_Position = u_ModelViewMatrix * a_Position;\n" +
            "   v_Color = a_Color;\n" +
            "}\n";
    
        //片元着色器
        var FSHADER_SOURCE = "" +
            "#ifdef GL_ES\n" +
            "precision mediump float;\n" +
            "#endif\n" +
            "varying vec4 v_Color;\n" +
            "void main(){" +
            "   gl_FragColor = v_Color;\n" +
            "}\n";
    
        //声明js需要的相关变量
        var canvas = document.getElementById("canvas");
        var gl = getWebGLContext(canvas);
    
        function main() {
            if (!gl) {
                console.log("你的浏览器不支持WebGL");
                return;
            }
    
            //初始化着色器
            if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
                console.log("无法初始化着色器");
                return;
            }
    
            var n = initVertexBuffers(gl);
            if (n < 0) {
                console.log("无法创建缓冲区");
                return;
            }
    
            //设置视角矩阵的相关信息
            var u_ModelViewMatrix = gl.getUniformLocation(gl.program, "u_ModelViewMatrix");
            if (u_ModelViewMatrix < 0) {
                console.log("无法获取矩阵变量的存储位置");
                return;
            }
    
            //设置底色
            gl.clearColor(0.0, 0.0, 0.0, 1.0);
    
            //进入场景初始化
            draw(gl, n, u_ModelViewMatrix);
        }
    
        function draw(gl, n, u_ModelViewMatrix) {
            //设置视角矩阵的相关信息(视点,视线,上方向)
            var viewMatrix = new Matrix4();
            viewMatrix.setLookAt(3,3,7,0,0,0,0,1,0);
    
            //设置模型矩阵的相关信息
            var modelMatrix = new Matrix4();
            modelMatrix.setRotate(0, 0, 0, 1);
    
            //设置透视投影矩阵
            var projMatrix = new Matrix4();
            projMatrix.setPerspective(30,canvas.width/canvas.height,1,100);
    
            //计算出模型视图矩阵 viewMatrix.multiply(modelMatrix)相当于在着色器里面u_ViewMatrix * u_ModelMatrix
            var modeViewMatrix = projMatrix.multiply(viewMatrix.multiply(modelMatrix));
    
            //将试图矩阵传给u_ViewMatrix变量
            gl.uniformMatrix4fv(u_ModelViewMatrix, false, modeViewMatrix.elements);
    
            //开启隐藏面清除
            gl.enable(gl.DEPTH_TEST);
    
            //清空颜色和深度缓冲区
            gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
    
            //绘制图形
            gl.drawElements(gl.TRIANGLES,n,gl.UNSIGNED_BYTE,0);
    
        }
    
        function initVertexBuffers(gl) {
            // 创建一个立方体
            //    v6----- v5
            //   /|      /|
            //  v1------v0|
            //  | |     | |
            //  | |v7---|-|v4
            //  |/      |/
            //  v2------v3
            var verticesColors = new Float32Array([
                // 设置顶点和颜色(偷的顶点代码位置)
                1.0,  1.0,  1.0,     1.0,  1.0,  1.0,  // v0 White
                -1.0,  1.0,  1.0,     1.0,  0.0,  1.0,  // v1 Magenta
                -1.0, -1.0,  1.0,     1.0,  0.0,  0.0,  // v2 Red
                1.0, -1.0,  1.0,     1.0,  1.0,  0.0,  // v3 Yellow
                1.0, -1.0, -1.0,     0.0,  1.0,  0.0,  // v4 Green
                1.0,  1.0, -1.0,     0.0,  1.0,  1.0,  // v5 Cyan
                -1.0,  1.0, -1.0,     0.0,  0.0,  1.0,  // v6 Blue
                -1.0, -1.0, -1.0,     0.0,  0.0,  0.0   // v7 Black
            ]);
    
            //顶点索引
            var indices = new Uint8Array([
                0, 1, 2,   0, 2, 3,    // 前
                0, 3, 4,   0, 4, 5,    // 右
                0, 5, 6,   0, 6, 1,    // 上
                1, 6, 7,   1, 7, 2,    // 左
                7, 4, 3,   7, 3, 2,    // 下
                4, 7, 6,   4, 6, 5     // 后
            ]);
    
            //创建缓冲区对象
            var vertexColorBuffer = gl.createBuffer();
            var indexBuffer = gl.createBuffer();
            if (!vertexColorBuffer || !indexBuffer) {
                console.log("无法创建缓冲区对象");
                return -1;
            }
    
            //绑定缓冲区对象并写入数据
            gl.bindBuffer(gl.ARRAY_BUFFER, vertexColorBuffer);
            gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW);
    
            //获取数组中一个元素所占的字节数
            var fsize = verticesColors.BYTES_PER_ELEMENT;
    
            //获取顶点位置变量位置
            var a_Position = gl.getAttribLocation(gl.program, "a_Position");
            if (a_Position < 0) {
                console.log("无法获取顶点位置的存储变量");
                return -1;
            }
    
            //对位置的顶点数据进行分配,并开启
            gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, fsize * 6, 0);
            gl.enableVertexAttribArray(a_Position);
    
            //获取顶点颜色的变量
            var a_Color = gl.getAttribLocation(gl.program, "a_Color");
            if (a_Color < 0) {
                console.log("无法获取顶点位置的存储变量");
                return -1;
            }
    
            //对位置的顶点数据进行分配,并开启
            gl.vertexAttribPointer(a_Color, 3, gl.FLOAT, false, fsize * 6, fsize * 3);
            gl.enableVertexAttribArray(a_Color);
    
            //将顶点索引数据写入缓冲区对象
            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,indexBuffer);
            gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,indices,gl.STATIC_DRAW);
    
            return indices.length;
        }
    </script>
    </html>

    在124行:

    本案例不再使用verticesColor中的顶点顺序来进行绘制,所以必须额外注意每个顶点的索引值,我们要通过索引值来指定绘制的顺序。比如说,第1个顶点的索引为0,第2个顶点的索引为1,等等。

    183行:

    缓冲区对象indexBuffer中的数据来自于数组indices,该数组以索引值的形式存储了绘制顶点的顺序。索引值是整型数,所以数组的类型是Uint8Array(无符号8位整型数)。如果有超过256个顶点,那么就应该使用Uint16Array。indices中的元素如图7.33中的三角形列表所示,每3个索引值为1组,指向3个顶点,由这3个顶点组成1个三角形。通常我们不需要手动创建这些顶点和索引数据,因为三维建模工具会帮助我们创建它们。

    在调用gl.drawElements()时,WebGL首先充绑定到gl.ELEMENT_ARRAY_BUFFER的缓冲区(也就是indexBuffer)中获取索引值,然后根据该索引值,从绑定到gl.ARRAY_BUFFER的缓冲区(即vertexColorBuffer)中获取顶点的坐标、颜色等信息,然后传递给attribute变量并执行顶点着色器。对每个索引值都这样做,最后就绘制出了整个立方体,而且值调用了一次gl.drawElements()。这种方式通过索引来访问顶点数据,从而循环利用顶点信息,控制内存的开销,但代价是你需要通过索引来简介地访问顶点,在某种程度上使程序赋值话了,所以,两个绘制方法各有优劣,具体用哪一个取决于具体的需求。

    展开全文
  • 要通过WebGL渲染出立方体旋转的动画效果,你首要了解“帧”这个概念,比如你观看的视频其实就是一帧一帧的图片连续播放的效果,只要图片刷新的频率的不是太低,人的眼睛都不会察觉,一般30~60FPS就可以。 WebGL如何...

    立方体旋转动画

    本文是WebGL电子书的1.10节内容

    要通过WebGL渲染出立方体旋转的动画效果,你首要了解“帧”这个概念,比如你观看的视频其实就是一帧一帧的图片连续播放的效果,只要图片刷新的频率的不是太低,人的眼睛都不会察觉,一般30~60FPS就可以。 WebGL如何产生一帧一帧的图片,这个很简单,执行一次绘制函数gl.drawArrays(),WebGL图形系统就会通知GPU渲染管线处理顶点数据生成一帧RGB像素数据显示在屏幕canvas画布上。只要周期性保持一定的频率调用gl.drawArrays()就可以生成一帧一帧的图片, 在这个过程中同时要利用Javascript程序更新顶点的旋转矩阵,如果顶点的位置不变化,渲染出来的都是一样的图片,自然也没有动画的效果。

    浏览器提供了一个方法requestAnimationFrame()可以实现周期性调用某个函数,主要用于动画,该方法如何使用可以查看文章《HTML5定时器》

    在1.9节光照立方体的基础上进行更改,一方面是周期性执行绘制方法gl.drawArrays(),另一方面以一定的旋转速度更新立方体的旋转矩阵,原来使用着色器语言定义的旋转矩阵更改为使用Javascript语句创建好再传递给顶点着色器, gl.drawArrays()每次执行的时候,都会重新传入着色器顶点旋转矩阵数据,并渲染出来。

    声明矩阵变量

    /**uniform声明旋转矩阵变量mx、my**/
    uniform mat4 mx;//绕x轴旋转矩阵
    uniform mat4 my;//绕y轴旋转矩阵
    

    在顶点着色器代码中使用关键字uniform声明两个旋转矩阵变量mxmy,分别表示绕x轴、y轴的旋转矩阵。旋转矩阵数据和光照数据一样适用于所有的非顶点数据,使用关键字uniform声明,不能使用attribute关键字声明。

    传入mx矩阵数据

    /**从program对象获得旋转矩阵变量mx、my地址**/
    var mx = gl.getUniformLocation(program,'mx');
    var my = gl.getUniformLocation(program,'my');
    
    /**绕x轴旋转45度**/
    var mxArr = new Float32Array([
        1,0,0,0,
        0,Math.cos(Math.PI/4),-Math.sin(Math.PI/4),0,
        0,Math.sin(Math.PI/4),Math.cos(Math.PI/4),0,
        0,0,0,1
    ]);
    //把数据mxArr传递给着色器旋转矩阵变量mx
    gl.uniformMatrix4fv(mx, false, mxArr);
    
    

    上节课定义顶点旋转矩阵使用的着色器语言,下面的案例是先在Javascript程序中使用类型数组Float32Array()创建旋转矩阵的数据,然后使用WebGL APIgl.uniformMatrix4fv()把数据传递给着色器。WebGL中给着色器中不同关键字声明的不同类型变量传递数据, 要使用不同的WebGL API,uniform关键字声明的mat4类型变量使用WebGL APIgl.uniformMatrix4fv()uniform关键字声明的mat2类型变量使用WebGL APIuniformMatrix2fv()uniform关键字声明的一个浮点数使用gl.uniform1f()传递, uniform关键字声明的vec4类型变量和mat4一样使用uniform4fv(变量地址名,new Float32Array([a,b,c,d]))传递,也可以使用uniform4f(变量地址名,a,b,c,d)传递,attribute关键字声明的变量使用WebGL APIgl.vertexAttribPointer()传递。

    绘制函数draw()

    该绘制函数draw()可以使用第requestAnimationFrame(draw);代码实现draw()函数的循环调用,因为要实现立方体绕y轴旋转,所以要在draw函数中更新my旋转矩阵的数据,同时利用WebGL APIgl.uniformMatrix4fv()把新的矩阵数据传递给着色器矩阵变量my, 在函数重复调用gl.drawArrays(gl.TRIANGLES,0,36);不停绘制旋转后的顶点数据,所有需要更新的数据都要写在draw函数中,不需要反复执行的代码写在draw函数外,比如mx旋转矩阵只需要执行传入一次不在改变。

    /**
     * 定义绘制函数draw(),定时更新旋转矩阵数据,并调用WebGL绘制API
     ***/
    var angle = Math.PI/4;//起始角度
    function draw() {
        /**
         * 立方体绕y轴旋转
         ***/
        angle += 0.01;//每次渲染角度递增,每次渲染不同的角度
        var sin = Math.sin(angle);//旋转角度正弦值
        var cos = Math.cos(angle);//旋转角度余弦值
        var myArr = new Float32Array([cos,0,-sin,0,  0,1,0,0,  sin,0,cos,0,  0,0,0,1]);
        gl.uniformMatrix4fv(my, false, myArr);
        requestAnimationFrame(draw);
        /**执行绘制命令**/
        gl.drawArrays(gl.TRIANGLES,0,36);
    }
    draw();
    
    展开全文
  • WebGL绘制立方体-每个面一种颜色 本文是WebGL电子书的1.8节内容 思路很简单,在线框模式的立方体源码基础上直接进行更改,添加varying变量,引入顶点数据颜色,立方体6个面,每个面可以分为两个三角面绘制出来,也...

    WebGL绘制立方体-每个面一种颜色

    本文是WebGL电子书的1.8节内容

    思路很简单,在线框模式的立方体源码基础上直接进行更改,添加varying变量,引入顶点数据颜色,立方体6个面,每个面可以分为两个三角面绘制出来,也就是说每个面需要定义6个点,6个点需要定义36个顶点。

    着色器程序

    着色器程序参考颜色插值varying的使用方法添加即可,就不再列出。

    顶点数据

    /**
     创建顶点位置数据数组data,Javascript中小数点前面的0可以省略
     **/
    var data=new Float32Array([
        .5,.5,.5,-.5,.5,.5,-.5,-.5,.5,.5,.5,.5,-.5,-.5,.5,.5,-.5,.5,      //面1
        .5,.5,.5,.5,-.5,.5,.5,-.5,-.5,.5,.5,.5,.5,-.5,-.5,.5,.5,-.5,      //面2
        .5,.5,.5,.5,.5,-.5,-.5,.5,-.5,.5,.5,.5,-.5,.5,-.5,-.5,.5,.5,      //面3
        -.5,.5,.5,-.5,.5,-.5,-.5,-.5,-.5,-.5,.5,.5,-.5,-.5,-.5,-.5,-.5,.5,//面4
        -.5,-.5,-.5,.5,-.5,-.5,.5,-.5,.5,-.5,-.5,-.5,.5,-.5,.5,-.5,-.5,.5,//面5
        .5,-.5,-.5,-.5,-.5,-.5,-.5,.5,-.5,.5,-.5,-.5,-.5,.5,-.5,.5,.5,-.5 //面6
    ]);
    /**
     创建顶点颜色数组colorData
     **/
    var colorData = new Float32Array([
        1,0,0, 1,0,0, 1,0,0, 1,0,0, 1,0,0, 1,0,0,//红色——面1
        0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0, 0,1,0,//绿色——面2
        0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1, 0,0,1,//蓝色——面3
        1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,//黄色——面4
        0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0,//黑色——面5
        1,1,1, 1,1,1, 1,1,1, 1,1,1, 1,1,1, 1,1,1 //白色——面6
    ]);
    

    深度测试

    /**执行绘制之前,一定要开启深度测试,以免颜色混乱**/
    gl.enable(gl.DEPTH_TEST);
    

    可以尝试把深度测试的语句注释掉,测试代码,观察视觉效果,你会看到面颜色混乱,比如立方体后面的颜色掩盖前面的颜色。执行gl.drawArrays()方法后,GPU开始绘制图形,默认的规则是后生成的像素覆盖前面生成的像素, 绿色的面是左侧可见面,但是如果没有gl.enable(gl.DEPTH_TEST);语句,你会看到本来处于底面不可见的黑色面会把绿色面覆盖,原因很简单,你可以看到代码中黑色面的顶点数据是面5在绿色面2的后面, 黑色面和绿色面在x,y坐标上是有重叠的,黑色与绿色重叠部分会被后生成的像素覆盖。说到这里你应该明白gl.enable(gl.DEPTH_TEST);语句的作用,顶点装配、光栅化后片元是携带坐标信息的, x,y坐标对应的就是显示器平面,z值就是深度信息,执行该语句就可以识别出黑色面和绿色面的前后位置关系,所有位置靠前的会显示在屏幕上,靠后的像素会被隐覆盖掉。

    gl.enable()是WebGL的方法,该方法的功能就像它的名字一样,可以开启某项功能,参数gl.DEPTH_TEST表示深度功能。GPU是一块数字电路, 渲染管线的每一个环节都是一个带有某种功能的数字电路单元,只是有些支持可编程,有些不支持可编程,有些可以设置开启或关闭,有些完全不可设置,对于顶点、片元着色器是可以编程的,这两个处理器可以执行编译后的着色器语言, GPU深度检测功能是可设置的,默认是关闭的,再执行绘制命令之前执行代码gl.enable(gl.DEPTH_TEST);就可以打开GPU的深度测试功能。

    渲染管线图

    初学WebGL,关键在于建立渲染管线的概念,WebGL渲染顶点数据数据就像富士康的一条流水线一样,一个硬件单元负责一个功能。

    在前面几节课程中对WebGL渲染管线的讲解主要是顶点着色器和片元着色器两个硬件单元,还有顶点着色器和片元着色器两个着色器之间的图源装配、光栅器。这节课关于WebGL渲染管线又给大家引入了一种功能单元"深度测试",关于深度测试在整个流水线上所处的位置可以参考下图,在下面的WebGL渲染管线所表达的流水线中有些功能单元你可能还不了解,这没有关系,可以先不管,只要你通过这几节课程建立了WebGL渲染管线的概念,就算达到课程的目的了,有了渲染管线的概念,对于接下来WebGL的学习就会比较顺利了,这也是WebGL编程和javascript编程为什么稍有不同的原因,所有WebGL编程的特殊地方,都和WebGL渲染管线就像流水线一样完成渲染过程有关。

    在这里插入图片描述

    测试

    可以把所有的颜色都改为红色,然后执行绘制,你会发现并没有立体的视觉效果,生活中单色的物体也有立体感,这好像不符合生活常识,事实上生活中即使单色的物体在一个自然的光场环境下,它的反射到你眼睛的每个像素点颜色并不是单色是有微小的差异, 即使都是红色,两个像素的红色与红色R值分量会有微小的差异。

    白、蓝、绿处于其他三个面的前面,是可见面。可以把三个面设置为红色R分别为1、0.9、0.8来测试效果。你可以发现R值差异了0.1,你会有很强的立体感,其实你可以继续使用更小的差值,来测试你的眼睛视觉变化。这其实相当于手动编写颜色值,模拟自然界光场, 如果有兴趣可以学习下一节课程,如何模拟真实自然界的太阳光、灯光等各种类型光线在物体表面反射光场的分布,不仅不同的面会出现R值不同,一个面上的R值也会不同,呈现某种规律的变化,比如金属在阳光下会有局部高光现象。

    /**
     创建顶点颜色数组colorData
     **/
    var colorData = new Float32Array([
        1,0,0, 1,0,0, 1,0,0, 1,0,0, 1,0,0, 1,0,0,      //红色——面1
        .9,0,0, .9,0,0, .9,0,0, .9,0,0, .9,0,0, .9,0,0,//R=0.9——面2
        .8,0,0, .8,0,0, .8,0,0, .8,0,0, .8,0,0, .8,0,0,//R=0.8——面3
        1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0, 1,1,0,      //黄色——面4
        0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0, 0,0,0,      //黑色——面5
        1,0,0, 1,0,0, 1,0,0, 1,0,0, 1,0,0, 1,0,0,      //R=1——面6
    ]);
    
    展开全文
  • WebGL的时候照着书上打了一段代码,结果发现运行到网页上只有背景颜色,没有正方体,看控制台也没有错误信息输出,实在是不知道哪里错了... js的代码 var VSHADER_SOURCE= 'attribute vec4 a_Position;\n'+ '...
  • 第六节 WebGL画球算法

    千次阅读 2017-11-27 13:42:44
    很多学习WebGL的小伙伴,刚开始一直都是学怎么画立方体,等到立方体画的炉火纯青的时候,却被另一个东西难住了,那就是球。what,还会被一个球难住?下面就给大家介绍一种画球的算法: 我们的地球现在被划分为很多...

    学习交流欢迎加群:789723098,博主会将一些demo整理共享

    很多学习WebGL的小伙伴,刚开始一直都是学怎么画立方体,等到立方体画的炉火纯青的时候,却被另一个东西难住了,那就是球。what,还会被一个球难住?下面就给大家介绍一种画球的算法:

    我们的地球现在被划分为很多经线和纬线,如下图所示:

     

     

    由下面的图,我们来推导一下计算球面上点的坐标:

    假设图中圆的半径R=1,由图可算出红点的坐标:x = R*cos theta, y = R * sin theta;那角度theta又是怎样得到的呢?

    其实很简单,如果将一个球的经纬线都取为由5,再将其投影到平面圆,就得到在圆的边上的交点总共有10个,两个半圆,一半5个,其所对应的5个圆心角都是相等的,这个角即theta, 所以theta = PI/5, 如果取最中间的那条线为第一条线,那么第一条线上的交点所对的圆心角theta = 0; 如下图所示:

    代码实现如下:

     

    for (j = 0; j <= SPHERE_DIV; j++){//SPHERE_DIV为经纬线数
    
        aj = j * Math.PI/SPHERE_DIV;
        sj = Math.sin(aj);
        cj = Math.cos(aj);
        for(i = 0; i <= SPHERE_DIV; i++){
            ai = i * 2 * Math.PI/SPHERE_DIV;
            si = Math.sin(ai);
            ci = Math.cos(ai);
    
            points.push(si * sj);//point为顶点坐标
            points.push(cj);
            points.push(ci * sj);
        }
    }点击打开链接
    
    for(j = 0; j < SPHERE_DIV; j++){
        for(i = 0; i < SPHERE_DIV; i++){
            p1 = j * (SPHERE_DIV+1) + i;
            p2 = p1 + (SPHERE_DIV+1);
    
            indices.push(p1);//indices为顶点的索引
            indices.push(p2);
            indices.push(p1 + 1);
    
            indices.push(p1 + 1);
            indices.push(p2);
            indices.push(p2 + 1);
        }
    }

    本文只提供算法部分,绘制的部分可参考:点击打开链接(里面绘制了一个可交互的立方体),最后我实现的效果如下:

     

     

     

     

    展开全文
  • WebGL绘制的的旋转、平移、缩放的立方体动画,压缩包内的文件包括HTML、JavaScript可以打开直接运行。
  • React像素网格 包装简单组件。 npm install react-pixel-grid 用法 import PixelGrid from " react-pixel-grid " ; const r = " #f00 " ; const g =
  • 主要实现过程如下,先用FBO输出当前环境在立方体纹理中,再出当前立方体,最后球,并且把FBO关联的纹理贴在这个球面上。 开始WebGL时,最好有些OpenGL基础,在前面讲Obj完善与MD2时,大家可能已经发现了,因为...
  • 编写C++程序main.cpp,在程序中定义立方体的八个顶点坐标vertex_list数组和顶点序号数组index_list,通过函数glVertex3fv来实现立方体的线条绘制 #include<GL/glut.h> // 绘制立方体 // 将立方体的八个...
  • WegGL立方体装载机 WegGL多维数据集加载器是一个循环动画,其中包含使用threeJS制作的多维数据集。 演示版 版本 1.0.0
  • webgl绘制一个彩色旋转立方体

    千次阅读 热门讨论 2017-07-05 21:12:00
    上次绘制二维彩色矩形时讲到,二维是三维场景的特殊情况,所以由二维向三维拓展也并不难,webgl里面提供了三角形的方法,立方体有6个面,一个面由两个三角形组成,共计需要12个三角形,每个三角形又有3个顶点,故...
  • 主要实现过程如下,先用FBO输出当前环境在立方体纹理中,再出当前立方体,最后球,并且把FBO关联的纹理贴在这个球面上。 开始WebGL时,最好有些OpenGL基础,在前面讲Obj完善与MD2时,大家可能已经发现了,因为...
  • //物体,CubeGeometry创建的是立方体 var material = new THREE.MeshLambertMaterial( { color: 0x666666 } ); //材质 mesh = new THREE.Mesh( geometry,material); //mesh对象由物体和材质组成 mesh....
  • 立方体动画旋转时点光源计算处理1.demo效果 1.demo效果
  • 完整源代码网址: https://github.com/QQ3282292829/cube-animation
  • WebGL(2):绘制立方体

    2020-08-21 16:10:48
    实现的基本思路很简单,首先提供如上图所示立方体线框所有顶点的三维坐标,然后通过旋转矩阵对所有顶点进行旋转变换,最后调用绘制函数gl.drawArrays把所有点连成线渲染出来。 完整代码: <!DOCTYPE html>...
  • 通过鼠标点击选中立方体,选中立方体的某个面1.三维物体选中原理与实现步骤1.1物体选中原理1.2物体选中实现步骤1.2.1注册鼠标点击事件1.2.2顶点着色器作特定值设置处理1.2.3告诉顶点着色器修改颜色缓冲区1.2.4读取...
  • 绘制一个立方体WebGL旋转变换 本文是WebGL电子书的1.5节内容 实现的基本思路很简单,首先提供如上图所示立方体线框所有顶点的三维坐标,然后通过旋转矩阵对所有顶点进行旋转变换,最后调用绘制函数gl.drawArrays...
  • 文章目录前言一、整体代码以及...立方体的每一个面由两个三角形组成,每个三角形有三个顶点,所以每个月需要有六个顶点,那么顶点数据需要有 36 个,我们会发现其实我们只需要用 8 个顶点来进行绘制立方体,但是如何
  • 7.1 改进的立方体程序(上)    如上一章所提,直接以顶点的方式提供数据,让后用WebGL函数drawArrays绘图,会导致很大的内容占用和带宽。比如,立方体只有8个顶点,但为了使用drawArrays绘画它,我们足足提供了36...
  • WebGL之旅(十二)IBO绘制立方体

    千次阅读 2017-07-27 00:27:00
    立方体有6个面,每个面需要2个三角形,每个三角形3个定点,因此需要绘制12个三角形即36个点。但立方体本来只有6个定点定点就可以确定了,如何优化点这些冗余的数据呢?答案就是IBO(index buffer object),在一个vbo...
  • 绘制每个面指定颜色的立方体1.demo效果2.相关知识点2.1 每个面指定颜色原理2.2 定义顶点坐标、顶点颜色、顶点索引数组3.demo代码 1.demo效果 如上,绘制了不同面指定颜色的立方体 2.相关知识点 2.1 每个面指定颜色...
  • 通过顶点索引绘制渐变色的立方体1.demo效果2.相关知识点2.1 顶点索引原理2.2 gl.drawElements() 方法3.demo代码 1.demo效果 如上,通过顶点索引绘制出了一个渐变色的立方体 2.相关知识点 2.1 顶点索引原理 如上,...
  • 立方体绘制成红色(也可以是其他颜色); 判断鼠标点击位置的颜色 恢复立方体的颜色 示例由以上原理,当鼠标点击位置的颜色跟立方体重绘之后的颜色一致为红色时,则点击的位置就在立方体上。(如果背景色也为红色,...
  • 我们先来厘清几个事情: 一个立方体有6个面,每个面4个顶点,所以要绘制24个顶点。 每个顶点位置由3个数字表示,所以顶点信息是72个数字的数组。 每个顶点颜色由4个数字表示,所以颜色信息是96个数字的数组。 先看...
  • //将u_Clicked变量设置为true,将立方体绘制成纯色 gl.uniform1i(u_Clicked,1); draw(gl,n,currentAngle,viewProjectionMatrix,u_MvpMatrix); //通过readPixels来吸取点击位置的颜色 var pixels = new Uint8...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,328
精华内容 531
关键字:

webgl画立方体