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