如何在OpenGL中对半透明三角形进行排序?

我正在使用OpenGL编写3D游戏。渲染半透明三角形时出现排序问题。我知道需要对它们进行排序,但是如何?我不想使用BSP树(如果要更改对象的位置,则需要重建树。)和OIT算法(性能昂贵)。我想按“覆盖率”对它们进行排序。

我有两个半透明的三角形,并且使用透视相机将它们投影到屏幕上。

视口:0、0、1280、720

例如

[正确排序]黑色三角形覆盖绿色三角形。

http://img.mukewang.com/60ae0fb000013b5111940541.jpg

[错误排序]绿色三角形覆盖黑色三角形。


http://img.mukewang.com/60ae0fbc0001230711570557.jpg

图像中的三角形是不透明的,以便清楚地看到分类伪像。


我对这个问题的解决方案


将这些三角形的顶点转换为屏幕空间坐标,并通过对z坐标进行插值进行比较,但在我的图像上,您可以看到黑色三角形的一个坐标在视口之外,因此该坐标很奇怪(类似于:-2896; 1423 ; 1.169),并且无法在黑色三角形上插值z坐标。


我如何转换为屏幕空间坐标


通过MVP矩阵变换三角形顶点

执行透视划分

转换为屏幕空间

通过MVP矩阵进行转换


public Vector4f transform(Vector4f vector) {

    float x = m00 * vector.x + m10 * vector.y + m20 * vector.z + m30 * vector.w;

    float y = m01 * vector.x + m11 * vector.y + m21 * vector.z + m31 * vector.w;

    float z = m02 * vector.x + m12 * vector.y + m22 * vector.z + m32 * vector.w;

    float w = m03 * vector.x + m13 * vector.y + m23 * vector.z + m33 * vector.w;


    return new Vector4f(x, y, z, w);

}

透视鸿沟


public Vector3f perspectiveDivide() {

    float wInverse = 1.0f / w;

    return new Vector3f(x * wInverse, y * wInverse, z * wInverse);

}

转换为屏幕空间


public void toScreenCoords(int width, int height) {

    x = (x * 0.5f + 0.5f) * width;

    y = (y * 0.5f + 0.5f) * height;

    z = (z + 1.0f) * 0.5f;

}

我如何执行


Vector4f clipspace = mvp.transform(triangle_vertex);

Vector3f ndc = clipspace.perspectiveDivide();

Vector3f screenspace = ndc.toScreenCoords(1280, 720);

我做错了什么?为什么在视口外协调该操作很奇怪?如何获得视口外的正确坐标?


- - 编辑 - -


我发现,如果三角形在视口外的坐标为一个,则该三角形必须分为两个。


但是如何使用裁剪空间坐标和裁剪平面将三角形分成两个部分呢?


Qyouu
浏览 194回答 1
1回答

翻过高山走不出你

快速简便地正确排序(半透明)三角形的解决方案我称之为“假投影排序”。如果可以假设三角形不相交,则只需检查三角形(黑色或绿色)是否与四面体相交即可(绿色三角形的黑色坐标与相机位置的坐标)。一个例子第一个三角形坐标:0.0, 0.0, 5.00.0, 5.0, 5.05.0, 5.0, 5.0第二个三角形坐标:0.0, 0.0, 5.05.0, 0.0, 5.05.0, 0.0, 5.0相机位置1.15, 5.8, 5.5然后,四面体坐标将是来自三角形(例如,第一个)和相机位置的坐标。0.0,  0.0, 5.0  // First coordinate from the first triangle0.0,  5.0, 5.0  // Second coordinate from the first triangle5.0,  5.0, 5.0  // Third coordinate from the first triangle1.15, 5.8, 5.5  // Camera position您需要做的最后一件事是检查第二个三角形是否与四面体相交。如果第二个三角形相交,则它覆盖第一个三角形。如果使用第二个三角形的坐标来创建四面体,则需要检查第一个三角形的交点,而不是第二个。笔记不要使用Java的TreeSet或TreeMap使用“假投影排序”来比较三角形,否则会产生不正确的排序。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java