2016-10-07 11 views
0

Ich benutze ein interaktives browserbasiertes WebGL Volume Rendering. Mit der Maus wenn ich die Interaktion mache, wird die Funktion drawVolume() aufgerufen. Um die Renderzeit zu messen, nehme ich den Zeitstempel um Start und Ende. Die Differenz gibt mir Renderzeit. Derzeit ich es auf zwei Maschinen leite: Client und ServerWie berechne ich die Renderzeit in WebGL? Sieht so aus, als würde ich es falsch berechnen

Im Folgenden sind die Beobachtungen:

Server-Maschine: [NVIDIA GeForce GTX970]Render_time ist etwa weniger als 2ms. Interaktion ist schneller.

-Client-Maschine: [NVIDIA Quadro K600]Render_time ist etwa 10-11ms. Interaktive Anzeige ist langsamer, Bilder werden langsam aktualisiert. Und manchmal hören die Bildschirmtreiber auf zu arbeiten und die Anzeige erlischt. Ich muss das System neu starten.

Ich weiß nicht, ob diese Methode für die Berechnung der Renderzeit richtig ist. Irgendwie habe ich das Gefühl, obwohl der Code bereits voll ist, auf Hardware-Ebene wird das gerenderte Bild noch nicht im Browserfenster angezeigt. Wie lernt man den jeweils aktuellen Rahmen für die jeweilige Interaktion kennen? Wenn ich diesen Status bekomme, kann ich vielleicht die Renderzeit richtig berechnen.

drawVolume = function() 
{ 
    start3 = new Date().getTime(); 

    gl.clearColor(0.0, 0.0, 0.0, 0.0); 
    gl.enable(gl.DEPTH_TEST); 
    gl.bindFramebuffer(gl.FRAMEBUFFER, gl.fboBackCoord); 
    gl.shaderProgram = gl.shaderProgram_BackCoord; 
    gl.useProgram(gl.shaderProgram); 
    gl.clearDepth(-50.0); 
    gl.depthFunc(gl.GEQUAL); 
    drawCube(gl,cube); 
    gl.bindFramebuffer(gl.FRAMEBUFFER, null); 
    gl.shaderProgram = gl.shaderProgram_RayCast; 
    gl.useProgram(gl.shaderProgram); 
    gl.clearDepth(50.0); 
    gl.depthFunc(gl.LEQUAL); 
    gl.activeTexture(gl.TEXTURE0); 
    gl.bindTexture(gl.TEXTURE_2D, gl.fboBackCoord.tex); 
    gl.activeTexture(gl.TEXTURE1); 
    gl.bindTexture(gl.TEXTURE_2D, gl.vol_tex); 
    gl.activeTexture(gl.TEXTURE2); 
    gl.bindTexture(gl.TEXTURE_2D, gl.tf_tex); 
    gl.uniform1i(gl.getUniformLocation(gl.shaderProgram, "uBackCoord"), 0); 
    gl.uniform1i(gl.getUniformLocation(gl.shaderProgram, "uVolData"), 1); 
    gl.uniform1i(gl.getUniformLocation(gl.shaderProgram, "uTransferFunction"), 2); 
    //Set Texture 
    drawCube(gl,cube); 

    end3 = new Date().getTime(); 
    render_time=end3-start3; 
    console.log(render_time); 
} 

Antwort

2

CPU/GPU-Interaktion ist asynchron, das implementiert wird unter Verwendung des Treibers internen Befehlspuffer in dem alle ausgegebenen Befehle gepuffert werden, so gibt es keine Garantie, dass Ihre Befehle, die von der Zeit ausgeführt werden, rufen Sie new Date().getTime() (mit Date.now() und Caching der einheitlichen Standorte wäre besser btw.). In den meisten Szenarien ist es nicht wünschenswert, die Ausführung bestimmter Befehle zu erzwingen/abzuwarten. Es ist jedoch möglich, finish (man page) zu verwenden, das einen Synchronisationspunkt einführt und die CPU-seitige Ausführung blockiert, bis alle Befehle ausgeführt wurden. Wie in gmans answer here gezeigt, ist dies jedoch nicht nur die Messung der Ausführungszeit von zuvor ausgegebenen Befehlen, sondern auch die Zeit, die benötigt wird, um die Pipeline zu blockieren.

Idealerweise würde man die EXT_disjoint_timer_query Erweiterung verwenden, die es erlaubt, die Ausführungszeit von gegebenen Befehlen zu messen, ohne die Pipeline zu blockieren, leider ist diese Erweiterung ab sofort (Oktober 2016) nicht in fast jedem Browser verfügbar.

+1

[Wie an anderer Stelle erklärt] (http://StackOverflow.com/a/24191845/128511) "Finish" gibt Ihnen kein genaues Timing. Dies gilt doppelt für gekachelte Architekturen. – gman

+0

Danke, dass du das unterstrichen hast! –

+0

So funktioniert die Option "glfinish" nicht in WebGL und EXT_disjoint_timer_query ist noch nicht im Browser verfügbar. Gibt es also keine andere Methode zur Berechnung der _approximate Rendering Time_? –

Verwandte Themen