在webGL中渲染圆环时出现问题 [英] Issue when rendering a torus in webGL

查看:202
本文介绍了在webGL中渲染圆环时出现问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个应该在webgl中绘制3D参数形状的程序。我目前使用的代码似乎对一个球体起作用(主要是),但是当我将用于查找x,y和z的方程转换为圆环时,只有圆环的上半部分被渲染(在xy平面)。当没有任何webgl的情况下使用2d canvas背景时,所有的参数方程(对于球体,圆环体和圆柱体)都可以工作;但是,当使用webgl时,似乎存在问题。此外,只渲染圆环的一半的问题,用于渲染圆柱体的等式不会呈现任何东西。

什么可能导致只有一半的圆环被渲染?渲染参数形状的代码如下:

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

var vertexPositionData = [];
var normalData = [];
var textureCoordData = [];
var indexData = []; (var latNumber = 0; latNumber <= latitudeBands; latNumber ++)
{var theta = latNumber * Math.PI / latitudeBands;

;
var sinTheta = Math.sin(theta);
var cosTheta = Math.cos(theta); (var longNumber = 0; longNumber< = longitudeBands; longNumber ++){
var phi = longNumber * 2 * Math.PI / longitudeBands;

;
var sinPhi = Math.sin(phi);
var cosPhi = Math.cos(phi);

//用于球面的方程
// var x = Math.cos(phi)* Math.cos(theta);
// var y = Math.cos(phi)* Math.sin(theta);
// var z = Math.sin(phi);

//用于环面的方程
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);

//用于圆柱的等式
// 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); (var latNumber = 0; latNumber< latitudeBands; latNumber ++){
for(
)vertexPositionData.push(radius * z)
}
}

(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;


解决方案

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

  theta = latNumber * Math.PI / latitudeBands 

应该是

  theta = latNumber * 2 * Math.PI / latitudeBands 

请参阅 WebGL圆环示例


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;

解决方案

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.

这篇关于在webGL中渲染圆环时出现问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