Javascript WebGL-添加标签并拾取对象
我尝试使用颜色索引技术进行拾取,但我想使用光线投射技术进行拾取,并在拾取的3d点上添加3d标签 我是webgl新手,我想要一个关于如何使用光线投射在webgl中拾取对象的示例代码 如何在webgl中执行项目和取消项目Javascript WebGL-添加标签并拾取对象,javascript,opengl-es,html5-canvas,webgl,webgl-earth,Javascript,Opengl Es,Html5 Canvas,Webgl,Webgl Earth,我尝试使用颜色索引技术进行拾取,但我想使用光线投射技术进行拾取,并在拾取的3d点上添加3d标签 我是webgl新手,我想要一个关于如何使用光线投射在webgl中拾取对象的示例代码 如何在webgl中执行项目和取消项目 我正在使用纯WebGl来实现这一点(没有three.js或其他框架),因此请帮助我了解WebGl代码示例。如果您对基于CPU的解决方案感兴趣,下面介绍如何: 首先,要将世界空间转换为屏幕空间坐标,只需通过视图投影矩阵变换世界位置。然后你需要用x,y,z除以w来做透视图除法。就这样。
我正在使用纯WebGl来实现这一点(没有three.js或其他框架),因此请帮助我了解WebGl代码示例。如果您对基于CPU的解决方案感兴趣,下面介绍如何: 首先,要将世界空间转换为屏幕空间坐标,只需通过视图投影矩阵变换世界位置。然后你需要用x,y,z除以w来做透视图除法。就这样。这种形式对我来说最有意义:(假设你有适当的矩阵函数): 将屏幕空间转换为世界空间基本上是使用反向视图投影矩阵的反向操作:
vec3.toWorldSpace = function(out, v3, viewProjectionMatrix, width, height){
// expects v3[2] (z value) to be -1 if want position at zNear and +1 at zFar
var invViewProj = mat4.inverse(vec3.SHARED_MAT4, viewProjectionMatrix);
var x = 2*v3[0]/width - 1.0;
var y = 1.0 - (2*v3[1]/height); // note: Y axis oriented top -> down in screen space
var z = v3[2];
out[0] = x;
out[1] = y;
out[2] = z;
var m = invViewProj;
vec3.transformByMat(out, out, m);
var w = m[3] * x + m[7] * y + m[11] * z + m[15]; // required for perspective divide
if (w !== 0){
var invW = 1.0/w;
out[0] *= invW;
out[1] *= invW;
out[2] *= invW;
}
return out;
};
然后,当您在屏幕上选择x,y坐标时,您可以在世界空间中计算光线,如下所示:
function screenPickTest(x, y){
var pos = SHARED_V;
var posFar = SHARED_V2;
pos[0] = x;
pos[1] = y;
pos[2] = -1;
posFar[0] = x;
posFar[1] = y;
posFar[2] = +1;
pos = vec3.toWorldSpace(pos, pos, viewProjection, canvas.width, canvas.height);
posFar = vec3.toWorldSpace(posFar, posFar, viewProjection, canvas.width, canvas.height);
var dir = vec3.minus(SHARED_V2, posFar, pos);
return raySweepTestAgainst____(pos, dir, COLLISION_GEOMETRYS);
}
您必须实现碰撞检测功能,该功能检测光线击中的第一个对象并返回碰撞点(以及其他数据,如果需要)
这样,您就可以在碰撞点等处创建一个标签。感谢您的帮助。
function screenPickTest(x, y){
var pos = SHARED_V;
var posFar = SHARED_V2;
pos[0] = x;
pos[1] = y;
pos[2] = -1;
posFar[0] = x;
posFar[1] = y;
posFar[2] = +1;
pos = vec3.toWorldSpace(pos, pos, viewProjection, canvas.width, canvas.height);
posFar = vec3.toWorldSpace(posFar, posFar, viewProjection, canvas.width, canvas.height);
var dir = vec3.minus(SHARED_V2, posFar, pos);
return raySweepTestAgainst____(pos, dir, COLLISION_GEOMETRYS);
}