Why don't my shaders work for trapezoids polygons?

前端 未结 1 1144
日久生厌
日久生厌 2021-01-28 09:03

I need to draw parts of a texture on trapezoids polygons. (old school fake-3D race game, the road is made of these trapezoids and I want to apply a texture on them.)

But

1条回答
  •  夕颜
    夕颜 (楼主)
    2021-01-28 09:48

    Looking at the examples you linked to you need to provide 3D texture coordinates. So instead of UVs like

     0, 0,
     0, 1,
     1, 0,
     1, 1,
    

    They need to each be multiplied by the absolute value of the X coordinate of the trapizoid's points and then that absolute value of X needs to be the 3rd coordinate

     0 * X0, 0 * X0, X0,
     0 * X1, 1 * X1, X1,
     1 * X2, 0 * X2, X2,
     1 * X3, 1 * X3, X3,
    

    This ends up with the same texture coordinates because texture2DProj divides the xy of each coordinate by z but it changes how the texture coordinate is interpolated.

    You can provide that those texture coordinates by supplying them manually and putting them in a buffer or you can do it by calculating them in the vertex shader

    attribute vec4 position;
    attribute vec2 texcoord;
    
    uniform mat4 u_matrix;
    
    varying vec3 v_texcoord;
    
    void main() {
      gl_Position = u_matrix * position;
      v_texcoord = vec3(texcoord.xy, 1) * abs(position.x);
    }
    

    example

    'use strict';
    
    /* global twgl, m4, requestAnimationFrame, document */
    
    const m4 = twgl.m4;
    const gl = document.querySelector('canvas').getContext('webgl');
    
    const vs = `
    attribute vec4 position;
    attribute vec2 texcoord;
    
    uniform mat4 u_matrix;
    
    varying vec3 v_texcoord;
    
    void main() {
      gl_Position = u_matrix * position;
      v_texcoord = vec3(texcoord.xy, 1) * abs(position.x);
    }
    `;
    
    const fs = `
    precision highp float;
    
    varying vec3 v_texcoord;
    
    uniform sampler2D tex;
    
    void main() {
      gl_FragColor = texture2DProj(tex, v_texcoord);
    }
    `;
    
    // compile shader, link, look up locations
    const programInfo = twgl.createProgramInfo(gl, [vs, fs]);
    
    // make some vertex data
    const W0 = 1;
    const W1 = 0.5;
    const bufferInfo = twgl.createBufferInfoFromArrays(gl, {
      position: {
        numComponents: 2,
        data: [
          -1, -1,
           1, -1,
         -.5,  1,
           
           1, -1,
          .5,  1,
         -.5,  1,
        ],
      },
      texcoord: [
         0,  0,  
         1,  0,
         0,  1,
    
         1,  0,
         1,  1,
         0,  1,
      ],
    });
    
    const tex = twgl.createTexture(gl, {
      src: [
        0xC0, 0x80, 0xC0, 0x80,
        0x80, 0xC0, 0x80, 0xC0,
        0xC0, 0x80, 0xC0, 0x80,
        0x80, 0xC0, 0x80, 0xC0,
      ],
      format: gl.LUMINANCE,
      minMag: gl.NEAREST,
    });
    
    function render(time) {
      time *= 0.001;
      
      gl.useProgram(programInfo.program);
    
      // calls gl.bindBuffer, gl.enableVertexAttribArray, gl.vertexAttribPointer
      twgl.setBuffersAndAttributes(gl, programInfo, bufferInfo);
    
      // calls gl.activeTexture, gl.bindTexture, gl.uniformXXX
      twgl.setUniforms(programInfo, {
        u_matrix: m4.rotationZ(time),
      });  
    
      // calls gl.drawArrays or gl.drawElements
      twgl.drawBufferInfo(gl, bufferInfo);
      
      requestAnimationFrame(render);
    }
    requestAnimationFrame(render);
    
    

    0 讨论(0)
提交回复
热议问题