You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WebGL偶发仅渲染纯色不显示quad问题排查求助

WebGL偶发黑屏问题修复方案

核心问题排查

以下是导致你在webview中偶发黑屏、Chrome安卓端正常的根本原因:

  • 冗余uniform变量触发严格模式错误
    你的片元着色器中没有定义frame变量,调用gl.getUniformLocation(program, "frame")会返回null,后续渲染循环中反复调用gl.uniform1i(frameUniform, timeStamp)给空位置赋值,嵌入式webview的WebGL实现对这类错误处理更严格,会直接中断渲染流程,而Chrome浏览器对这类非致命错误做了兼容忽略,因此仅在webview中出现异常。
  • 画布尺寸初始化时机不可靠
    页面onload触发时部分webview还未完成布局计算,window.innerWidth/innerHeight可能返回0值,此时画布和视口尺寸为0,自然无法渲染出画面,就会出现偶发黑屏。
  • 冗余深度测试配置(非强制,建议优化)
    你的场景仅渲染一个全屏四边形,完全不需要深度测试,反复开启深度测试、清空深度缓冲属于冗余操作,可能触发部分老旧驱动的兼容问题。

修复代码

<html>
    <head>
        <title>WebGL</title>
        <style>
            body { margin: 0; }
            #glCanvas {
                position: absolute;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
            }
        </style>
    </head>
    <body onload="main();">
        <canvas id="glCanvas"></canvas>
        <script type="text/javascript">
            function main() {
                var canvas = document.querySelector("#glCanvas");
                var gl = canvas.getContext("webgl");
            
                if(gl == null) {
                    alert("Unable to initialize WebGL. Your browser or machine may not support it.");
                    return;
                }
                let resolutionUniform;
                // 统一处理画布尺寸更新
                function updateCanvasSize() {
                    canvas.width = window.innerWidth;
                    canvas.height = window.innerHeight;
                    gl.viewport(0, 0, window.innerWidth, window.innerHeight);
                    gl.uniform2fv(resolutionUniform, new Float32Array([canvas.width, canvas.height]));
                }
                
                var vertexShaderSc = `
                    precision highp float;
                    precision highp int;
                    
                    attribute vec2 position;
                    
                    void main(void) {
                        gl_Position = vec4(position, 0.0, 1.0);
                    }
                `;
                
                var fragmentShaderSc = `
                    precision highp float;
                    precision highp int;
                    uniform vec2 resolution;
                    uniform float time;
                    
                    void main(void) {
                        vec2 uv = gl_FragCoord.xy/resolution.xy;
                        gl_FragColor = vec4(uv+time, 0.0, 1.0);
                    }
                `;
                
                var vertexShader = gl.createShader(gl.VERTEX_SHADER);
                var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
                gl.shaderSource(vertexShader, vertexShaderSc);
                gl.shaderSource(fragmentShader, fragmentShaderSc);
                
                gl.compileShader(vertexShader);
                if(!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
                    console.error("Error compiling vertex shader", gl.getShaderInfoLog(vertexShader));
                    return;
                }
                gl.compileShader(fragmentShader);
                if(!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
                    console.error("Error compiling fragment shader", gl.getShaderInfoLog(fragmentShader));
                    return;
                }
                
                var program = gl.createProgram();
                gl.attachShader(program, vertexShader);
                gl.attachShader(program, fragmentShader);
                gl.linkProgram(program);
                if(!gl.getProgramParameter(program, gl.LINK_STATUS)) {
                    console.error('ERROR linking program!', gl.getProgramInfoLog(program));
                    return;
                }
                gl.validateProgram(program);
                if(!gl.getProgramParameter(program, gl.VALIDATE_STATUS)) {
                    console.error('ERROR validating program!', gl.getProgramInfoLog(program));
                    return;
                }
                
                var vertex_data = [ 
                    // First triangle:
                     1.0,  1.0,
                    -1.0,  1.0,
                    -1.0, -1.0,
                    // Second triangle:
                    -1.0, -1.0,
                     1.0, -1.0,
                     1.0,  1.0];
                var buffer0 = gl.createBuffer();
                gl.bindBuffer(gl.ARRAY_BUFFER, buffer0);
                gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertex_data), gl.STATIC_DRAW);
                
                var positionAttrib = gl.getAttribLocation(program, "position");
                gl.vertexAttribPointer(positionAttrib, 2, gl.FLOAT, gl.FALSE, 2 * Float32Array.BYTES_PER_ELEMENT, 0);
                gl.enableVertexAttribArray(positionAttrib);
                
                gl.useProgram(program);
                resolutionUniform = gl.getUniformLocation(program, "resolution");
                var timeUniform = gl.getUniformLocation(program, "time");
                // 初始化尺寸&监听窗口变化
                updateCanvasSize();
                window.addEventListener('resize', updateCanvasSize);

                // 初始化配置只执行一次
                gl.clearColor(0.0, 0.0, 0.0, 1.0);
                
                function render(timeStamp) {
                    gl.uniform1f(timeUniform, timeStamp*0.001);
                    gl.clear(gl.COLOR_BUFFER_BIT);
                    gl.drawArrays(gl.TRIANGLES, 0, 6);
                    requestAnimationFrame(render);
                }
                requestAnimationFrame(render);
            }
        </script>
    </body>
</html>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 23:42:02