drawElements 纹理花的看不清

发布于 2023-04-03 13:51:32

微信截图_20230403140035.png
<script src="glMatrix-0.9.6.min.js"></script>

<script>
    let vertexstring = `
    attribute vec4 a_position;
    uniform   mat4    proj;
    attribute vec2 outUV;
    varying vec2 inUV;
    void main(void){
        gl_Position = proj *  a_position;
        inUV = outUV;
    }
    `;
    let fragmentstring = `
    precision mediump float;
    uniform sampler2D texture;
    uniform sampler2D texture1;
    uniform float anim;
    varying vec2 inUV;
    void main(void){
      vec4 color1 =texture2D(texture,inUV);
      vec4 color2 =texture2D(texture1, vec2(inUV.x + anim, inUV.y));

      gl_FragColor = color1 + color2 ;
    }
    `;
    var projMat4 = mat4.create();
    var webgl;
    var uniformTexture = 0;
    var uniformTexture1 = 0;
    var uniformAnim = 0;
    var count = 0;
    var texture0;
    var texture1;
    function webglStart() {
        init();
        tick();
    }
    function tick() {
        request(tick)
        draw();
    };
    function init() {
        initWebgl();
        initShader();
        initBuffer();

    }
    function initWebgl() {
        let webglDiv = document.getElementById('myCanvas');
        webgl = webglDiv.getContext("webgl");
        webgl.viewport(0, 0, webglDiv.clientWidth, webglDiv.clientHeight);
        mat4.ortho(0, webglDiv.clientWidth, webglDiv.clientHeight, 0, -1.0, 1.0, projMat4)
    }
    function initShader() {

        let vsshader = webgl.createShader(webgl.VERTEX_SHADER);
        let fsshader = webgl.createShader(webgl.FRAGMENT_SHADER);

        webgl.shaderSource(vsshader, vertexstring);
        webgl.shaderSource(fsshader, fragmentstring);

        webgl.compileShader(vsshader);
        webgl.compileShader(fsshader);
        if (!webgl.getShaderParameter(vsshader, webgl.COMPILE_STATUS)) {
            var err = webgl.getShaderInfoLog(vsshader);
            alert(err);
            return;
        }
        if (!webgl.getShaderParameter(fsshader, webgl.COMPILE_STATUS)) {
            var err = webgl.getShaderInfoLog(fsshader);
            alert(err);
            return;
        }
        let program = webgl.createProgram();
        webgl.attachShader(program, vsshader);
        webgl.attachShader(program, fsshader)

        webgl.linkProgram(program);
        webgl.useProgram(program);

        webgl.program = program
    }
    function initBuffer() {
        let arr = [
            0, 0, 0, 1, 0, 0,
            0, 700, 0, 1, 0, 1,
            700, 0, 0, 1, 1, 0,

            700, 700, 0, 1, 1, 0,
        ]

        *let index = [
            0, 1, 2,
            1, 2, 3
        ];**

        let pointPosition = new Float32Array(arr);
        let aPsotion = webgl.getAttribLocation(webgl.program, "a_position");
        let triangleBuffer = webgl.createBuffer();
        webgl.bindBuffer(webgl.ARRAY_BUFFER, triangleBuffer);
        webgl.bufferData(webgl.ARRAY_BUFFER, pointPosition, webgl.STATIC_DRAW);
        webgl.enableVertexAttribArray(aPsotion);
        webgl.vertexAttribPointer(aPsotion, 4, webgl.FLOAT, false, 6 * 4, 0);

        let indexarr = new Uint8Array(index);//  这个地方 Uint16Array啥都不显示不出效果
        let indexBuffer = webgl.createBuffer();
        webgl.bindBuffer(webgl.ELEMENT_ARRAY_BUFFER, indexBuffer);
        webgl.bufferData(webgl.ELEMENT_ARRAY_BUFFER, indexarr, webgl.STATIC_DRAW);

        let uniformProj = webgl.getUniformLocation(webgl.program, "proj");
        webgl.uniformMatrix4fv(uniformProj, false, projMat4);

        attribOutUV = webgl.getAttribLocation(webgl.program, "outUV");
        webgl.enableVertexAttribArray(attribOutUV);
        webgl.vertexAttribPointer(attribOutUV, 2, webgl.FLOAT, false, 6 * 4, 4 * 4);


        uniformTexture = webgl.getUniformLocation(webgl.program, "texture");
        uniformTexture1 = webgl.getUniformLocation(webgl.program, "texture1");

        texture1 = initTexture("fog.png");
        texture0 = initTexture("山水.png");

    }
    function handleLoadedTexture(texture) {


        webgl.bindTexture(webgl.TEXTURE_2D, texture);
        webgl.texImage2D(webgl.TEXTURE_2D, 0, webgl.RGBA, webgl.RGBA, webgl.UNSIGNED_BYTE, texture.image);
        webgl.texParameteri(webgl.TEXTURE_2D, webgl.TEXTURE_MAG_FILTER, webgl.LINEAR);
        webgl.texParameteri(webgl.TEXTURE_2D, webgl.TEXTURE_MIN_FILTER, webgl.LINEAR);
        webgl.texParameteri(webgl.TEXTURE_2D, webgl.TEXTURE_WRAP_S, webgl.REPEAT);
        webgl.texParameteri(webgl.TEXTURE_2D, webgl.TEXTURE_WRAP_T, webgl.REPEAT);

    }
    function initTexture(imageFile, num) {
        let textureHandle = webgl.createTexture();
        textureHandle.image = new Image();
        textureHandle.image.src = imageFile;
        textureHandle.image.onload = function () {
            handleLoadedTexture(textureHandle, num)
        }
        return textureHandle;
    }
    function draw() {
        webgl.clearColor(0.0, 1.0, 0.0, 1.0);
        webgl.clear(webgl.COLOR_BUFFER_BIT | webgl.DEPTH_BUFFER_BIT);
        webgl.enable(webgl.DEPTH_TEST);

        //纹理变动
        uniformAnim = webgl.getUniformLocation(webgl.program, "anim");
        count = count + 0.01;
        webgl.uniform1f(uniformAnim, count);

        webgl.activeTexture(webgl.TEXTURE0);
        webgl.bindTexture(webgl.TEXTURE_2D, texture0);
        webgl.uniform1i(uniformTexture, 0);

        webgl.activeTexture(webgl.TEXTURE1);
        webgl.bindTexture(webgl.TEXTURE_2D, texture1);
        webgl.uniform1i(uniformTexture1, 1);

        **webgl.drawElements(webgl.TRIANGLES, 6, webgl.UNSIGNED_BYTE, 0);**

        // webgl.drawArrays(webgl.TRIANGLES, 0, 6);
    }
    function request(callback) {
        return window.requestAnimationFrame(callback);
    };

