- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在进行视锥体剔除的方式上遇到了一些问题。当前的方法确实解决了剔除问题,但效果确实很奇怪。当我离我的主要父对象太近时,我正在使用场景图来渲染所有内容,对象开始非常快速地闪烁。当我离开时,它就消失了。我尝试了很多东西,但再也没有想法了。你们有什么想法吗?非常感谢任何帮助。
我首先在我的模型周围创建一个由八个点组成的边界框。据我所知,经过大量测试,这些都是正确的。
这是我计算截锥平面点的方法。相机位置是世界空间中的位置,方向是它正在看的方向。此外,每次旋转相机时都会计算 cameraUp 和 cameraRight。
Vector3 pos = Camera.staticPosition;
Vector3 view = Camera.staticOrientation;
Vector3 upVector3 = Camera.cameraUp;
Vector3 rightVector3 = Camera.cameraRight;
float toRadians = (float)Math.PI / 180.0f;
float nearDis = .1f;
float farDistance = 1000f;
float fov = Game.FOV;
float aspectRatio = 1.3f;
//Get with and height of near and far plane
float tanDiv = 2 * (float) Math.Tan(fov*toRadians / 2);
float heightNear = tanDiv * nearDis;
float widthNear = heightNear * aspectRatio;
float heightFar = tanDiv * farDistance;
float widthFar = heightFar * aspectRatio;
// get the centre points of the planes so they can be used to calculate the edge points
Vector3 centreNear = pos + view * nearDis;
Vector3 centreFar = pos + view * farDistance;
// get the halfht values of the width and hegiht to make sure you can get the points
float hNearHalf = heightNear / 2;
float wNearHalf = widthNear / 2;
float hFarHalf = heightFar / 2;
float wFarHalf = widthFar / 2;
Vector3 nearTopLeft = centreNear + (upVector3 * hNearHalf) - (rightVector3 * wNearHalf);
Vector3 nearTopRight = centreNear + (upVector3 * hNearHalf) + (rightVector3 * wNearHalf);
Vector3 nearBottomLeft = centreNear - (upVector3 * hNearHalf) - (rightVector3 * wNearHalf);
Vector3 nearBottomRight = centreNear - (upVector3 * hNearHalf) + (rightVector3 * wNearHalf);
Vector3 farTopLeft = centreFar + (upVector3 * hFarHalf) - (rightVector3 * wFarHalf);
Vector3 farTopRight = centreFar + (upVector3 * hFarHalf) + (rightVector3 * wFarHalf);
Vector3 farBotomLeft = centreFar - (upVector3 * hFarHalf) - (rightVector3 * wFarHalf);
Vector3 farBottomRight = centreFar - (upVector3 * hFarHalf) + (rightVector3 * wFarHalf);
我将平截头体点存储在一个数组中。首先是近平面点,然后是远平面、顶平面、底平面、左平面,最后是右平面。然后我遍历所有六个平面和 boundinbox 的 8 个点,如果该点位于平面的右侧,则增加字典中该键的值。
Vector3[] frustumPoints = new Vector3[18]
{
nearTopLeft, nearTopRight, nearBottomLeft, farTopLeft, farTopRight, farBotomLeft, nearTopLeft, farTopLeft,
nearTopRight, nearBottomLeft, farBotomLeft, nearBottomRight, nearTopLeft, nearBottomLeft, farTopLeft,
nearTopRight, nearBottomRight, farTopRight
};
Dictionary<Vector3, int> count = new Dictionary<Vector3, int>(8);
for (int value = 0; value < 8; value++)
{
count.Add(cubePositions[value], 0);
}
for (int x = 0; x < 18; x += 3)
{
Vector3 normal = NormalPlane(frustumPoints[x], frustumPoints[x + 1], frustumPoints[x + 2]);
for (int y = 0; y < 8; y++)
{
Vector3 pointPlane = frustumPoints[x] - cubePositions[y];
float dot = Vector3.Dot(pointPlane, normal);
if (dot <= 0 && x % 6 == 0)
{
count[cubePositions[y]]++;
}
else if (dot >= 0 && x % 3 == 0)
{
count[cubePositions[y]]++;
}
}
}
这是我获取平面法线的方法
Vector3 NormalPlane(Vector3 pointOne, Vector3 pointTwo, Vector3 pointThree)
{
Vector3 normal;
Vector3 edgeOne = pointTwo - pointOne; // calculate vector from point one to point two
Vector3 edgeTwo = pointThree - pointOne; // calculate vector from point one to point three
normal = Vector3.Normalize(Vector3.Cross(edgeOne, edgeTwo)); // calculate the cross product of the two given vectors. Then normalize it so you have normal of plane
return normal; // return the normal
}
如果对于立方体上的这些点之一,计数为 6,则这些点位于所有平面内,因此平截头体和我绘制对象。如果所有点都不等于 6,则不会绘制对象。
问题是我不知道我在哪里犯了错误所以你们有什么想法吗?
提前致谢
杰罗默
最佳答案
If for one of these points on the cube the count is six, the points is within all planes and thus the frustum and I draw the object. If none of the points is equal to 6 the objects don't get drawn.
你这里的逻辑好像是
但是。这是错误的。即使立方体的所有 8 个顶点都位于平截头体之外,立方体仍然可以与平截头体相交,如这个 2D 草图所示:
*----------*
| |
+-----------------+--+ |
\ | / |
\ |/ |
\ / |
\ /| |
\ / *----------*
\ /
\ /
+----+
因此,您剔除了可能可见的内容。
截头体剔除的通常逻辑是只有当所有顶点都被同一平面拒绝时才剔除该框。 (这会导致一些奇怪的情况,即盒子完全在外面并且没有被剔除,但这些情况不太可能发生,通常也没什么大不了的。)
关于c# - 当前的截锥体剔除效果导致 openTk 中的对象闪烁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44735084/
我有一个充满体素的世界,假设我的世界是 320*320*96 体素。我的想法是将整个世界加载到我的视频卡的内存中,这样在将新的“ block ”传输到 GPU 时就不会损失性能。为显示体素世界而生成的
我不知道如何告诉 libgdx 在透明贴花后面绘制绿色球体。 这是我的问题的示例图片: 贴花创建:前两个参数是宽度和高度,最后一个标志是透明与否。 Decal.newDecal(count * (GU
我有 vector ,我想检索一个包含所有条目的 vector ,这些条目在所有输入 vector 中的任何地方都不重复。 #include int main() { std::vector a
我正在尝试为网站设置代码块的样式。容器 div 设置为垂直和水平溢出。问题是当它水平溢出时,斑马条纹背景颜色被剔除。我也尝试过使用背景图片,但它也剔除了它。为什么会这样?我该如何解决? 谢谢。 图片:
我应该在调用 Canvas 绘制方法之前剔除元素还是让 Canvas 处理剔除。我是否应该实现如下逻辑: if(circle.x+circle.radius>=0 || circle.x-circle
我刚刚发现 Azure Blob 存储上有 100 GB 的日志文件/失败请求日志,这些日志文件多年来一直在累积。是否有管理它们的工具或技术 - 目录结构很复杂,因此它不像按日期排序那么简单(我使用
我是一名优秀的程序员,十分优秀!