我在如何计算三维空间中视锥体的边界点的图表之后绘制了图表.首先,我有两组数据,每组包含三个值:摄像机的xyz坐标和围绕x,y和z轴的旋转.给定一定的视距,应该可以计算出6个平面中每个平面的边界点.我一直用这些方程来计算远平面的宽度和高度:
hfar = 2 * tan(45/2) * view_distance
wfar = hfar * ratio
Run Code Online (Sandbox Code Playgroud)
hfar是远平面的高度,wfar是宽度,比率是视口宽度除以高度的比率.我一直在使用下图来试图找出它:

我需要找到由(?,?,?)注释的点.我一直试图计算这些值几天,但无济于事.任何帮助,将不胜感激.
此外,可以在此处和此处找到一些提供有关该主题的信息的好消息来源.
编辑:我掀起的另一个图像显示通过y轴的单个切片向下看x轴.它显示的信息与上图相同,但它也显示了我的问题:我无法计算远平面的每个边界点的正确z轴值.
请记住,可以通过x轴进行相同的切割以显示相同的过程但是具有玩家向上或向下看的角度.
我有一个截锥体(截断的金字塔),我需要为这个截锥体计算一个尽可能小的边界球.我可以选择中心位于平截头体的中心,半径是距离"远"角之一的距离,但通常会在平截头体的窄端留下相当多的松弛
这看起来像简单的几何,但我似乎无法弄明白.有任何想法吗?
我一直在努力解决Hartmann/Gribbs提取Frustum飞机一段时间的方法,但收效甚微.我想构建一个摄像机视图 - 视锥体来剔除我的场景.
我正在使用右手坐标系中的柱主矩阵.(OpenGL风格 - 我使用的是C#和Playstation Mobile,但数学应该是相同的)
我想让我的飞机进入World-Space,所以我从View-Projection Matrix(即projectionMatrix*viewMatrix)构建我的平截头体.视图矩阵与相机的世界变换相反.
问题是; 不管我调整什么,我似乎无法得到正确的截头.我想我可能会遗漏一些明显的东西.
如果我在俯视z轴时向左或向右"扫视"我的相机,我的平面的法线会发生变化,以至于它们总是指向场景的原点 - 这让我觉得它们不在世界空间中...
我对OpenGL的模型视图转换感到困惑.我理解所有的转换过程,但是当谈到投影矩阵时,我迷失了:(
如果我有一个点P(x,y,z),我该如何检查这个点是否会在由平行剪裁体积或透视剪裁体积定义的剪裁体积上绘制?这个过程背后的数学背景是什么?
我正在构建一个应用程序,其中我呈现一些纹理的平面.但是,我想根据平截头体宽度和摄像机位置动态计算螺旋的半径(我在计算中用来创建螺旋).
螺旋位于屏幕的中心x = 0,y = 0,z = 0.
我想要考虑屏幕方向(横向/纵向).到目前为止这是我的代码,但似乎我错过了一些东西,因为左边和右边的平面不在视口内.
App.prototype.calculateHelixRadius = function(){
// plane width = height = 512;
var friend = this.getFriend();
var vFOV = friend.camera.fov * Math.PI / 180;
var dist = utils.getAbsPointsDistance3D(friend.camera.position, friend.scene.position);
var aspect = friend.settings.container.clientWidth / friend.settings.container.clientHeight;
var frustumHeight = 2.0 * dist * Math.tan(0.5 * vFOV);
var frustumWidth = frustumHeight * aspect;
return utils.isLandscape() ? frustumHeight / 2 : frustumWidth / 2 ;
};
Run Code Online (Sandbox Code Playgroud)
我做错了什么,为什么屏幕边缘的飞机不在里面?
这里还有代码供参考 getAbsPointsDistance3D
var utils = {
// other helpers... …Run Code Online (Sandbox Code Playgroud) GLM提供了一种声明投影矩阵的方法:
projectionMatrix = glm :: perspective(45.0f,4.0f/3.0f,0.1f,1000.f);
由此,我希望能够检查边界框是否在我的视锥体中.我如何从投影矩阵中获得平截头体平面或者我需要计算的平面?这甚至是正确的方法吗?
试图至少使用Lighthouse3D Radar Frustum Culling教程的非常简单的 第1部分来工作......我绝对感到困惑,我甚至无法在我的渲染器中使用该部分.
所以第一步是:你测试一个点是在近平面前面还是在远平面后面,如果是这样的话就进行早期剔除.(如果没有,那么你会进行进一步的测试,但我只是坚持第一部分.)
我使用2x2立方体的世界空间中心(x1y2z3),并有一个可以自由移动和旋转的相机.所有我的矢量和矩阵的东西必须相当坚固,因为渲染器否则工作得很好.所以这是我对第一部分的看法(在Go中),简单的"Z vs near-or-far"测试:
func (cam *Camera) frustumHasPoint(point *Vec3) bool {
var pc Vec3
v := point.Sub(&cam.Controller.Pos) // point minus camPos
ref := cam.Controller.dir // take a copy of camDir
ref.Z = -ref.Z
ref.Normalize() // camDir was already normalized but anyway...
pc.Z = v.Dot(&ref)
if pc.Z > cam.Perspective.ZFar || pc.Z < cam.Perspective.ZNear {
return false
}
return true
}
Run Code Online (Sandbox Code Playgroud)
现在我为什么要反转ref的Z?因为在教程中他们写道:"请注意,图中的参考不是右手系统(如在OpenGL中),因为Z的方向已被颠倒以使教程更直观" - 好吧,在GL教程中当然这有相反的效果......
好吧,如果如上所述反转Z,它会剔除超过50%的时间; 如果我不这样做,那么大约98%的时间它会"过度剔除".
我错过了什么?
我是OpenGL的新手.我和JOGL一起使用它.
我正在读关于截头剔除:
http://www.lighthouse3d.com/opengl/viewfrustum/
http://www.crownandcutlass.com/features/technicaldetails/frustum.html
我不确定它应该做什么.OpenGL不会自动剔除屏幕外对象吗?(这种剔除速度明显慢于不首先发送对象吗?)
从我正在阅读的内容来看,它看起来并不像是避免绘制被遮挡在另一个之后但在视锥体内的对象.这是否意味着唯一的好处是避免将屏幕外对象发送到OpenGL?
视锥体计算的各种示例是使用glGetFloatv()来获取当前投影和模型视图矩阵(GL_PROJECTION_MATRIX,GL_MODELVIEW_MATRIX),并且基于此做一些视锥体剔除.
我已经读过glGet*是你在主渲染循环中不想要的东西;
"使用"Get"或"Is"函数会降低渲染性能.这些命令会强制图形系统执行所有排队的OpenGL调用,然后才能回答"Get"或"Is"查询."
所以我的问题是.如何在我的代码中创建一个坚实的Frustum剔除算法,我在哪里放置它以确保永远不会发生这种停顿?
我正在尝试在背景图像(正投影)上渲染一些带有Frustum投影的网格.无论我做什么,背景图像都会保持在场景之上(隐藏网格物体).
我尝试过一点测试 - 当我用相同的投影矩阵渲染它们时,它们的顺序是正确的 - 背景图像在网格后面.
这些是投影矩阵和Depth-Buffer init:
glEnable(GL_DEPTH_TEST);
glClearDepthf( 1.0f );
glDepthFunc( GL_LEQUAL );
glDepthMask (GL_TRUE);
EGLConfig eglconfig;
EGLint const attrib_list[] = {
EGL_DEPTH_SIZE, 16,
EGL_NONE
};
EGLint numreturned;
CHECK(eglChooseConfig(esContext.eglDisplay, attrib_list, &eglconfig, 1, &numreturned) != EGL_FALSE);
float fieldOfView = 60.0;
float znear = 0.1f;
float zfar = 100000;
float size = (float)(znear * tanf((fieldOfView * M_PI /180.0f) / 2.0f));
m_orthoProjMatrix.loadOrtho(0,
screenWidth,
0,
screenHeight,
znear,
zfar);
m_frustProjMatrix.loadFrustum(-size,
size,
-size / (screenWidth / screenHeight),
size / (screenWidth / screenHeight),
znear,
zfar); …Run Code Online (Sandbox Code Playgroud) opengl-es frustum orthographic projection-matrix opengl-es-2.0