我正在使用THREE.JS和GLSL处理一些屏幕空间着色器。我想同时渲染一个"漫反射"每个对象材料/纹理的缓冲区并渲染一个" ID"缓冲区,其中每个对象具有用于对象边缘检测的唯一颜色。这对于对象选择也非常有用,正如一些THREE.JS示例所示。
我已经在使用Scene.overrideMaterial来渲染普通缓冲区(以及其他一些很酷的东西),但还没有找到一种方法来为ID缓冲区做类似的事情。有这样的东西存在吗?看起来很有用,很可能。有其他人为这个问题开发了解决方案吗?也许通过将对象UUID映射到颜色值?
- - - - >编辑 以下是我使用此示例的尝试: https://threejs.org/examples/webgl_interactive_instances_gpu.html
我不关心此时的选择,不管这不起作用。我想我可能会错误地设置onBeforeRender()。对此有何帮助?
谢谢!
initPieces = function(geometry){
...
//set id Color to unique color
//for picking will use setHex(i) method
m.userData.idColor = material.color;
...
m.onBeforeRender = function (){
if(Viewer._scene.overrideMaterial){
if(Viewer._scene.overrideMaterial._name == "id"){
var updateList = [];
var u = scene.overrideMaterial.uniforms;
//picking color in user data
var d = this.userData;
//Is this just equivalent to checking whether this is the picking material?
if(u.idColor){
u.idColor.value = (d.idColor);
// u.needsUpdate = true;
updateList.push("idColor");
}
//Don't understand what this is doing
//Throws "WebGL INVALID_OPERATION: uniformMatrix4fv: location is not from current program"
if (updateList.length){
var materialProperties = renderer.properties.get(material);
if( materialProperties.program){
var gl = renderer.getContext();
var p = materialProperties.program;
gl.useProgram( p.program );
var pu = p.getUniforms();
updateList.forEach(function(name){
pu.setValue( gl, name, u[name].value);
});
}
}
}
}
}
// Doesn't show onBeforeRender set as I expected?
console.log(m);
...
}
...
}
...
function render(scene, camera){
...
scene.overrideMaterial = getMaterial("id");
renderer.render(scene, camera, getTarget("id"));
scene.overrideMaterial = null;
...
}