在webGL中渲染圆环时出现的问题

问题描述 投票:0回答:3

我正在编写一个应该在webgl中绘制3D参数形状的程序。我目前拥有的代码似乎(大部分)适用于球体,但是当我切换出用于查找圆环的x,y和z的方程式时,仅呈现圆环的上半部分(在xy中飞机)。当仅使用2d canvas上下文而不使用任何webgl时,我拥有的所有参数方程式(对于球体,圆环和圆柱体)都会起作用。但是,使用webgl时似乎存在问题。除了仅渲染一半圆环的问题之外,用于渲染圆柱体的方程式也不会渲染任何内容。

什么会导致只呈现一半的圆环?渲染参数形状的代码如下:

            var latitudeBands = 30;
            var longitudeBands = 30;
            var radius = 0.5;

            var vertexPositionData = [];
            var normalData = [];
            var textureCoordData = [];
            var indexData = [];

            for (var latNumber = 0; latNumber <= latitudeBands; latNumber++)                     
              {  var theta = latNumber * Math.PI / latitudeBands;
                var sinTheta = Math.sin(theta);
                var cosTheta = Math.cos(theta);

                for (var longNumber = 0; longNumber <= longitudeBands; longNumber++) {
                    var phi = longNumber * 2 * Math.PI / longitudeBands;
                    var sinPhi = Math.sin(phi);
                    var cosPhi = Math.cos(phi);

                    //Equation used for sphere     
                    //var x =  Math.cos(phi) * Math.cos(theta);
                    //var y = Math.cos(phi) * Math.sin(theta);
                    //var z = Math.sin(phi);

                    //Equation used for torus
                    var x = (1 + radius * Math.cos(phi)) * Math.cos(theta);
                    var y = (1 + radius * Math.cos(phi)) * Math.sin(theta);
                    var z = radius * Math.sin(phi);

                  //Equation used for cylinder
                  //var x =  Math.cos(theta);
                  //var y = Math.sin(theta);
                  //var z = 2 * latNumber - 1;


                    var u = 1 - (longNumber / longitudeBands);
                    var v = 1 - (latNumber / latitudeBands);

                    normalData.push(x);
                    normalData.push(y);
                    normalData.push(z);
                    textureCoordData.push(u);
                    textureCoordData.push(v);
                    vertexPositionData.push(radius * x);
                    vertexPositionData.push(radius * y);
                    vertexPositionData.push(radius * z)
                }
            }

            for (var latNumber = 0; latNumber < latitudeBands; latNumber++) {
                for (var longNumber = 0; longNumber < longitudeBands; longNumber++) {
                    var first = (latNumber * (longitudeBands + 1)) + longNumber;
                    var second = first + longitudeBands + 1;
                    indexData.push(first);
                    indexData.push(second);
                    indexData.push(first + 1);
                    indexData.push(second);
                    indexData.push(second + 1);
                    indexData.push(first + 1);
                }
            }

        moonVertexPositionBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, moonVertexPositionBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexPositionData), gl.STATIC_DRAW);
        moonVertexPositionBuffer.itemSize = 3;
        moonVertexPositionBuffer.numItems = vertexPositionData.length / 3;

        moonVertexIndexBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, moonVertexIndexBuffer);
        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indexData), gl.STATIC_DRAW);
        moonVertexIndexBuffer.itemSize = 1;
        moonVertexIndexBuffer.numItems = indexData.length;
javascript html graphics opengl-es webgl
3个回答
1
投票

您的球面仰角范围仅为PI(从极点到极点),但圆环的范围是2 * PI;因此

theta = latNumber * Math.PI / latitudeBands

应该是

theta = latNumber * 2 * Math.PI / latitudeBands

请参见WebGL Torus Example


1
投票

老实说,对于这些类型的问题,最有可能的错误来自几何图形生成代码。我建议参考出色的THREE.js源代码以检查差异。托罗斯生成代码here

如果将来需要,您可以找到其他几何图形here的代码。


0
投票

法线不应与半径相乘,因为法线必须为单一长度。以下是正确的法线:

norm_x = Math.cos(theta) * Math.cos(phi);  
norm_y = Math.cos(theta) * Math.sin(phi);  
norm_z = Math.sin(theta);  
© www.soinside.com 2019 - 2024. All rights reserved.