Javascript 在webGL中渲染圆环体时出现的问题
我正在写一个程序,应该在webgl中绘制3D参数化形状。我目前使用的代码似乎(主要)适用于球体,但当我切换出用于计算圆环体x、y和z的方程式时,只有圆环体的上半部分被渲染(在x-y平面中)。当仅使用2d画布上下文而不使用任何webgl时,我拥有的所有参数方程(对于球体、圆环体和圆柱体)都有效;然而,当使用webgl时,似乎存在一个问题。除了只渲染半个圆环体的问题外,用于渲染圆柱体的方程式不会渲染任何东西 是什么导致只有一半的圆环体被渲染?渲染参数化形状的代码如下所示:Javascript 在webGL中渲染圆环体时出现的问题,javascript,html,graphics,opengl-es,webgl,Javascript,Html,Graphics,Opengl Es,Webgl,我正在写一个程序,应该在webgl中绘制3D参数化形状。我目前使用的代码似乎(主要)适用于球体,但当我切换出用于计算圆环体x、y和z的方程式时,只有圆环体的上半部分被渲染(在x-y平面中)。当仅使用2d画布上下文而不使用任何webgl时,我拥有的所有参数方程(对于球体、圆环体和圆柱体)都有效;然而,当使用webgl时,似乎存在一个问题。除了只渲染半个圆环体的问题外,用于渲染圆柱体的方程式不会渲染任何东西 是什么导致只有一半的圆环体被渲染?渲染参数化形状的代码如下所示: v
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;
var纬度带=30;
var longitudeBands=30;
var半径=0.5;
var vertexPositionData=[];
var normalData=[];
var textureCoordData=[];
var indexData=[];
对于(var latNumber=0;latNumber老实说,对于这些类型的问题,最有可能的错误来自几何体生成代码。我建议参考优秀的THREE.js源代码来检查差异。Toros生成代码
如果将来需要,您可以找到其他几何图形生成的代码。球体的仰角范围仅为PI(从极点到极点),但
环面的范围是2*PI;因此
theta = latNumber * Math.PI / latitudeBands
应该是
theta = latNumber * 2 * Math.PI / latitudeBands
请参见。圆环体的法线不需要从中心计算,就像球体的法线与x、y、z坐标相同一样。创建面后,最好计算法线。每个顶点的法线是使用该顶点的所有面法线的平均值。法线用于剔除背面。将材质设置为双面很可能会显示所有面,但使用错误的法线进行着色将不正确。@Blindman67我认为只有在使用照明时才需要法线?在这种情况下,我不使用任何法线,因此我不确定法线的计算是否会影响渲染。我只是用我正在发送到GPU的数组。这正是错误所在,谢谢!您知道学习如何在WebGL中绘制高级形状的最佳web资源是什么吗?