Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Chrome和Windows的非最佳WebGL性能_Javascript_Performance_Google Chrome_Webgl - Fatal编程技术网

Javascript Chrome和Windows的非最佳WebGL性能

Javascript Chrome和Windows的非最佳WebGL性能,javascript,performance,google-chrome,webgl,Javascript,Performance,Google Chrome,Webgl,作为对自己的一个挑战,我正在用javascript重新制作一个基本的minecraft,并使用标记支持的WebGL库。我在youtube上有一个演示视频。为了使世界易于编辑,我将世界几何体分割为块(16^3)区域,这意味着我需要对每个渲染块进行绘制调用。这就是问题所在。这不是图形卡的性能问题我的Nvidia GeForce 980甚至没有打开风扇,GPU报告的利用率仅为最大时钟速度的一半,因此更准确的数字是利用率为12.5%。问题出在CPU上 google chrome任务管理器中的GPU进程

作为对自己的一个挑战,我正在用javascript重新制作一个基本的minecraft,并使用
标记支持的WebGL库。我在youtube上有一个演示视频。为了使世界易于编辑,我将世界几何体分割为块(16^3)区域,这意味着我需要对每个渲染块进行绘制调用。这就是问题所在。这不是图形卡的性能问题我的Nvidia GeForce 980甚至没有打开风扇,GPU报告的利用率仅为最大时钟速度的一半,因此更准确的数字是利用率为12.5%。问题出在CPU上


google chrome任务管理器中的
GPU进程
比我CPU中的一个内核饱和多15%。这是GL的呼叫记录器所说的:

GL drawElements: [4, 7680, 5123, 0]
GL drawElements: [4, 6144, 5123, 0]
GL drawElements: [4, 7866, 5123, 0]
GL drawElements: [4, 6618, 5123, 0]
GL drawElements: [4, 6144, 5123, 0]
GL drawElements: [4, 4608, 5123, 0]
GL uniformMatrix4fv: [[object WebGLUniformLocation], false, mat4(0.9999874830245972, -0.000033332948078168556, 0.004999868106096983, 0, 0, 0.9999777674674988, 0.006666617467999458, 0, -0.0049999793991446495, -0.00666653411462903, 0.999965250492096, 0, -127.43840026855469, -129.25619506835938, -113.50281524658203, 1)]
GL uniform2fv: [[object WebGLUniformLocation], vec2(-8, -7)]
GL drawElements: [4, 7680, 5123, 0]
GL drawElements: [4, 6144, 5123, 0]
GL drawElements: [4, 6210, 5123, 0]
GL drawElements: [4, 8148, 5123, 0]
GL drawElements: [4, 6144, 5123, 0]
GL drawElements: [4, 4608, 5123, 0]
GL uniformMatrix4fv: [[object WebGLUniformLocation], false, mat4(0.9999874830245972, -0.000033332948078168556, 0.004999868106096983, 0, 0, 0.9999777674674988, 0.006666617467999458, 0, -0.0049999793991446495, -0.00666653411462903, 0.999965250492096, 0, -127.51840209960938, -129.36285400390625, -97.50337219238281, 1)]
GL uniform2fv: [[object WebGLUniformLocation], vec2(-8, -6)]
GL drawElements: [4, 7680, 5123, 0]
GL drawElements: [4, 6144, 5123, 0]
GL drawElements: [4, 7842, 5123, 0]
GL drawElements: [4, 6144, 5123, 0]
GL drawElements: [4, 4608, 5123, 0]
我之所以能够进行背对背的抽屉元素调用,是因为我使用的是WebGL扩展名
OES\u vertex\u array\u object
,因此记录器不会记录这些调用,因此您不会看到它们

Iv'e从众报道状态变化非常昂贵,但既然我连续调用了很多
drawerelements
这不应该是个问题吗?此外,我还发现,使用我的硬件类型的人可以通过考虑这些状态变化轻松地进行4096次draw调用。也许这是因为webgl本身在Google Chrome使用的从gl到direct3D调用的角度上没有得到优化

