Код не имеет большого смысла с первого взгляда.У вас есть внутренний и внешний цикл
Во внутреннем цикле этот код вычисляет вершину
let x = (this.outerRad + this.inner_rad * cos_slices) * cos_loops;
let y = (this.outerRad + this.inner_rad * cos_slices) * sin_loops;
let z = this.inner_rad * sin_slices;
this.vertices.push(x, y, z);
this.normals.push(x, y, z);
Но ничего внутри этих вычислений не меняется внутри внутреннего цикла
нормали не могут быть x, y, z (такими же, как позиции).
Также вам нужно сделать петли + 1 и срезы + 1 вершины.Вершины начинаются с вершины каждого цикла, срез будет иметь одинаковую позицию, но не будет иметь одинаковую координату текстуры.
Тогда, насколько ваши индексы идут каждый срез как (петли + 1) вершин, так что я думаю, чтоЦиклы в коде обратные.
Если бы это был я, а не цикл, основанный на углах, которые я бы зацикливал на основе циклов и срезов
for (slice = 0; slice < this.slices; ++slice) {
for (loop = 0; loop < this.loops; ++loop) {
...
Так вот еще одна версия
const o = {
slices: 8,
loops: 20,
inner_rad: 0.5,
outerRad: 2,
makeVerts() {
this.vertices = [];
this.indices = [];
this.normals = [];
this.texCoords = [];
for (let slice = 0; slice <= this.slices; ++slice) {
const v = slice / this.slices;
const slice_angle = v * 2 * Math.PI;
const cos_slices = Math.cos(slice_angle);
const sin_slices = Math.sin(slice_angle);
const slice_rad = this.outerRad + this.inner_rad * cos_slices;
for (let loop = 0; loop <= this.loops; ++loop) {
// x=(R+r·cos(v))cos(w)
// y=(R+r·cos(v))sin(w)
// z=r.sin(v)
const u = loop / this.loops;
const loop_angle = u * 2 * Math.PI;
const cos_loops = Math.cos(loop_angle);
const sin_loops = Math.sin(loop_angle);
const x = slice_rad * cos_loops;
const y = slice_rad * sin_loops;
const z = this.inner_rad * sin_slices;
this.vertices.push(x, y, z);
this.normals.push(
cos_loops * sin_slices,
sin_loops * sin_slices,
cos_slices);
this.texCoords.push(u);
this.texCoords.push(v);
}
}
// 0 1 2 3 4 5
// 6 7 8 9 10 11
// 12 13 14 15 16 17
const vertsPerSlice = this.loops + 1;
for (let i = 0; i < this.slices; ++i) {
let v1 = i * vertsPerSlice;
let v2 = v1 + vertsPerSlice;
for (let j = 0; j < this.loops; ++j) {
this.indices.push(v1);
this.indices.push(v1 + 1);
this.indices.push(v2);
this.indices.push(v2);
this.indices.push(v1 + 1);
this.indices.push(v2 + 1);
v1 += 1;
v2 += 1;
}
}
//this.indices = undefined;
},
};
o.makeVerts();
// -------------- ignore below this line -------------
const gl = document.querySelector('canvas').getContext('webgl');
const m4 = twgl.m4;
const vs = `
attribute vec4 position;
attribute vec3 normal;
attribute vec2 texcoord;
uniform mat4 u_matrix;
varying vec3 v_normal;
void main() {
gl_Position = u_matrix * position;
v_normal = normal; // just for testing
//v_normal = vec3(texcoord, 0); // comment in to see texcoords
gl_PointSize = 3.0;
}
`;
const fs = `
precision highp float;
varying vec3 v_normal;
void main() {
gl_FragColor = vec4(v_normal * 0.5 + 0.5, 1);
}
`;
const programInfo = twgl.createProgramInfo(gl, [vs, fs]);
const bufferInfo = twgl.createBufferInfoFromArrays(gl, {
position: o.vertices,
normal: o.normals,
texcoord: o.texCoords,
indices: o.indices,
});
twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);
gl.useProgram(programInfo.program);
function render(time) {
gl.enable(gl.DEPTH_TEST);
gl.enable(gl.CULL_FACE);
let mat = m4.perspective(
45 * Math.PI / 180, // fov
2, // aspect
0.1, // near
100, // far
);
mat = m4.translate(mat, [0, 0, -7]);
mat = m4.rotateY(mat, time * 0.001);
mat = m4.rotateX(mat, time * 0.0005);
twgl.setUniforms(programInfo, { u_matrix: mat });
twgl.drawBufferInfo(gl, bufferInfo);
//twgl.drawBufferInfo(gl, bufferInfo, gl.POINTS);
requestAnimationFrame(render);
}
requestAnimationFrame(render);
<canvas></canvas>
<script src="https://twgljs.org/dist/4.x/twgl-full.min.js"></script>