You need to enable JavaScript to run this app. WebGL无报错无法渲染图片,TypeScript开发2D游戏纹理显示失败
优惠活动
大模型
产品
解决方案
定价
更多

WebGL无报错无法渲染图片,TypeScript开发2D游戏纹理显示失败

存在的问题及修复方案

1. 顶点属性名不匹配

你顶点着色器中定义的输入属性名为a_position,但初始化时获取属性位置的代码传入的是a_pos,二者名称不一致导致WebGL无法读取顶点数据,无法绘制图形。
修复:修改属性获取代码的入参即可

this.a_posLoc = this.gl.getAttribLocation(this.program,"a_position");

2. 缺少纹理相关配置

你没有显式给片元着色器的纹理采样器u_image绑定纹理单元,绘制前也没有重新绑定要使用的纹理对象,导致着色器无法读取纹理数据。

3. 未确认图片加载状态

如果调用绘制时图片还没有加载完成,此时img元素的宽高为0,上传的纹理内容为空,也会导致绘制结果为空。

4. 顶点属性配置可能被覆盖

如果项目中还有其他绘制逻辑修改了ARRAY_BUFFER绑定或顶点属性指针配置,仅在构造函数中配置一次顶点属性会导致后续绘制时数据读取错误。


修正后的drawImage代码

public drawImage(tex: HTMLImageElement, x: number, y: number): void{
    // 先校验图片加载状态
    if (!tex.complete || tex.naturalWidth === 0) {
        return
    }
    const width = tex.width;
    const height = tex.height;

    this.glUtil.resizeCanvasToDisplaySize(this.gl);
    this.gl.useProgram(this.program);

    // 重新绑定顶点缓冲区,配置顶点属性
    this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.positionBuffer);
    this.gl.enableVertexAttribArray(this.a_posLoc);
    this.gl.vertexAttribPointer(this.a_posLoc, 2, this.gl.FLOAT, false, 0, 0);

    // 绑定纹理、上传纹理数据
    this.gl.bindTexture(this.gl.TEXTURE_2D, this.plainTex);
    this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.gl.RGBA, this.gl.UNSIGNED_BYTE, tex);

    // 给纹理采样器绑定0号纹理单元(WebGL默认激活的就是0号单元)
    this.gl.uniform1i(this.u_imageLoc, 0);

    const clipX = x / this.gl.canvas.width  *  2 - 1;
    const clipY = y / this.gl.canvas.height * -2 + 1;
    const clipWidth = width  / this.gl.canvas.width  *  2;
    const clipHeight = height / this.gl.canvas.height * -2;

    this.gl.uniformMatrix3fv(this.u_matrixLoc, false, [
        clipWidth, 0, 0,
        0, clipHeight, 0,
        clipX, clipY, 1,
    ]);

    this.gl.drawArrays(this.gl.TRIANGLES, 0, 6);
}

图片加载逻辑优化

确保图片加载完成后再调用绘制:

this.temptex = document.getElementById('imagee') as HTMLImageElement;
const draw = () => this.imageRender.drawImage(this.temptex,0,0);
this.temptex.complete ? draw() : this.temptex.onload = draw;

排查技巧

如果修改后还是没有内容,可以先把片元着色器的输出改成固定颜色验证顶点逻辑是否正常:

void main() {
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}

如果能看到红色矩形,说明顶点部分逻辑正常,问题出在纹理相关配置;如果看不到,再回头检查顶点属性、矩阵计算等逻辑。

内容的提问来源于stack exchange,提问作者Akshay_VK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.11 21:27:00