如何使用Three.js renderer.info对象调试WebGL错误?

时间:2015-05-08 19:08:39

标签: javascript three.js webgl

我创建了一个带有新功能的玩具程序,我现在正在将其集成到我正在研究的更大程序中。目前,在它们的调试形式中,两个程序都显示PointClouds使用ShaderMaterialBufferGeometry呈现的纹理。现在我正在尝试调试现在在大程序中的WebGL错误,但不是在玩具中:

GL ERROR :GL_INVALID_OPERATION : glDrawElements: Source and destination textures of the draw are the same.

我注意到尽管在两个程序中运行相同的可视化,但它们给出的renderer.info对象存在差异。

没有错误的玩具程序控制台显示:

render: Object
    calls: 1
    faces: 2
    points: 0
    vertices: 6

程序的控制台显示错误:

render: Object
    calls: 2
    faces: 2
    points: 20
    vertices: 6

这两个程序表面上应该做同样的事情。这个额外的电话和额外的积分可以与问题相关吗?我查看了Three.js WebGLRenderer.js脚本,并相信这些值是在处理PointClouds几何的区域中设置的。

在没有错误的玩具程序中(顶部列表),无论我添加到云中的纹理图像点数是多少,points对象的renderer.info值都保持为零,可视化渲染正确,而且没有错误。但是,在带有错误的其他程序(第二个列表)中,points值跟踪我添加到云中的点数,可视化呈现正确,但我收到错误消息。在这两种情况下,我都没有弄清楚如何影响calls的数量。

有人可以帮助我更好地理解这些内容,以及它们与此错误消息的关系吗?谢谢!

更新

我已经了解到如果我从程序中的场景中删除PointCloud并出现错误,则错误消失,renderer.info对象看起来就像玩具程序中的对象,但是当然玩具仍然显示PointCloud并且没有错误。我使用新的几何和材质替换了多维数据集而不是PointCloud并返回了错误消息,因此错误似乎并不特定于PointCloud。也许构造EffectComposer有问题:

var container, renderer;
var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight;
var lightComposer, lightCamera, lightLight, lightScene, lightCloud;

function init() {

    renderer = new THREE.WebGLRenderer( {
        antialias : false,
        alpha : true
    } );
    var ctx = renderer.getContext();
    ctx.disable( ctx.DEPTH_TEST );
    renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
    renderer.setClearColor( 0x000000, 0 );
    renderer.autoClear = false;

    container = document.getElementById( 'ThreeJS' );
    container.appendChild( renderer.domElement );

    lightScene = new THREE.Scene();

    lightCamera = new THREE.OrthographicCamera( SCREEN_WIDTH / - 2, SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, SCREEN_HEIGHT / - 2, 1, 1000 );
    lightCamera.position.set( 0,0,1000 );
    lightCamera.lookAt( lightScene.position );

    lightLight = new THREE.PointLight( 0xffffff );
    lightLight.position.set( 100,250,0 );
    lightScene.add( lightLight );

    var shaderCopy = THREE.CopyShader;
    var effectCopy = new THREE.ShaderPass( shaderCopy );
    effectCopy.renderToScreen = true;

    // COMPOSER
    var rtParameters = {
        minFilter : THREE.LinearFilter,
        magFilter : THREE.LinearFilter,
        format: THREE.RGBFormat,
        stencilBuffer: false
    };

    var rtWidth  = SCREEN_WIDTH;
    var rtHeight = SCREEN_HEIGHT;

    lightComposer = new THREE.EffectComposer( renderer, new THREE.WebGLRenderTarget( rtWidth, rtHeight, rtParameters ) );
    lightCloud = LightCloudMaker.getCloud( SCREEN_WIDTH, SCREEN_HEIGHT );
    lightScene.add( lightCloud );//***If I remove this the error goes away, if I add a plain cube in its place the error returns. Both the PointCloud and Cube are displayed when the error occurs
    var renderLight = new THREE.RenderPass( lightScene, lightCamera );
    lightComposer.addPass( renderLight );
    lightComposer.addPass( effectCopy );

    animate();   
}

function animate() {

     requestAnimationFrame( animate );
     render();
}

function render() {
    renderer.clear(); 
    lightComposer.render();
}

更新2:

当场景中有任何可见对象时,我会看到大程序中的错误 - PointCloudCube,甚至是AxisHelpers。我删除这些可见对象的那一刻,错误消失了。将这些中的任何一个放入玩具程序中都没有问题 - 没有错误。在大型和玩具程序中,对象显示得很好;区别在于错误消息的存在与否。

更新3:

我发现如果我在两个程序(lightComposer.addPass( effectCopy );)中注释掉复制着色器传递,则图像不再渲染(因为复制传递是渲染到屏幕的传递),但我仍然可以读取两个程序中渲染过程的render.info值。结果提供了丰富的信息。如果没有复制传递,两个渲染过程都会为调用,面,点和顶点生成相同的值。例如,这里是一个简单多维数据集的值(在两个程序中都是相同的):

render: Object
    calls: 1
    faces: 12
    points: 0
    vertices: 36

现在,当我将复制传递添加回两个程序时,结果会有所不同:

玩具程序,无误地执行:

render: Object
    calls: 1
    faces: 2
    points: 0
    vertices: 6

错误的大程序:

render: Object
    calls: 2
    faces: 14
    points: 0
    vertices: 42

在出现Web GL错误的大程序中,您可以看到renderer.info对象显示缓冲区现在包含渲染过程的结果(多维数据集值) plus 复制传递的结果(网格)。无错误执行的玩具程序仅显示复制传递(网格)的值。为什么在大型程序中将值加在一起?就像错误所说的那样,读写缓冲区是相同的,这就是这些值所反映的。这里发生了什么?感谢任何正确方向的捅。

新信息:我在使用控制台时也发现错误直到第二次通过渲染功能才会显示。也许这是提供信息的,或者是否通常会延迟从GPU接收错误?

0 个答案:

没有答案