我创建了一个带有新功能的玩具程序,我现在正在将其集成到我正在研究的更大程序中。目前,在它们的调试形式中,两个程序都显示PointClouds
使用ShaderMaterial
和BufferGeometry
呈现的纹理。现在我正在尝试调试现在在大程序中的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:
当场景中有任何可见对象时,我会看到大程序中的错误 - PointCloud
,Cube
,甚至是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接收错误?