在 webGL 中使用 Nurbs Surface,索引总是错误的,除非我使用角点而不是控制点

我正在尝试使 Verb 的 Nurbs Surface 与 vanilla webGL 一起使用(尽管使用 webgl-utils 有点作弊)。PIXI.js 也产生相同的结果,角起作用,但控制点不起作用。

我可以使用角来做到这一点verb.geom.NurbsSurface.byCorners,但是当我尝试使用verb.geom.NurbsSurface.byKnotsControlPointsWeights表面的控制点时会变得混乱,很可能索引是错误的!

有一个在 THREE.js 中使用动词的示例,但即使我尝试示例中使用的相同函数,结果也是相同的。

我已经根据角点注释掉了这个函数,你可以看到它是有效的。我记录了控制台srf,从_data对象中我可以看到 Verb 正在引擎盖下生成这些控制点,但如果我尝试使用它们,相同的点将不起作用byKnotsControlPointsWeights

除了一个可行的解决方案之外,我还想了解为什么代码不起作用,以及 THREE.js 中的哪一部分与我的普通代码不同,这使得它可以与 THREE 一起使用,但在这里不行。

body { margin: 0; }

<script src="https://webglfundamentals.org/webgl/resources/webgl-utils.js"></script>

<script src="https://unpkg.com/verb-nurbs-web@2.1.3/build/js/verb.js"></script>

<script src="https://unpkg.com/lodash@4.17.20/lodash.js"></script>

<canvas id="c"></canvas>


拉莫斯之舞
浏览 102回答 1
1回答

湖上湖