</script>

</head>

<body onload="webglStart()">

<canvas id='myCanvas' width="1024" height='768'></canvas>

</body>

查看更多

关注者
0
被浏览
840
Jsonco
Jsonco 图形社区官方人员 2023-04-03
奔驰的蜗牛

你好。一般在webgl遇到纹理花边这种问题,直接考虑两种情况。
情况一:
uv坐标错误:这个不言而喻,说明你uv坐标在映射到顶点的时候匹配的是不对的。我们来具体分析下你的代码

let arr = [
            0, 0, 0, 1,        0, 0,
            0, 700, 0, 1,      0, 1,
            700, 0, 0, 1,      1, 0,

            700, 700, 0, 1,    1, 0,
        ]

通过shader里面输入我们看到a_position输入的是vec4 ,所以定义的bufferdata中前4个值是顶点,同样的道理得到后2个就是uv坐标。我们观察uv明显是有问题的,我们绘制的是一个长方形,我们图片也是一个长方形,很明显最后一行700, 700, 0, 1, 1, 0,是有问题的哈。
情况二:该情况一般在图片处理的时候存在问题,如下面代码

webgl.texParameteri(webgl.TEXTURE_2D, webgl.TEXTURE_MAG_FILTER, webgl.LINEAR);
        webgl.texParameteri(webgl.TEXTURE_2D, webgl.TEXTURE_MIN_FILTER, webgl.LINEAR);
        webgl.texParameteri(webgl.TEXTURE_2D, webgl.TEXTURE_WRAP_S, webgl.REPEAT);
        webgl.texParameteri(webgl.TEXTURE_2D, webgl.TEXTURE_WRAP_T, webgl.REPEAT);

webgl.texParameteri(webgl.TEXTURE_2D, webgl.TEXTURE_WRAP_S, webgl.REPEAT);函数表示纹理映射方式,本质也是对于shader的封装,也是对于uv坐标的改变,封装成webglAPI。关键是第3个参数,REPEAT,现在代表的是如果你的图片默认比你填充的范围小的话,它会重复进行填充。很明显按照正常逻辑你现在如果至少不会是这样“拉丝”,最不行也应该是纹理重复。当然有些情况我们也需要“拉丝”,这时候你需要用到APICLAMP_TO_EDGE,使用该参数会达到你“拉丝”效果,也就是边缘拉伸效果哈。

1 个回答

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友

手机
浏览

扫码手机浏览