【问题标题】:How to clip only intersection (not union) of clipping planes?如何仅剪切剪切平面的交集(而不是联合)?
【发布时间】:2013-05-29 21:42:16
【问题描述】:

在 OpenGL/JOGL 中,当使用多个剪裁平面时,似乎会应用所有剪裁平面的联合。我想要的是要应用的所有剪切平面的 intersection。这可能吗?请参阅下面的简化二维示例。

编辑:顶点着色器裁剪的示例(参见下面的 cmets)。

【问题讨论】:

  • 难道你不能只使用片段着色器来计算像素是否在你要渲染的区域,如果不是,就调用discard;
  • @fintalia 是的!这正是我在您刚刚回答的question 中的“测试”。

标签: opengl 3d jogl


【解决方案1】:

使用glClipPlane,没有。如果顶点在至少一个平面的正半空间之外,则顶点将被剪裁。一旦发生这种情况,任何其他飞机可能是什么都无关紧要。

但是,您可以通过在顶点着色器中将适当的值写入gl_ClipDistance 来获得此效果(或几乎任何其他效果)。

您写出的插值小于 0.0(“负半空间”)的任何部分都将被剪裁,您可以写入任何您喜欢的值,例如到一个点的平方距离,或者到两个平面的距离之和,或者你计算的任何其他值。

【讨论】:

  • 是否可以将gl_ClipVertex 用于相同目的? gl_ClipDistance 在我的 OpenGL 2.1 项目中不可用。
  • 是的,但是正如您链接到的问题中所解释的那样,它会稍微复杂一些。您需要在同一坐标系中为剪辑平面提供 4 个分量点,而不仅仅是一个不需要在任何特定坐标系中的“距离值”,因为它只是一个告诉 OpenGL“距离多近”的值" 你认为这一点被剪掉了。
  • 我在概念上遇到了从gl_ClipDistancegl_ClipVertex 的飞跃的问题。我能找到的gl_ClipVertex 的每个例子都只是gl_ModelViewMatrix*gl_Vertex。查看使用gl_ClipVertex 修改剪切平面的示例将非常有帮助,就像您描述如何使用gl_ClipDistance 一样。我尝试将gl_ClipVertex 设置为我的顶点着色器中的各种修改顶点,但从未看到任何相对于剪裁内容的变化。如果您能够发布一个示例,那将非常有帮助。
  • gl_ClipVertex 是用词不当,因为(虽然它看起来像一个顶点,有 4 个分量)它实际上是一个平面方程,而不是一个顶点。即normal plus a distance from the origingl_ClipDistance 是平面和顶点的点积,或者是“顶点距离被剪裁多远”的概念,这在概念上要容易得多。将gl_ClipVertex 设置为实际顶点可能不会给出很多合理的输出,因为通常 w = 1.0 - 所以除非顶点非常接近原点,否则您将一直剪切所有内容。
  • 使用这种方法,我剪裁的是顶点,而不是三角形图元。所以我不应该期待干净的线条,对吗?我是否正确假设我需要自己处理重新计算分割三角形(可能在几何着色器中)?还是我在这里错过了一个简单的解决方案? (顺便说一句,我上面遇到的问题与我的片段着色器以某种方式隐藏了gl_ClipVertex 的效果有关——显然我还有一些 GLSL 学习要做。)
【解决方案2】:

多遍:

#include <GL/glut.h>

void scene()
{
    glColor3ub( 255, 0, 0 );
    glBegin( GL_QUADS );
    glVertex2i( -1, -1 );
    glVertex2i(  1, -1 );
    glVertex2i(  1,  1 );
    glVertex2i( -1,  1 );
    glEnd();
}

void display()
{
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    double w = glutGet( GLUT_WINDOW_WIDTH );
    double h = glutGet( GLUT_WINDOW_HEIGHT );
    double ar = w / h;
    glOrtho( -2 * ar, 2 * ar, -2, 2, -1, 1);

    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();

    glEnable( GL_CLIP_PLANE0 );

    // -y plane
    GLdouble plane0[] = { -1, 0, 0, 0 };
    glClipPlane( GL_CLIP_PLANE0, plane0 );

    scene();

    // -x plane
    GLdouble plane1[] = { 0, -1, 0, 0 };
    glClipPlane( GL_CLIP_PLANE0, plane1 );

    scene();

    glutSwapBuffers();
}

int main( int argc, char **argv )
{
    glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
    glutInitWindowSize( 640, 480 );
    glutCreateWindow( "Clipping" );
    glutDisplayFunc( display );
    glutMainLoop();
    return 0;
}

【讨论】:

    猜你喜欢
    • 2021-10-25
    • 2023-04-11
    • 2021-04-07
    • 1970-01-01
    • 2019-02-12
    • 1970-01-01
    • 2023-03-04
    • 1970-01-01
    • 2017-10-11
    相关资源
    最近更新 更多