还有一个注意事项:如果我将几何体的构造大小从16^3调整为16x16x128,将抽签次数减少8次,那么如果没有创建世界几何体,我就可以以稳定的60 fps速度运行游戏。如果有,游戏是不可玩的

编辑:更多的测试。。。所以我决定制作一个最小的webgl程序,它是一个非常酷的屏幕保护程序。这是:

<html>
<body style="margin:0px">
    <canvas id="gl" style="width:100%;height:100%;">

    </canvas>
</body>

<script type="vertex" id="vertex">
    attribute vec2 pos;

    uniform mat4 matrix;

    uniform float time;
    uniform vec2 translate;

    varying vec3 color;

    void main (){
        gl_Position = matrix * vec4(pos + translate, (sin(time) + 1.5) * -10.0, 1.0);

        color = vec3((sin(time) + 1.0) / 2.0);
    }
</script>

<script type="frag", id="frag">
    precision mediump float;

    varying vec3 color;

    void main (){
        gl_FragColor = vec4(color, 1.0);
    }
</script>

<script>
    var canvas = document.getElementById("gl");
    var gl = canvas.getContext("webgl");

    canvas.width = canvas.clientWidth;
    canvas.height = canvas.clientHeight;

    gl.viewport(0, 0, canvas.width, canvas.height);

    var vertShader = gl.createShader(gl.VERTEX_SHADER);
    var fragShader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(vertShader, "attribute vec2 pos;uniform mat4 matrix;uniform float time;uniform vec2 translate;varying vec3 color;void main(){gl_Position=matrix*vec4(pos+translate,(sin(time)+1.5)*-10.0,1.0);color=vec3((sin(time)+1.0)/2.0);}");
    gl.shaderSource(fragShader, "precision mediump float;varying vec3 color;void main(){gl_FragColor=vec4(color, 1.0);}");
    gl.compileShader(vertShader);
    gl.compileShader(fragShader);

    var shader = gl.createProgram();
    gl.attachShader(shader, vertShader);
    gl.attachShader(shader, fragShader);
    gl.linkProgram(shader);
    gl.useProgram(shader);

    gl.enableVertexAttribArray(0);

    var u_time = gl.getUniformLocation(shader, "time");
    var u_matrix = gl.getUniformLocation(shader, "matrix");
    var u_translate = gl.getUniformLocation(shader, "translate");

    (function (){
        var nearView = 0.1;
        var farView = 100;
        var f = 1 / Math.tan(60 / 180 * Math.PI / 2);
        var nf = nearView - farView;
        var aspectRatio = canvas.width / canvas.height;

        gl.uniformMatrix4fv(u_matrix, false, [
            f / aspectRatio, 0, 0, 0,
            0, f, 0, 0,
            0, 0, (farView + nearView) / nf, -1,
            0, 0, (2 * farView * nearView) / nf, 0
        ]);
    })();

    var buf = gl.createBuffer();
    gl.bindBuffer (gl.ARRAY_BUFFER, buf);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
        -1, -1,
         1,  1,
        -1,  1,
        -1, -1,
         1,  1,
         1, -1,
    ]), gl.STATIC_DRAW);

    gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);

    var time = 0;

    var translations = [];

    for (var i = 0; i < 4096; i++){
        translations.push(Math.random() * 10 - 5, Math.random() * 10 - 5);
    }

    var renderLoop = function (){
        gl.clear(gl.CLEAR_COLOR_BIT | gl.CLEAR_DEPTH_BIT);

        for (var i = 0; i < 4096; i++){

            gl.uniform1f(u_time, time + i / 100);
            gl.uniform2f(u_translate, translations[i * 2], translations[i * 2 + 1])

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

        window.requestAnimationFrame(renderLoop);
    }

    window.setInterval(function (){
        time += 0.01;
    }, 10);

    window.requestAnimationFrame(renderLoop);
</script>

属性向量2位;
一致mat4矩阵;
均匀浮动时间;
统一的vec2翻译;
可变的vec3颜色;
空干管(){
gl_位置=矩阵*vec4(位置+平移,(sin(时间)+1.5)*-10.0,1.0);
颜色=vec3((sin(time)+1.0)/2.0);
}
精密中泵浮子;
可变的vec3颜色;
空干管(){
gl_FragColor=vec4(颜色,1.0);
}
var canvas=document.getElementById(“gl”);
var gl=canvas.getContext(“webgl”);
canvas.width=canvas.clientWidth;
canvas.height=canvas.clientHeight;
总图视口(0,0,canvas.width,canvas.height);
var vertShader=gl.createShader(gl.VERTEX\u着色器);
var fragShader=gl.createShader(gl.FRAGMENT\u着色器);
gl.shaderSource(vertShader,“属性vec2 pos;统一mat4矩阵;统一浮点时间;统一vec2 translate;变化vec3颜色;void main(){gl_Position=matrix*vec4(pos+translate,(sin(time)+1.5)*-10.0,1.0);color=vec3((sin(time)+1.0)/2.0););
gl.shaderSource(fragShader,“precision mediump float;可变vec3颜色;void main(){gl_FragColor=vec4(颜色,1.0);}”);
总帐编译头(vertShader);
总帐编译主管(fragShader);
var shader=gl.createProgram();
gl.attachShader(着色器、顶点着色器);
gl.attachShader(着色器,fragShader);
gl.linkProgram(着色器);
gl.useProgram(着色器);
gl.EnableVertexAttributeArray(0);
var u_time=gl.getUniformLocation(着色器,“时间”);
var u_matrix=gl.getUniformLocation(着色器,“矩阵”);
var u_translate=gl.getUniformLocation(着色器,“translate”);
(功能(){
var nearView=0.1;
var farView=100;
var f=1/Math.tan(60/180*Math.PI/2);
var nf=近视图-远视图;
var aspectRatio=canvas.width/canvas.height;
gl.uniformMatrix4fv(u_矩阵,假[
f/aspectRatio,0,0,0,
0,f,0,0,
0,0,(远视图+近视图)/nf,-1,
0,0,(2*远视图*近视图)/nf,0
]);
})();
var buf=gl.createBuffer();
gl.bindBuffer(gl.ARRAY\u BUFFER,buf);
gl.bufferData(gl.ARRAY\u BUFFER,新Float32Array([
-1, -1,
1,  1,
-1,  1,
-1, -1,
1,  1,
1, -1,
])、总图、静态图);
gl.VertexAttribute指针(0,2,gl.FLOAT,false,0,0);
var时间=0;
var转换=[];
对于(变量i=0;i<4096;i++){
push(Math.random()*10-5,Math.random()*10-5);
}
var renderLoop=函数(){
gl.clear(gl.clear_颜色_位| gl.clear_深度_位);
对于(变量i=0;i<4096;i++){
总分类单位m1f(单位时间,时间+i/100);
gl.uniform2f(u_翻译,翻译[i*2],翻译[i*2+1])
gl.绘图阵列(gl.三角形,0,6);
}
requestAnimationFrame(renderLoop);
}
window.setInterval(函数(){
时间+=0.01;
}, 10);
requestAnimationFrame(renderLoop);


该程序绘制了一组正方形。在这种情况下,4096进行了那么多抽签调用。性能比我的主项目更好,但仍然不是最佳的。gpu进程使用约13%的CPU,我不知何故保持了60 FPS的销售速度。当然,我在这方面做的最多的就是打几个统一的电话。我的真实项目使用5个着色器程序,显然可以处理更多的信息。我将试着用我用来渲染主游戏的api来写这篇文章。也许还有改进的余地。

你有多少块?你说每个区块是16^3。这就是4096个立方体或最多49152个三角形(如果通过某种魔法,你可以显示每个立方体的每个面,我想你不能)

我真的不知道如何回答你的问题。我想首先要测试的是一个空程序能运行多少CPU

function render(){
请求动画帧(渲染);
}

请求动画帧(渲染)问题是否可能在requestAnimationFrame中?我记得有一个非空的requestAnimationFrame/setTimeout回调,只有ctx.clearRect()以60 fps的速度调用,将使用大约15-20%的CP