gpt4 book ai didi

3d - 在 webgl 中绘制圆环

转载 作者:行者123 更新时间:2023-12-02 19:51:22 25 4
gpt4 key购买 nike

我正在尝试使用 webgl 渲染圆环。我正在使用第三方库,这使得这个过程变得更容易:我只需要声明各个顶点、它们的法线和它们的索引。每个 3 个索引的元组绘制一个三角形,顶点必须遵循右手定则。

到目前为止,这就是我所拥有的:

 this.vertices = [];
this.indices = [];
this.normals = [];
this.texCoords = [];

let slices_angle = 0;
let loops_angle = 0;
let slices_delta = (2 * Math.PI) / this.slices;
let loops_delta = (2 * Math.PI) / this.loops;
let abc = 0;

while (slices_angle < 2 * Math.PI + slices_delta) {
let cos_slices = Math.cos(slices_angle);
let sin_slices = Math.sin(slices_angle);
let cos_loops = Math.cos(loops_angle);
let sin_loops = Math.sin(loops_angle);

while (loops_angle < 2 * Math.PI + loops_delta) {
// x=(R+r·cos(v))cos(w)
// y=(R+r·cos(v))sin(w)
// z=r.sin(v)

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

// this.texCoords.push(j / this.slices);
// this.texCoords.push(i / this.stacks);

loops_angle += loops_delta;
}

slices_angle += slices_delta;
}

for (var i = 0; i < this.loops; i++) {
let v1 = i * (this.slices + 1);
let v2 = v1 + this.slices + 1;

for (var j = 0; j < this.slices; j++) {

this.indices.push(v1);
this.indices.push(v2);
this.indices.push(v1 + 1);

this.indices.push(v1 + 1);
this.indices.push(v2);
this.indices.push(v2 + 1);

v1++;
v2++;
}
}

我在该网站的帮助下声明了顶点的坐标,但我在索引方面遇到了问题。

example

最佳答案

该代码乍一看没有多大意义。你有一个内循环和外循环

在内部循环中,此代码计算一个顶点

           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 个顶点。每个循环的顶点起始顶点,切片将具有相同的位置,但不会具有相同的纹理坐标。

然后,就你的索引而言,每个切片都是 (loops + 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>

关于3d - 在 webgl 中绘制圆环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58101753/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com