Issue when rendering a torus in webGL

青春壹個敷衍的年華 提交于 2020-01-17 04:57:31

问题


I'm writing a program that is supposed to draw 3D parametric shapes in webgl. The code I have currently seems to work (mostly) for a sphere, but when I switch out the equations used to find x, y, and z, for a torus, only the top half of the torus is being rendered (in the x-y plane). All of the parametric equations I have (for a sphere, a torus, and a cylinder) work when just the 2d canvas context is used without any webgl; however, when webgl is used, there seems to be a problem. In addition the problem with only rendering half of the torus, the equation used to render the cylinder doesn't render anything.

What could be causing only half of the torus to be rendered? The code for rendering the parametric shapes is below:

            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;

回答1:


Your elevation angle range for a sphere is only PI (from pole to pole), but the range is 2*PI for a torus; Thus

theta = latNumber * Math.PI / latitudeBands

should be

theta = latNumber * 2 * Math.PI / latitudeBands

See WebGL Torus Example.




回答2:


Honestly for these type of problems the most likely error arise from the geometry generation code. I suggest consult the excellent THREE.js source code to check for discrepancies. Toros generation code here.

You can find code for other geometry generation here should you need them in the future.



来源:https://stackoverflow.com/questions/33860167/issue-when-rendering-a-torus-in-webgl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!