我不知道它应该是什么样子,但代码在调用时传递了 2 作为位置的大小gl.vertexAttribPointer,但数据有 3 (x, y, z)。将其设置为 3 肯定会得到不同的图像。仍然需要确保 UV 的大小设置为 2const flatten = _.flatten;// const corners = [//&nbsp; &nbsp;[100, 100], // top left//&nbsp; &nbsp;[450, 50], // top right//&nbsp; &nbsp;[650, 650], // bottom right//&nbsp; &nbsp;[0, 750] // bottom left// ];// var srf = verb.geom.NurbsSurface.byCorners(...corners);const degreeU = 3;const degreeV = 3;const knotsU = [0, 0, 0, 0, 1, 1, 1, 1];const knotsV = [0, 0, 0, 0, 1, 1, 1, 1];const controlPoints = [&nbsp; [&nbsp; &nbsp; [0, 0, 1],&nbsp; &nbsp; [0, 249, 1],&nbsp; &nbsp; [0, 500, 1],&nbsp; &nbsp; [0, 750, 1]&nbsp; ],&nbsp; [&nbsp; &nbsp; [249, 0, 1],&nbsp; &nbsp; [249, 249, 1],&nbsp; &nbsp; [249, 500, 1],&nbsp; &nbsp; [249, 750, 1]&nbsp; ],&nbsp; [&nbsp; &nbsp; [500, 0, 1],&nbsp; &nbsp; [500, 249, 1],&nbsp; &nbsp; [500, 500, 1],&nbsp; &nbsp; [500, 750, 1]&nbsp; ],&nbsp; [&nbsp; &nbsp; [750, 0, 1],&nbsp; &nbsp; [750, 249, 1],&nbsp; &nbsp; [750, 500, 1],&nbsp; &nbsp; [750, 750, 1]&nbsp; ]];var srf = verb.geom.NurbsSurface.byKnotsControlPointsWeights(&nbsp; degreeU,&nbsp; degreeV,&nbsp; knotsU,&nbsp; knotsV,&nbsp; controlPoints);// tesselate the nurface and get the trianglesvar tess = srf.tessellate();console.log(tess);const vertexSource = `&nbsp; attribute vec2 a_position;&nbsp; attribute vec2 a_texCoord;&nbsp; uniform vec2 u_resolution;&nbsp; varying vec2 v_texCoord;&nbsp; void main() {&nbsp; &nbsp; vec2 zeroToOne = a_position / u_resolution;&nbsp; &nbsp; vec2 zeroToTwo = zeroToOne * 2.0;&nbsp; &nbsp; vec2 clipSpace = zeroToTwo - 1.0;&nbsp; &nbsp; gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);&nbsp; &nbsp; v_texCoord = a_texCoord;&nbsp; }`;const fragmentSource = `&nbsp; precision mediump float;&nbsp; // our texture&nbsp; uniform sampler2D u_image;&nbsp; // the texCoords passed in from the vertex shader.&nbsp; varying vec2 v_texCoord;&nbsp; void main() {&nbsp; &nbsp; gl_FragColor = texture2D(u_image, v_texCoord);&nbsp; }`;function main() {&nbsp; var image = new Image();&nbsp; image.crossOrigin = "anonymous";&nbsp; image.onload = function () {&nbsp; &nbsp; render(image);&nbsp; };&nbsp; image.src = "https://pixijs.io/examples/examples/assets/bg_scene_rotate.jpg";}function render(image) {&nbsp; // Get A WebGL context&nbsp; /** @type {HTMLCanvasElement} */&nbsp; var canvas = document.getElementById("c");&nbsp; var gl = canvas.getContext("webgl");&nbsp; // setup GLSL program&nbsp; var program = webglUtils.createProgramFromSources(gl, [&nbsp; &nbsp; vertexSource,&nbsp; &nbsp; fragmentSource&nbsp; ]);&nbsp; // look up where the vertex data needs to go.&nbsp; var positionLocation = gl.getAttribLocation(program, "a_position");&nbsp; var texcoordLocation = gl.getAttribLocation(program, "a_texCoord");&nbsp; // Create a buffer to put three 2d clip space points in&nbsp; var positionBuffer = gl.createBuffer();&nbsp; // Bind it to ARRAY_BUFFER (think of it as ARRAY_BUFFER = positionBuffer)&nbsp; gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);&nbsp; // Set a rectangle the same size as the image.&nbsp; gl.bufferData(&nbsp; &nbsp; gl.ARRAY_BUFFER,&nbsp; &nbsp; new Float32Array(flatten(tess.points)),&nbsp; &nbsp; gl.STATIC_DRAW&nbsp; );&nbsp; // provide texture coordinates for the rectangle.&nbsp; var texcoordBuffer = gl.createBuffer();&nbsp; gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer);&nbsp; gl.bufferData(&nbsp; &nbsp; gl.ARRAY_BUFFER,&nbsp; &nbsp; new Float32Array(flatten(tess.uvs)),&nbsp; &nbsp; gl.STATIC_DRAW&nbsp; );&nbsp; // Create a texture.&nbsp; var texture = gl.createTexture();&nbsp; gl.bindTexture(gl.TEXTURE_2D, texture);&nbsp; // Set the parameters so we can render any size image.&nbsp; gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);&nbsp; gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);&nbsp; gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);&nbsp; gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);&nbsp; // Upload the image into the texture.&nbsp; gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);&nbsp; // lookup uniforms&nbsp; var resolutionLocation = gl.getUniformLocation(program, "u_resolution");&nbsp; // resize canvas to display size&nbsp; canvas.width = window.innerWidth;&nbsp; canvas.height = window.innerHeight;&nbsp; // Tell WebGL how to convert from clip space to pixels&nbsp; gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);&nbsp; // Clear the canvas&nbsp; gl.clearColor(0, 0, 0, 0);&nbsp; gl.clear(gl.COLOR_BUFFER_BIT);&nbsp; // Tell it to use our program (pair of shaders)&nbsp; gl.useProgram(program);&nbsp; // index buffer&nbsp; const indexBuffer = gl.createBuffer();&nbsp; // make this buffer the current 'ELEMENT_ARRAY_BUFFER'&nbsp; gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);&nbsp; // Fill the current element array buffer with data&nbsp; const indices = new Uint16Array(flatten(tess.faces));&nbsp; gl.bufferData(&nbsp; &nbsp; gl.ELEMENT_ARRAY_BUFFER,&nbsp; &nbsp; new Uint16Array(indices),&nbsp; &nbsp; gl.STATIC_DRAW&nbsp; );&nbsp; // Turn on the position attribute&nbsp; gl.enableVertexAttribArray(positionLocation);&nbsp; // Bind the position buffer.&nbsp; gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);&nbsp; // Tell the position attribute how to get data out of positionBuffer (ARRAY_BUFFER)&nbsp; var size = 3; // 2 components per iteration&nbsp; var type = gl.FLOAT; // the data is 32bit floats&nbsp; var normalize = false; // don't normalize the data&nbsp; var stride = 0; // 0 = move forward size * sizeof(type) each iteration to get the next position&nbsp; var offset = 0; // start at the beginning of the buffer&nbsp; gl.vertexAttribPointer(&nbsp; &nbsp; positionLocation,&nbsp; &nbsp; size,&nbsp; &nbsp; type,&nbsp; &nbsp; normalize,&nbsp; &nbsp; stride,&nbsp; &nbsp; offset&nbsp; );&nbsp; // Turn on the texcoord attribute&nbsp; gl.enableVertexAttribArray(texcoordLocation);&nbsp; // bind the texcoord buffer.&nbsp; gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer);&nbsp; gl.vertexAttribPointer(&nbsp; &nbsp; texcoordLocation,&nbsp; &nbsp; 2, //size,&nbsp; &nbsp; type,&nbsp; &nbsp; normalize,&nbsp; &nbsp; stride,&nbsp; &nbsp; offset&nbsp; );&nbsp; // set the resolution&nbsp; gl.uniform2f(resolutionLocation, gl.canvas.width, gl.canvas.height);&nbsp; // Draw the rectangle.&nbsp; gl.drawElements(gl.TRIANGLES, indices.length, gl.UNSIGNED_SHORT, 0);}main();body { margin: 0; }<script src="https://webglfundamentals.org/webgl/resources/webgl-utils.js"></script><script src="https://unpkg.com/verb-nurbs-web@2.1.3/build/js/verb.js"></script><script src="https://unpkg.com/lodash@4.17.20/lodash.js"></script><canvas id="c"></canvas>
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript