0

I am trying to wrap an object with texture. The object is Quadrilateral with different side lengths. But when I wrap the object with texture, the texture is not stretching equally.

const canvas = document.querySelector('canvas');
canvas.width = 600;
canvas.height = 400;
const gl = canvas.getContext('webgl');
const mat4 = glMatrix.mat4

if (!gl) {
    throw new Error('WebGL not supported');
}

xf = .5
ot = 1.2

const vertexData = [
    // Front
    -ot, xf, xf, // top left
    ot, xf, xf, // top right
    -xf, -xf, xf, // bottom left
    -xf, -xf, xf, // bottom left
    ot, xf, xf, // top right
    xf, -xf, xf, // bottom right
];

const uvData = [
    0, 0, ot,
    ot, 0, ot,
    0, xf, xf,
    0, xf, xf,
    ot, 0, ot,
    xf, xf, xf,
];

const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexData), gl.STATIC_DRAW);

const uvBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, uvBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(uvData), gl.STATIC_DRAW);


// RESOURCE LOADING
// ================

function loadTexture(url) {
    const texture = gl.createTexture();
    const image = new Image();
    requestCORSIfNotSameOrigin(image, url)


    image.onload = e => {
        gl.bindTexture(gl.TEXTURE_2D, texture);

        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);

        gl.generateMipmap(gl.TEXTURE_2D);
    };

    image.src = url;
    return texture;
}



const brick = loadTexture(`https://i.ibb.co/z7YGMdK/rsz-1rsz-11uv-maptemplate.jpg`);

gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, brick);

// SHADER PROGRAM
// ==============
let uniformLocations;
(function shaderProgram() {
    const vertexShader = gl.createShader(gl.VERTEX_SHADER);
    gl.shaderSource(vertexShader, `
    precision mediump float;

    attribute vec3 position;
    attribute vec3 uv;

    varying vec3 vUV;

    uniform mat4 matrix;

    void main() {
        gl_Position = matrix * vec4(position, 1);
        vUV = uv;
    }
    `);
    gl.compileShader(vertexShader);

    const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(fragmentShader, `
    precision mediump float;

    varying vec3 vUV;
    uniform sampler2D textureID;

    void main() {
        gl_FragColor = texture2DProj(textureID, vUV);
    }
    `);
    gl.compileShader(fragmentShader);
    console.log(gl.getShaderInfoLog(fragmentShader));

    const program = gl.createProgram();
    gl.attachShader(program, vertexShader);
    gl.attachShader(program, fragmentShader);

    gl.linkProgram(program);

    const positionLocation = gl.getAttribLocation(program, `position`);
    gl.enableVertexAttribArray(positionLocation);
    gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
    gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);

    const uvLocation = gl.getAttribLocation(program, `uv`);
    gl.enableVertexAttribArray(uvLocation);
    gl.bindBuffer(gl.ARRAY_BUFFER, uvBuffer);
    gl.vertexAttribPointer(uvLocation, 3, gl.FLOAT, false, 0, 0);

    gl.useProgram(program);
    gl.enable(gl.DEPTH_TEST);

    uniformLocations = {
        matrix: gl.getUniformLocation(program, `matrix`),
        textureID: gl.getUniformLocation(program, 'textureID'),
    };

    gl.uniform1i(uniformLocations.textureID, 0);
})();


// MATRICES
// ========
const modelMatrix = mat4.create();
const viewMatrix = mat4.create();
const projectionMatrix = mat4.create();
mat4.perspective(projectionMatrix, 
    75 * Math.PI / 240, // vertical field-of-view (angle, radians)
    canvas.width / canvas.height, // aspect W/H
    1e-4, // near cull distance
    1e4 // far cull distance
);

const mvMatrix = mat4.create();
const mvpMatrix = mat4.create();

mat4.translate(viewMatrix, viewMatrix, [0, 0.1, 2]);
mat4.invert(viewMatrix, viewMatrix);


// ANIMATION LOOP
// ==============

function animate() {
    requestAnimationFrame(animate);

    mat4.rotateX(modelMatrix, modelMatrix, 0);
    mat4.rotateY(modelMatrix, modelMatrix, 0);

    mat4.multiply(mvMatrix, viewMatrix, modelMatrix);
    mat4.multiply(mvpMatrix, projectionMatrix, mvMatrix);
    gl.uniformMatrix4fv(uniformLocations.matrix, false, mvpMatrix);
    gl.drawArrays(gl.TRIANGLES, 0, vertexData.length / 3);
}

animate();

function requestCORSIfNotSameOrigin(img, url) {
    if ((new URL(url, window.location.href)).origin !== window.location.origin) {
      img.crossOrigin = "";
    }
  }
<canvas id="canvas"></canvas>
<!--
for most samples webgl-utils only provides shader compiling/linking and
canvas resizing because why clutter the examples with code that's the same in every sample.
See https://webgl2fundamentals.org/webgl/lessons/webgl-boilerplate.html
and https://webgl2fundamentals.org/webgl/lessons/webgl-resizing-the-canvas.html
for webgl-utils, m3, m4, and webgl-lessons-ui.
-->
<script src="https://webgl2fundamentals.org/webgl/resources/webgl-utils.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gl-matrix@3/gl-matrix.js"></script>

This is the correct formula for the snippet above. And working well as expected.

xf = .5
ot = 1.2

const vertexData = [
    // Front
    -ot, xf, xf, // top left
    ot, xf, xf, // top right
    -xf, -xf, xf, // bottom left
    -xf, -xf, xf, // bottom left
    ot, xf, xf, // top right
    xf, -xf, xf, // bottom right
];

const uvData = [
    0, 0, 1 * ot,
    1 * ot, 0, 1 * ot,
    0, 1 * xf, 1 * xf,
    0, 1 * xf, 1 * xf,
    1 * ot, 0, ot,
    1* xf, 1 * xf, 1 * xf,
];

But when I use a different shaped object I could not find a general formula for different shape objects. The example below for a different shape object.

The texture must be wrapped like this

Texture must be wrapped like this

Instead, it's wrapping like this

Instead, it's wrapping like this

I used texture2Dproj and gave the z-axis. But I could not find the general formula and failed to project it correctly

I used texture2DProj and gave the z-axis. But I could not find the general formula and failed to project it correctly

Is there a general formula for different shaped objects like this Thank you in advance.

vehbi
  • 1
  • 2
  • You might find [this](https://stackoverflow.com/questions/56915103/why-dont-my-shaders-work-for-trapezoids-polygons) useful – gman Jun 02 '20 at 06:45
  • Thank you for your help. It's looks like my problem. I will try it. – vehbi Jun 02 '20 at 07:43

0 Answers0