如何使用 glreadpixels() 获取 z 深度
how to get z depth using glreadpixels()
谁能告诉我怎么用
GL11.glreadpixels()
在 lwjgl 中获取鼠标投射的光线的 z 深度?
在将其转换为射线之前,我可以获得 x、y 和视图的视图
float x = Mouse.getX();
float y = Mouse.getY();
但我不知道如何使用 glreadpixels
因为当我使用它时它没有任何意义
calculateMousePoint 和 calculate MouseRay 都给出相同的结果
public static float getZDepth(int x, int y)
{
ByteBuffer zdepth = allocBytes(SIZE_FLOAT);
GL11.glReadPixels(x, y, 1, 1, GL11.GL_DEPTH_COMPONENT, GL11.GL_FLOAT, zdepth);
return ( (float) (zdepth.getFloat(0)));
}
private Vector3f calculateMouseRay() {
float mouseX = Mouse.getX();
float mouseY = Mouse.getY();
Vector2f normalizedCoords = getNormalisedDeviceCoordinates(mouseX, mouseY);
Vector4f clipCoords = new Vector4f(normalizedCoords.x, normalizedCoords.y, -1.0f, 1.0f);
Vector4f eyeCoords = toEyeCoords(clipCoords);
Vector3f worldRay = toWorldCoords(eyeCoords);
return worldRay;
}
private Vector3f calculateMousePoint() {
float mouseX = Mouse.getX();
float mouseY = Mouse.getY();
float mouseZ = getZDepth((int)mouseX,(int) mouseY);
Vector2f normalizedCoords = getNormalisedDeviceCoordinates(mouseX, mouseY);
Vector4f clipCoords = new Vector4f(normalizedCoords.x, normalizedCoords.y, mouseZ, 1.0f);
Vector4f eyeCoords = toEyeCoords2(clipCoords);
Vector3f worldRay = toWorldCoords(eyeCoords);
return worldRay;
}
private Vector3f toWorldCoords(Vector4f eyeCoords) {
Matrix4f invertedView = Matrix4f.invert(viewMatrix, null);
Vector4f rayWorld = Matrix4f.transform(invertedView, eyeCoords, null);
Vector3f mouseRay = new Vector3f(rayWorld.x, rayWorld.y, rayWorld.z);
mouseRay.normalise();
return mouseRay;
}
private Vector4f toEyeCoords(Vector4f clipCoords) {
Matrix4f invertedProjection = Matrix4f.invert(projectionMatrix, null);
Vector4f eyeCoords = Matrix4f.transform(invertedProjection, clipCoords, null);
return new Vector4f(eyeCoords.x, eyeCoords.y, -1f, 0f);
}
private Vector4f toEyeCoords2(Vector4f clipCoords) {
Matrix4f invertedProjection = Matrix4f.invert(projectionMatrix, null);
Vector4f eyeCoords = Matrix4f.transform(invertedProjection, clipCoords, null);
return new Vector4f(eyeCoords.x, eyeCoords.y, eyeCoords.z, 0f);
}
private Vector2f getNormalisedDeviceCoordinates(float mouseX, float mouseY) {
float x = (2.0f * mouseX) / Display.getWidth() - 1f;
float y = (2.0f * mouseY) / Display.getHeight() - 1f;
return new Vector2f(x, y);
}
From the documentation、x,y和_width、height代表拍摄的区域。 type是数据的类型,那么data就是结果。
最后,这里最重要的是 format 参数:您可以 select 您想要检索的内容。对你来说,它将是 GL_DEPTH_COMPONENT :
float zmouse;
GL11.glReadnPixels(xmouse, ymouse, 1, 1, GL11.GL_DEPTH_COMPONENT, GL11.GL_FLOAT, zmouse)
你有 Z 深度,现在你必须把它转换成好的 space。实际上,它是夹子 space,我想你会得到相机 space 一个。所以你必须将 "mouse" 点乘以投影和视图矩阵的倒数,比如 realPoint = inverse(projection * view * model) * (xmouse, ymousen, zmouse)
.
最后,realPoint 是 3D 中的点 space。
以您的代码为例,这应该可以完成工作:
public static float getZDepth(int x, int y)
{
ByteBuffer zdepth = allocBytes(SIZE_FLOAT);
GL11.glReadPixels(x, y, 1, 1, GL11.GL_DEPTH_COMPONENT, GL11.GL_FLOAT, zdepth);
return ( (float) (zdepth.getFloat(0)));
}
private Vector3f calculateMousePoint(Vector3f point) {
float x = Mouse.getX();
float y = Mouse.getY();
float z = getZDepth((int)mouseX,(int) mouseY);
return project(new Vector3f(x,y,z), new Vector4f(0,0,Display.getWidth(), Display.getHeight()));
}
private Vector3f calculateFarPoint(Vector3f point) {
float x = Mouse.getX();
float y = Mouse.getY();
return project(new Vector3f(x,y,1.), new Vector4f(0,0,Display.getWidth(), Display.getHeight()));
}
// Code translated from GLM_GTC_matrix_transform
//(https://glm.g-truc.net/0.9.2/api/a00245.html#gac38d611231b15799a0c06c54ff1ede43)
private Vector3f project(Vector3f point, Vector4f viewport)
{
Matrix4f Inverse = Matrix4f.invert(projectionMatrix * viewMatrix)
Vector4f tmp = new Vector4f(point.x, point.y, point.z, 1.f);
tmp.x = (tmp.x - viewport.x) / viewport.z;
tmp.y = (tmp.y - viewport.y) / viewport.w;
tmp = tmp * 2.0 - 1.0;
Vector4f obj = Inverse * tmp;
obj /= obj.w;
return new Vector3f(obj.x, obj.y, obj.z);
}
谁能告诉我怎么用
GL11.glreadpixels()
在 lwjgl 中获取鼠标投射的光线的 z 深度? 在将其转换为射线之前,我可以获得 x、y 和视图的视图
float x = Mouse.getX();
float y = Mouse.getY();
但我不知道如何使用 glreadpixels 因为当我使用它时它没有任何意义 calculateMousePoint 和 calculate MouseRay 都给出相同的结果
public static float getZDepth(int x, int y)
{
ByteBuffer zdepth = allocBytes(SIZE_FLOAT);
GL11.glReadPixels(x, y, 1, 1, GL11.GL_DEPTH_COMPONENT, GL11.GL_FLOAT, zdepth);
return ( (float) (zdepth.getFloat(0)));
}
private Vector3f calculateMouseRay() {
float mouseX = Mouse.getX();
float mouseY = Mouse.getY();
Vector2f normalizedCoords = getNormalisedDeviceCoordinates(mouseX, mouseY);
Vector4f clipCoords = new Vector4f(normalizedCoords.x, normalizedCoords.y, -1.0f, 1.0f);
Vector4f eyeCoords = toEyeCoords(clipCoords);
Vector3f worldRay = toWorldCoords(eyeCoords);
return worldRay;
}
private Vector3f calculateMousePoint() {
float mouseX = Mouse.getX();
float mouseY = Mouse.getY();
float mouseZ = getZDepth((int)mouseX,(int) mouseY);
Vector2f normalizedCoords = getNormalisedDeviceCoordinates(mouseX, mouseY);
Vector4f clipCoords = new Vector4f(normalizedCoords.x, normalizedCoords.y, mouseZ, 1.0f);
Vector4f eyeCoords = toEyeCoords2(clipCoords);
Vector3f worldRay = toWorldCoords(eyeCoords);
return worldRay;
}
private Vector3f toWorldCoords(Vector4f eyeCoords) {
Matrix4f invertedView = Matrix4f.invert(viewMatrix, null);
Vector4f rayWorld = Matrix4f.transform(invertedView, eyeCoords, null);
Vector3f mouseRay = new Vector3f(rayWorld.x, rayWorld.y, rayWorld.z);
mouseRay.normalise();
return mouseRay;
}
private Vector4f toEyeCoords(Vector4f clipCoords) {
Matrix4f invertedProjection = Matrix4f.invert(projectionMatrix, null);
Vector4f eyeCoords = Matrix4f.transform(invertedProjection, clipCoords, null);
return new Vector4f(eyeCoords.x, eyeCoords.y, -1f, 0f);
}
private Vector4f toEyeCoords2(Vector4f clipCoords) {
Matrix4f invertedProjection = Matrix4f.invert(projectionMatrix, null);
Vector4f eyeCoords = Matrix4f.transform(invertedProjection, clipCoords, null);
return new Vector4f(eyeCoords.x, eyeCoords.y, eyeCoords.z, 0f);
}
private Vector2f getNormalisedDeviceCoordinates(float mouseX, float mouseY) {
float x = (2.0f * mouseX) / Display.getWidth() - 1f;
float y = (2.0f * mouseY) / Display.getHeight() - 1f;
return new Vector2f(x, y);
}
From the documentation、x,y和_width、height代表拍摄的区域。 type是数据的类型,那么data就是结果。
最后,这里最重要的是 format 参数:您可以 select 您想要检索的内容。对你来说,它将是 GL_DEPTH_COMPONENT :
float zmouse;
GL11.glReadnPixels(xmouse, ymouse, 1, 1, GL11.GL_DEPTH_COMPONENT, GL11.GL_FLOAT, zmouse)
你有 Z 深度,现在你必须把它转换成好的 space。实际上,它是夹子 space,我想你会得到相机 space 一个。所以你必须将 "mouse" 点乘以投影和视图矩阵的倒数,比如 realPoint = inverse(projection * view * model) * (xmouse, ymousen, zmouse)
.
最后,realPoint 是 3D 中的点 space。
以您的代码为例,这应该可以完成工作:
public static float getZDepth(int x, int y)
{
ByteBuffer zdepth = allocBytes(SIZE_FLOAT);
GL11.glReadPixels(x, y, 1, 1, GL11.GL_DEPTH_COMPONENT, GL11.GL_FLOAT, zdepth);
return ( (float) (zdepth.getFloat(0)));
}
private Vector3f calculateMousePoint(Vector3f point) {
float x = Mouse.getX();
float y = Mouse.getY();
float z = getZDepth((int)mouseX,(int) mouseY);
return project(new Vector3f(x,y,z), new Vector4f(0,0,Display.getWidth(), Display.getHeight()));
}
private Vector3f calculateFarPoint(Vector3f point) {
float x = Mouse.getX();
float y = Mouse.getY();
return project(new Vector3f(x,y,1.), new Vector4f(0,0,Display.getWidth(), Display.getHeight()));
}
// Code translated from GLM_GTC_matrix_transform
//(https://glm.g-truc.net/0.9.2/api/a00245.html#gac38d611231b15799a0c06c54ff1ede43)
private Vector3f project(Vector3f point, Vector4f viewport)
{
Matrix4f Inverse = Matrix4f.invert(projectionMatrix * viewMatrix)
Vector4f tmp = new Vector4f(point.x, point.y, point.z, 1.f);
tmp.x = (tmp.x - viewport.x) / viewport.z;
tmp.y = (tmp.y - viewport.y) / viewport.w;
tmp = tmp * 2.0 - 1.0;
Vector4f obj = Inverse * tmp;
obj /= obj.w;
return new Vector3f(obj.x, obj.y, obj.z);
}