WebGL 2.0 遮挡查询
WebGL 2.0 Occlusion Query
我想使用 WebGL 渲染一个大场景(模拟城市),我认为 遮挡剔除 是优化性能的好方法。
而且我知道 WebGL 2.0 有一个名为 'Query Objects' 的新功能来获取遮挡信息。但是每次我使用gl.getQueryParameter(query, gl.QUERY_RESULT),我得到的结果都是一样的1.
并且我在这里写了一个demo来说明问题:
var query = gl.createQuery();
gl.beginQuery(gl.ANY_SAMPLES_PASSED, query);
gl.drawArrays(gl.TRIANGLES,0,n);
gl.endQuery(gl.ANY_SAMPLES_PASSED);
var tick = function(){
if(!gl.getQueryParameter(query,gl.QUERY_RESULT_AVAILABLE)){
requestAnimationFrame(tick);
return;
}
var result = gl.getQueryParameter(query,gl.QUERY_RESULT);
console.log(Number(result));
gl.deleteQuery(query);
};
tick();
这是我的顶点信息,第二个三角形被第一个三角形遮挡了。
var vertexData = new Float32Array([
0.0,0.5,0.0, //first triangle
-0.5,-0.5,0.0,
0.5,-0.5,0.0,
0.0,0.5,-0.5, //second triangle
-0.5,-0.5,-0.5,
0.5,-0.5,-0.5
]);
结果总是 1。
结果'1'代表什么?
此外,如何使用 WebGL 2.0 进行遮挡剔除?有没有有用的示例?
遮挡查询和遮挡剔除不是一回事。
基本的对象剔除可以(并且应该)完全在 CPU 上完成(例如,对对象边界框、门户可见性、八叉树等的平截头体检查)比在 GPU 上更有效,因为应用程序可以利用图形驱动程序根本不具备的场景级知识。
在 GPU 上,遮挡剔除最容易通过使用从前到后的渲染顺序渲染不透明对象来提供(同样,游戏引擎通常会粗略地对对象批次进行排序),并使用深度测试来剔除模糊的东西。
遮挡查询是一种非常专业的工具,可用于少量视觉效果(例如镜头光晕),但对于单帧内的任何激进剔除来说太难了。
首先,here is a good example如何使用WebGL 2遮挡查询API。
与其他答案相反,完全可以使用遮挡查询来实现遮挡剔除。要注意的是,您将需要稍微复杂的 CPU 辅助数据 structures/algorithms 来帮助您。我在这里不自己解释,而是让你去真正的专家GPU Gems 2 - Chapter 6 Hardware Occlusion Queries Made Useful。如果没有适当的算法,您的遮挡查询本身将比仅渲染对象更昂贵!
gl.ANY_SAMPLES_PASSED 结果为真 (1) 或假 (0)。它不是通过了多少个样本的信息,而是为您提供了任何样本通过的 true (1) 结果,与哪个样本无关。
我想使用 WebGL 渲染一个大场景(模拟城市),我认为 遮挡剔除 是优化性能的好方法。
而且我知道 WebGL 2.0 有一个名为 'Query Objects' 的新功能来获取遮挡信息。但是每次我使用gl.getQueryParameter(query, gl.QUERY_RESULT),我得到的结果都是一样的1.
并且我在这里写了一个demo来说明问题:
var query = gl.createQuery();
gl.beginQuery(gl.ANY_SAMPLES_PASSED, query);
gl.drawArrays(gl.TRIANGLES,0,n);
gl.endQuery(gl.ANY_SAMPLES_PASSED);
var tick = function(){
if(!gl.getQueryParameter(query,gl.QUERY_RESULT_AVAILABLE)){
requestAnimationFrame(tick);
return;
}
var result = gl.getQueryParameter(query,gl.QUERY_RESULT);
console.log(Number(result));
gl.deleteQuery(query);
};
tick();
这是我的顶点信息,第二个三角形被第一个三角形遮挡了。
var vertexData = new Float32Array([
0.0,0.5,0.0, //first triangle
-0.5,-0.5,0.0,
0.5,-0.5,0.0,
0.0,0.5,-0.5, //second triangle
-0.5,-0.5,-0.5,
0.5,-0.5,-0.5
]);
结果总是 1。
结果'1'代表什么?
此外,如何使用 WebGL 2.0 进行遮挡剔除?有没有有用的示例?
遮挡查询和遮挡剔除不是一回事。
基本的对象剔除可以(并且应该)完全在 CPU 上完成(例如,对对象边界框、门户可见性、八叉树等的平截头体检查)比在 GPU 上更有效,因为应用程序可以利用图形驱动程序根本不具备的场景级知识。
在 GPU 上,遮挡剔除最容易通过使用从前到后的渲染顺序渲染不透明对象来提供(同样,游戏引擎通常会粗略地对对象批次进行排序),并使用深度测试来剔除模糊的东西。
遮挡查询是一种非常专业的工具,可用于少量视觉效果(例如镜头光晕),但对于单帧内的任何激进剔除来说太难了。
首先,here is a good example如何使用WebGL 2遮挡查询API。
与其他答案相反,完全可以使用遮挡查询来实现遮挡剔除。要注意的是,您将需要稍微复杂的 CPU 辅助数据 structures/algorithms 来帮助您。我在这里不自己解释,而是让你去真正的专家GPU Gems 2 - Chapter 6 Hardware Occlusion Queries Made Useful。如果没有适当的算法,您的遮挡查询本身将比仅渲染对象更昂贵!
gl.ANY_SAMPLES_PASSED 结果为真 (1) 或假 (0)。它不是通过了多少个样本的信息,而是为您提供了任何样本通过的 true (1) 结果,与哪个样本无关。